1
0
Fork 0

Patch from Julian Foad to fix wrapping behaviour for property-adjust

and property-multiply:

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".

[also fixed]

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
This commit is contained in:
david 2003-01-04 18:47:25 +00:00
parent a1d4e79127
commit 1ec788b6da

View file

@ -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 SGPropertyNode * arg)
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()))
@ -278,7 +272,7 @@ fix_hud_visibility()
}
}
void
static void
do_view_next( bool )
{
globals->get_current_view()->setHeadingOffset_deg(0.0);
@ -287,7 +281,7 @@ do_view_next( bool )
globals->get_tile_mgr()->refresh_view_timestamps();
}
void
static void
do_view_prev( bool )
{
globals->get_current_view()->setHeadingOffset_deg(0.0);
@ -438,6 +432,8 @@ do_property_adjust (const SGPropertyNode * arg)
limit_value(&modifiable, arg);
prop->setDoubleValue(unmodifiable + modifiable);
return true;
}
@ -468,6 +464,8 @@ do_property_multiply (const SGPropertyNode * arg)
limit_value(&modifiable, arg);
prop->setDoubleValue(unmodifiable + modifiable);
return true;
}
@ -530,7 +528,7 @@ do_dialog_show (const SGPropertyNode * arg)
/**
* Hide the active XML-configured dialog.
* Built-in Command: Hide the active XML-configured dialog.
*/
static bool
do_dialog_close (const SGPropertyNode * arg)