David Megginson wrote:
Julian Foad writes:

> 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.
OK. I think the best thing to do would be:

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>


Reply via email to