1 | # ---------------------------------------------------------------------- |
---|
2 | # RAPPTURE OBJECT: number |
---|
3 | # |
---|
4 | # A number is a real value with units of measure. It is usually |
---|
5 | # used as an input, but it can also be an output from a simulation. |
---|
6 | # |
---|
7 | # ====================================================================== |
---|
8 | # AUTHOR: Michael McLennan, Purdue University |
---|
9 | # Copyright (c) 2004-2011 Purdue Research Foundation |
---|
10 | # |
---|
11 | # See the file "license.terms" for information on usage and |
---|
12 | # redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
13 | # ====================================================================== |
---|
14 | |
---|
15 | object number -extends base { |
---|
16 | palettes "Inputs" "Outputs" |
---|
17 | |
---|
18 | help http://rappture.org/wiki/rp_xml_ele_number |
---|
19 | |
---|
20 | attr default -title "Default Value" -type string:validate=number -path default |
---|
21 | attr units -title "Units of Measurement" -type units -path units |
---|
22 | attr min -title "Minimum Value" -type string:validate=number -path min |
---|
23 | attr max -title "Maximum Value" -type string:validate=number -path max |
---|
24 | attr color -title "Color" -type color -path color |
---|
25 | |
---|
26 | check default { |
---|
27 | if {[string length [string trim $attr(default)]] == 0} { |
---|
28 | return [list error "Must have a default value for this number."] |
---|
29 | } |
---|
30 | if {"" != $attr(units)} { |
---|
31 | set base [Rappture::Units::System::for $attr(units)] |
---|
32 | if {[validate_number_parse $attr(default) num units] |
---|
33 | && "" != $units |
---|
34 | && ![string equal [Rappture::Units::System::for $units] $base]} { |
---|
35 | return [list error "Units for default value don't match the expected units for this value"] |
---|
36 | } |
---|
37 | |
---|
38 | set dval [Rappture::Units::convert $attr(default) -context $attr(units) -to $attr(units) -units off] |
---|
39 | |
---|
40 | if {[validate_number_parse $attr(min) num units] |
---|
41 | && [catch {Rappture::Units::convert $attr(min) -context $attr(units) -to $attr(units) -units off} min] == 0 |
---|
42 | && $dval < $min} { |
---|
43 | return [list error "Default value is less than the minimum that you've specified for this value."] |
---|
44 | } |
---|
45 | |
---|
46 | if {[validate_number_parse $attr(max) num units] |
---|
47 | && [catch {Rappture::Units::convert $attr(max) -context $attr(units) -to $attr(units) -units off} max] == 0 |
---|
48 | && $dval > $max} { |
---|
49 | return [list error "Default value is greater than the maximum that you've specified for this value."] |
---|
50 | } |
---|
51 | } |
---|
52 | } |
---|
53 | |
---|
54 | check min { |
---|
55 | if {"" != $attr(units)} { |
---|
56 | set base [Rappture::Units::System::for $attr(units)] |
---|
57 | if {[validate_number_parse $attr(min) num units] |
---|
58 | && "" != $units |
---|
59 | && ![string equal [Rappture::Units::System::for $units] $base]} { |
---|
60 | return [list error "Units for minimum value don't match the expected units for this value"] |
---|
61 | } |
---|
62 | } |
---|
63 | if {[catch {Rappture::Units::convert $attr(min) -context $attr(units) -to $attr(units) -units off} min] == 0 |
---|
64 | && [catch {Rappture::Units::convert $attr(max) -context $attr(units) -to $attr(units) -units off} max] == 0 |
---|
65 | && $min >= $max} { |
---|
66 | return [list error "Minimum value should be less than the maximum. If you don't want to see a min/max range, you can clear out either or both values."] |
---|
67 | } |
---|
68 | } |
---|
69 | |
---|
70 | check max { |
---|
71 | if {"" != $attr(units)} { |
---|
72 | set base [Rappture::Units::System::for $attr(units)] |
---|
73 | if {[validate_number_parse $attr(max) num units] |
---|
74 | && "" != $units |
---|
75 | && ![string equal [Rappture::Units::System::for $units] $base]} { |
---|
76 | return [list error "Units for maximum value don't match the expected units for this value"] |
---|
77 | } |
---|
78 | } |
---|
79 | } |
---|
80 | |
---|
81 | storage { |
---|
82 | private variable _num 0.0 ;# real number value |
---|
83 | private variable _units "" ;# physical units |
---|
84 | } |
---|
85 | |
---|
86 | import xml {xmlobj path} { |
---|
87 | attr import $xmlobj $path |
---|
88 | import_string [$xmlobj get $path.current] [attr get units] |
---|
89 | } |
---|
90 | |
---|
91 | export xml {xmlobj path} { |
---|
92 | $xmlobj put $path "${_num}${_units}" |
---|
93 | } |
---|
94 | |
---|
95 | import string {val {defunits ""}} { |
---|
96 | puts "IMPORTING: $val (number with units $defunits)" |
---|
97 | if {[regexp {^([-+]?(?:[0-9]+\.|\.)?[0-9]+(?:[eE][-+]?[0-9]+)?)( *(?:[a-zA-Z]+[0-9]*)+(?:\/(?:[a-zA-Z]+[0-9]*)+)*)*$} $val match num units]} { |
---|
98 | set sys [Rappture::Units::System::for $units] |
---|
99 | set base [Rappture::Units::System::for $defunits] |
---|
100 | if {$sys eq "" && $base ne ""} { |
---|
101 | error "don't recognize value" |
---|
102 | } |
---|
103 | if {$sys ne $base} { |
---|
104 | error "bad units \"$sys\": should be $base" |
---|
105 | } |
---|
106 | set _num $num |
---|
107 | set _units $units |
---|
108 | } elseif {[string is double -strict $val]} { |
---|
109 | set _num $val |
---|
110 | set _units $defunits |
---|
111 | } else { |
---|
112 | error "don't recognize value" |
---|
113 | } |
---|
114 | } |
---|
115 | |
---|
116 | export string {var} { |
---|
117 | upvar $var val |
---|
118 | set val "${_num}${_units}" |
---|
119 | } |
---|
120 | |
---|
121 | compare { |
---|
122 | set sys1 [Rappture::Units::System::for $_units] |
---|
123 | set sys2 [Rappture::Units::System::for $_units2] |
---|
124 | if {$sys1 ne $sys2} { |
---|
125 | # different units systems -- order by physical quantities |
---|
126 | return [string compare $sys1 $sys2] |
---|
127 | } |
---|
128 | |
---|
129 | # normalize the value of num1 |
---|
130 | if {$_units ne ""} { |
---|
131 | set num1 [Rappture::Units::convert $_num \ |
---|
132 | -context $_units -to $_units -units off] |
---|
133 | } else { |
---|
134 | set num1 $_num |
---|
135 | } |
---|
136 | |
---|
137 | # normalize the value of num2 |
---|
138 | if {$_units2 ne ""} { |
---|
139 | set num2 [Rappture::Units::convert $_num2 \ |
---|
140 | -context $_units2 -to $_units -units off] |
---|
141 | } else { |
---|
142 | set num2 $_num2 |
---|
143 | } |
---|
144 | |
---|
145 | return [cmpdbl $num1 $num2] |
---|
146 | } |
---|
147 | } |
---|