David Megginson wrote:
Julian Foad writes:OK. I think the best thing to do would be:
> I don't like to add more configuration and code, I like to pare things > down to the simplest correct implementation. But I think this "snap to > valid value" behaviour will be necessary.
> > I might have a go at an implementation. How do you feel about > specifying "max" using the "min <= x < max" rule in all cases?
That may work -- please let me know what you come up with.
Firstly, change back to wrapping modulo the interval, with "min <= x < max" semantics. I believe the previous implementation did that. The inline function that Norman mentioned also does that.
Secondly, make it snap to the nearest value (min + N*resolution) when a "resolution" tag is present, taking special care of floating-point precision. Or perhaps specify "number of divisions in the interval" as an integer, instead of "resolution" by which I meant a floating-point "size of a division".
I attach a patch which does these, and an update to navcom-radio.xml which specifies "resolution" appropriately and sets "max" to 118 or 136 instead of 117.95 or 135.975. Other files will need to be updated similarly; how is this for a start? It seems to work without skipping values.
While working on this file I noticed some potentially serious warnings:
fg_commands.cxx: In function `bool do_property_adjust(const SGPropertyNode*)':
fg_commands.cxx:435: warning: control reaches end of non-void function
fg_commands.cxx: In function `bool do_property_multiply(const SGPropertyNode*)':
fg_commands.cxx:465: warning: control reaches end of non-void function
/usr/local/include/simgear/misc/props.hxx: At top level:
fg_commands.cxx:600: warning: `bool do_presets_commit(const SGPropertyNode*)' defined but not used
And also the functions do_view_next and do_view_prev should probably be "static".
- Julian
Index: fg_commands.cxx =================================================================== RCS file: /var/cvs/FlightGear-0.9/FlightGear/src/Main/fg_commands.cxx,v retrieving revision 1.13 diff -u -3 -p -d -r1.13 fg_commands.cxx --- fg_commands.cxx 31 Dec 2002 18:26:06 -0000 1.13 +++ fg_commands.cxx 3 Jan 2003 23:13:07 -0000 @@ -11,6 +11,7 @@ #include <simgear/debug/logstream.hxx> #include <simgear/misc/commands.hxx> #include <simgear/misc/props.hxx> +#include <simgear/sg_inlines.h> #include <Cockpit/panel.hxx> #include <Cockpit/panel_io.hxx> @@ -39,22 +40,6 @@ SG_USING_STD(ofstream); //////////////////////////////////////////////////////////////////////// -/** - * Template function to wrap a value. - */ -template <class T> -static inline void -do_wrap (T * value, T min, T max) -{ - if (min >= max) { // basic sanity check - *value = min; - } else if (*value > max) { - *value = min; - } else if (*value < min) { - *value = max; - } -} - static inline SGPropertyNode * get_prop (const SGPropertyNode * arg) { @@ -105,12 +90,21 @@ limit_value (double * value, const SGPro if (min_node == 0 || max_node == 0) wrap = false; - if (wrap) { // wrap - if (*value < min_node->getDoubleValue()) - *value = max_node->getDoubleValue(); - else if (*value > max_node->getDoubleValue()) - *value = min_node->getDoubleValue(); - } else { // clamp + if (wrap) { // wrap such that min <= x < max + double min_val = min_node->getDoubleValue(); + double max_val = max_node->getDoubleValue(); + double resolution = arg->getDoubleValue("resolution"); + if (resolution > 0.0) { + // snap to (min + N*resolution), taking special care to handle imprecision + int n = (int)floor((*value - min_val) / resolution + 0.5); + int steps = (int)floor((max_val - min_val) / resolution + 0.5); + SG_NORMALIZE_RANGE(n, 0, steps); + *value = min_val + resolution * n; + } else { + // plain circular wrapping + SG_NORMALIZE_RANGE(*value, min_val, max_val); + } + } else { // clamp such that min <= x <= max if ((min_node != 0) && (*value < min_node->getDoubleValue())) *value = min_node->getDoubleValue(); else if ((max_node != 0) && (*value > max_node->getDoubleValue()))
Index: navcom-radio.xml =================================================================== RCS file: /home/cvsroot/FlightGear/FlightGear/Aircraft/Instruments/navcom-radio.xml,v retrieving revision 1.4 diff -u -3 -p -d -r1.4 navcom-radio.xml --- navcom-radio.xml 2002/12/30 19:48:04 1.4 +++ navcom-radio.xml 2003/01/03 23:13:01 @@ -286,7 +286,8 @@ properties' values. <mask>decimal</mask> <step>-0.05</step> <min>0.00</min> - <max>0.95</max> + <max>1.00</max> + <resolution>0.05</resolution> <wrap>true</wrap> </binding> </action> @@ -304,7 +305,8 @@ properties' values. <mask>integer</mask> <step>-1</step> <min>108</min> - <max>117</max> + <max>118</max> + <resolution>1</resolution> <wrap>true</wrap> </binding> </action> @@ -322,7 +324,8 @@ properties' values. <mask>decimal</mask> <step>0.05</step> <min>0.00</min> - <max>0.95</max> + <max>1.00</max> + <resolution>0.05</resolution> <wrap>true</wrap> </binding> </action> @@ -340,7 +343,8 @@ properties' values. <mask>integer</mask> <step>1</step> <min>108</min> - <max>117</max> + <max>118</max> + <resolution>1</resolution> <wrap>true</wrap> </binding> </action> @@ -359,7 +363,8 @@ properties' values. <mask>decimal</mask> <step>-0.025</step> <min>0.000</min> - <max>0.975</max> + <max>1.000</max> + <resolution>0.025</resolution> <wrap>true</wrap> </binding> </action> @@ -377,7 +382,8 @@ properties' values. <mask>integer</mask> <step>-1</step> <min>118</min> - <max>135</max> + <max>136</max> + <resolution>1</resolution> <wrap>true</wrap> </binding> </action> @@ -395,7 +401,8 @@ properties' values. <mask>decimal</mask> <step>0.025</step> <min>0.000</min> - <max>0.975</max> + <max>1.000</max> + <resolution>0.025</resolution> <wrap>true</wrap> </binding> </action> @@ -413,7 +420,8 @@ properties' values. <mask>integer</mask> <step>1</step> <min>118</min> - <max>135</max> + <max>136</max> + <resolution>1</resolution> <wrap>true</wrap> </binding> </action>