1
0
Fork 0

Major code simplification.

This commit is contained in:
david 2002-10-25 22:19:51 +00:00
parent 4c2e97be18
commit d43dfa54df

View file

@ -34,79 +34,39 @@ SG_USING_STD(ofstream);
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Saved command states. // Static helper functions.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/** /**
* Base saved state for property commands. * Template function to wrap a value.
*
* Since this class isn't publicly visible, it is simply an aggregate
* of all the stuff any property command needs.
*/ */
class PropertyCommandState : public SGCommandState template <class T>
static inline void
do_wrap (T * value, T min, T max)
{ {
public: if (min >= max) { // basic sanity check
PropertyCommandState (const SGPropertyNode * arg); *value = min;
virtual SGPropertyNode * getProp () const { return _prop; } } else {
virtual SGPropertyNode * getProp2 () const { return _prop2; } T range = max - min;
virtual const SGPropertyNode * getValue () const while (*value < min)
{ return _value ? _value : &_dummy_0; } *value += range;
virtual const bool hasStep () const { return _step != 0; } while (*value > max)
virtual const SGPropertyNode * getStep () const *value -= range;
{ return _step ? _step : &_dummy_0; } }
virtual const SGPropertyNode * getMin () const { return _min; }
virtual const SGPropertyNode * getMax () const { return _max; }
virtual const SGPropertyNode * getWrap () const
{ return _wrap ? _wrap : &_dummy_0; }
virtual const SGPropertyNode * getFactor () const
{ return _factor ? _factor : &_dummy_1; }
virtual const SGPropertyNode * getSquared () const
{ return _squared ? _squared : &_dummy_0; }
virtual const SGPropertyNode * getSetting () const
{ return _setting ? _setting : &_dummy_0; }
virtual const SGPropertyNode * getOffset () const
{ return _offset ? _offset : &_dummy_0; }
private:
static SGPropertyNode _dummy_0;
static SGPropertyNode _dummy_1;
mutable SGPropertyNode * _prop;
mutable SGPropertyNode * _prop2;
const SGPropertyNode * _value;
const SGPropertyNode * _step;
const SGPropertyNode * _min;
const SGPropertyNode * _max;
const SGPropertyNode * _wrap;
const SGPropertyNode * _factor;
const SGPropertyNode * _squared;
const SGPropertyNode * _setting;
const SGPropertyNode * _offset;
};
SGPropertyNode PropertyCommandState::_dummy_0;
SGPropertyNode PropertyCommandState::_dummy_1;
PropertyCommandState::PropertyCommandState (const SGPropertyNode * arg)
: SGCommandState(arg),
_prop(fgGetNode(arg->getStringValue("property[0]", "/null"), true)),
_prop2(fgGetNode(arg->getStringValue("property[1]", "/null"), true)),
_value(arg->getNode("value")),
_step(arg->getNode("step")),
_min(arg->getNode("min")),
_max(arg->getNode("max")),
_wrap(arg->getNode("wrap")),
_factor(arg->getNode("factor")),
_squared(arg->getNode("squared")),
_setting(arg->getNode("setting")),
_offset(arg->getNode("offset"))
{
// It would be better not to do this
// every time, but it's not that big
// a deal. I don't know enough about
// C++ static initialization to fix it.
_dummy_1.setDoubleValue(1.0);
} }
static inline SGPropertyNode *
get_prop (const SGPropertyNode * arg)
{
return fgGetNode(arg->getStringValue("property[0]", "/null"), true);
}
static inline SGPropertyNode *
get_prop2 (const SGPropertyNode * arg)
{
return fgGetNode(arg->getStringValue("property[1]", "/null"), true);
}
@ -367,9 +327,7 @@ do_lighting_update (const SGPropertyNode * arg, SGCommandState ** state)
static bool static bool
do_property_toggle (const SGPropertyNode * arg, SGCommandState ** state) do_property_toggle (const SGPropertyNode * arg, SGCommandState ** state)
{ {
if (*state == 0) SGPropertyNode * prop = get_prop(arg);
*state = new PropertyCommandState(arg);
SGPropertyNode * prop = ((PropertyCommandState *)(*state))->getProp();
return prop->setBoolValue(!prop->getBoolValue()); return prop->setBoolValue(!prop->getBoolValue());
} }
@ -383,27 +341,32 @@ do_property_toggle (const SGPropertyNode * arg, SGCommandState ** state)
static bool static bool
do_property_assign (const SGPropertyNode * arg, SGCommandState ** state) do_property_assign (const SGPropertyNode * arg, SGCommandState ** state)
{ {
if (*state == 0) SGPropertyNode * prop = get_prop(arg);
*state = new PropertyCommandState(arg); const SGPropertyNode * value = arg->getNode("value");
SGPropertyNode * prop = ((PropertyCommandState *)(*state))->getProp();
const SGPropertyNode * value =
((PropertyCommandState *)(*state))->getValue();
switch (prop->getType()) { switch (prop->getType()) {
case SGPropertyNode::BOOL: case SGPropertyNode::BOOL:
return prop->setBoolValue(value->getBoolValue()); return prop->setBoolValue(value->getBoolValue());
case SGPropertyNode::INT: case SGPropertyNode::INT:
return prop->setIntValue(value->getIntValue()); return prop->setIntValue(value->getIntValue());
case SGPropertyNode::LONG: case SGPropertyNode::LONG:
return prop->setLongValue(value->getLongValue()); return prop->setLongValue(value->getLongValue());
case SGPropertyNode::FLOAT: case SGPropertyNode::FLOAT:
return prop->setFloatValue(value->getFloatValue()); return prop->setFloatValue(value->getFloatValue());
case SGPropertyNode::DOUBLE: case SGPropertyNode::DOUBLE:
return prop->setDoubleValue(value->getDoubleValue()); return prop->setDoubleValue(value->getDoubleValue());
case SGPropertyNode::STRING: case SGPropertyNode::STRING:
return prop->setStringValue(value->getStringValue()); return prop->setStringValue(value->getStringValue());
default: default:
return prop->setUnspecifiedValue(value->getStringValue()); return prop->setUnspecifiedValue(value->getStringValue());
} }
} }
@ -424,29 +387,26 @@ do_property_assign (const SGPropertyNode * arg, SGCommandState ** state)
static bool static bool
do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state) do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state)
{ {
if (*state == 0) SGPropertyNode * prop = get_prop(arg);
*state = new PropertyCommandState(arg); const SGPropertyNode * step = arg->getChild("step");
bool hasStep = ((PropertyCommandState *)(*state))->hasStep(); const SGPropertyNode * offset = arg->getChild("offset");
SGPropertyNode * prop = ((PropertyCommandState *)(*state))->getProp(); const SGPropertyNode * factor = arg->getChild("factor");
const SGPropertyNode * step = ((PropertyCommandState *)(*state))->getStep(); const SGPropertyNode * min = arg->getChild("min");
const SGPropertyNode * offset = const SGPropertyNode * max = arg->getChild("max");
((PropertyCommandState *)(*state))->getOffset(); bool wrap = arg->getBoolValue("wrap");
const SGPropertyNode * factor =
((PropertyCommandState *)(*state))->getFactor(); if (min == 0 || max == 0)
const SGPropertyNode * min = ((PropertyCommandState *)(*state))->getMin(); wrap = false;
const SGPropertyNode * max = ((PropertyCommandState *)(*state))->getMax();
bool wrap = ((PropertyCommandState *)(*state))->getWrap()->getBoolValue();
double amount = 0; double amount = 0;
if (!hasStep) { if (step == 0)
amount = offset->getDoubleValue() * factor->getDoubleValue(); amount = offset->getDoubleValue() * factor->getDoubleValue();
}
switch (prop->getType()) { switch (prop->getType()) {
case SGPropertyNode::BOOL:
case SGPropertyNode::BOOL: {
bool value; bool value;
if (hasStep) if (step != 0)
value = step->getBoolValue(); value = step->getBoolValue();
else else
value = (0.0 != amount); value = (0.0 != amount);
@ -454,94 +414,86 @@ do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state)
return prop->setBoolValue(!prop->getBoolValue()); return prop->setBoolValue(!prop->getBoolValue());
else else
return true; return true;
}
case SGPropertyNode::INT: { case SGPropertyNode::INT: {
int value; int value;
if (hasStep) if (step != 0)
value = prop->getIntValue() + step->getIntValue(); value = prop->getIntValue() + step->getIntValue();
else else
value = prop->getIntValue() + int(amount); value = prop->getIntValue() + int(amount);
if (min && (value < min->getIntValue())) { if (wrap) {
if (wrap && max) do_wrap(&value, min->getIntValue(), max->getIntValue());
value = max->getIntValue(); } else {
else if (min != 0 && value < min->getIntValue())
value = min->getIntValue(); value = min->getIntValue();
} if (max != 0 && value > max->getIntValue())
if (max && value > max->getIntValue()) { value = max->getIntValue();
if (wrap && min)
value = min->getIntValue();
else
value = max->getIntValue();
} }
return prop->setIntValue(value); return prop->setIntValue(value);
} }
case SGPropertyNode::LONG: { case SGPropertyNode::LONG: {
long value; long value;
if (hasStep) if (step != 0)
value = prop->getLongValue() + step->getLongValue(); value = prop->getLongValue() + step->getLongValue();
else else
value = prop->getLongValue() + long(amount); value = prop->getLongValue() + long(amount);
if (min && (value < min->getLongValue())) { if (wrap) {
if (wrap && max) do_wrap(&value, min->getLongValue(), max->getLongValue());
value = max->getLongValue(); } else {
else if (min != 0 && value < min->getLongValue())
value = min->getLongValue(); value = min->getLongValue();
} if (max != 0 && value > max->getLongValue())
if (max && value > max->getLongValue()) { value = max->getLongValue();
if (wrap && min)
value = min->getLongValue();
else
value = max->getLongValue();
} }
return prop->setLongValue(value); return prop->setLongValue(value);
} }
case SGPropertyNode::FLOAT: { case SGPropertyNode::FLOAT: {
float value; float value;
if (hasStep) if (step != 0)
value = prop->getFloatValue() + step->getFloatValue(); value = prop->getFloatValue() + step->getFloatValue();
else else
value = prop->getFloatValue() + float(amount); value = prop->getFloatValue() + float(amount);
if (min && (value < min->getFloatValue())) { if (wrap) {
if (wrap && max) do_wrap(&value, min->getFloatValue(), max->getFloatValue());
value = max->getFloatValue(); } else {
else if (min != 0 && value < min->getFloatValue())
value = min->getFloatValue(); value = min->getFloatValue();
} if (max != 0 && value > max->getFloatValue())
if (max && value > max->getFloatValue()) { value = max->getFloatValue();
if (wrap && min)
value = min->getFloatValue();
else
value = max->getFloatValue();
} }
return prop->setFloatValue(value); return prop->setFloatValue(value);
} }
case SGPropertyNode::DOUBLE: case SGPropertyNode::DOUBLE:
case SGPropertyNode::UNSPECIFIED: case SGPropertyNode::UNSPECIFIED:
case SGPropertyNode::NONE: { case SGPropertyNode::NONE: {
double value; double value;
if (hasStep) if (step != 0)
value = prop->getDoubleValue() + step->getDoubleValue(); value = prop->getDoubleValue() + step->getDoubleValue();
else else
value = prop->getDoubleValue() + amount; value = prop->getDoubleValue() + amount;
if (min && (value < min->getDoubleValue())) { if (wrap) {
if (wrap && max) do_wrap(&value, min->getDoubleValue(), max->getDoubleValue());
value = max->getDoubleValue(); } else {
else if (min != 0 && value < min->getDoubleValue())
value = min->getDoubleValue(); value = min->getDoubleValue();
} if (max != 0 && value > max->getDoubleValue())
if (max && value > max->getDoubleValue()) { value = max->getDoubleValue();
if (wrap && min)
value = min->getDoubleValue();
else
value = max->getDoubleValue();
} }
return prop->setDoubleValue(value); return prop->setDoubleValue(value);
} }
case SGPropertyNode::STRING: // doesn't make sense with strings case SGPropertyNode::STRING: // doesn't make sense with strings
SG_LOG(SG_INPUT, SG_ALERT, "Cannot adjust a string value"); SG_LOG(SG_INPUT, SG_ALERT, "Cannot adjust a string value");
return false; return false;
default: default:
SG_LOG(SG_INPUT, SG_ALERT, "Unknown value type"); SG_LOG(SG_INPUT, SG_ALERT, "Unknown value type");
return false; return false;
} }
} }
@ -555,30 +507,35 @@ do_property_adjust (const SGPropertyNode * arg, SGCommandState ** state)
static bool static bool
do_property_multiply (const SGPropertyNode * arg, SGCommandState ** state) do_property_multiply (const SGPropertyNode * arg, SGCommandState ** state)
{ {
if (*state == 0) SGPropertyNode * prop = get_prop(arg);
*state = new PropertyCommandState(arg); const SGPropertyNode * factor = arg->getChild("factor");
SGPropertyNode * prop = ((PropertyCommandState *)(*state))->getProp();
const SGPropertyNode * factor = if (factor == 0)
((PropertyCommandState *)(*state))->getFactor(); return true;
switch (prop->getType()) { switch (prop->getType()) {
case SGPropertyNode::BOOL: case SGPropertyNode::BOOL:
return prop->setBoolValue(prop->getBoolValue() && return prop->setBoolValue(prop->getBoolValue() && factor->getBoolValue());
factor->getBoolValue());
case SGPropertyNode::INT: case SGPropertyNode::INT:
return prop->setIntValue(int(prop->getIntValue() return prop->setIntValue(int(prop->getIntValue()
* factor->getDoubleValue())); * factor->getDoubleValue()));
case SGPropertyNode::LONG: case SGPropertyNode::LONG:
return prop->setLongValue(long(prop->getLongValue() return prop->setLongValue(long(prop->getLongValue()
* factor->getDoubleValue())); * factor->getDoubleValue()));
case SGPropertyNode::FLOAT: case SGPropertyNode::FLOAT:
return prop->setFloatValue(float(prop->getFloatValue() return prop->setFloatValue(float(prop->getFloatValue()
* factor->getDoubleValue())); * factor->getDoubleValue()));
case SGPropertyNode::DOUBLE: case SGPropertyNode::DOUBLE:
case SGPropertyNode::UNSPECIFIED: case SGPropertyNode::UNSPECIFIED:
case SGPropertyNode::NONE: case SGPropertyNode::NONE:
return prop->setDoubleValue(prop->getDoubleValue() return prop->setDoubleValue(prop->getDoubleValue()
* factor->getDoubleValue()); * factor->getDoubleValue());
default: // doesn't make sense with strings default: // doesn't make sense with strings
return false; return false;
} }
@ -594,10 +551,8 @@ do_property_multiply (const SGPropertyNode * arg, SGCommandState ** state)
static bool static bool
do_property_swap (const SGPropertyNode * arg, SGCommandState ** state) do_property_swap (const SGPropertyNode * arg, SGCommandState ** state)
{ {
if (*state == 0) SGPropertyNode * prop1 = get_prop(arg);
*state = new PropertyCommandState(arg); SGPropertyNode * prop2 = get_prop2(arg);
SGPropertyNode * prop1 = ((PropertyCommandState *)(*state))->getProp();
SGPropertyNode * prop2 = ((PropertyCommandState *)(*state))->getProp2();
// FIXME: inefficient // FIXME: inefficient
const string & tmp = prop1->getStringValue(); const string & tmp = prop1->getStringValue();
@ -617,23 +572,16 @@ do_property_swap (const SGPropertyNode * arg, SGCommandState ** state)
static bool static bool
do_property_scale (const SGPropertyNode * arg, SGCommandState ** state) do_property_scale (const SGPropertyNode * arg, SGCommandState ** state)
{ {
if (*state == 0) SGPropertyNode * prop = get_prop(arg);
*state = new PropertyCommandState(arg); double setting = arg->getDoubleValue("setting");
SGPropertyNode * prop = ((PropertyCommandState *)(*state))->getProp(); double offset = arg->getDoubleValue("offset", 0.0);
double setting = double factor = arg->getDoubleValue("factor", 1.0);
((PropertyCommandState *)(*state))->getSetting()->getDoubleValue(); bool squared = arg->getBoolValue("squared", false);
double offset =
((PropertyCommandState *)(*state))->getOffset()->getDoubleValue();
double factor =
((PropertyCommandState *)(*state))->getFactor()->getDoubleValue();
bool squared =
((PropertyCommandState *)(*state))->getSquared()->getBoolValue();
if (squared) if (squared)
setting = (setting < 0 ? -1 : 1) * setting * setting; setting = (setting < 0 ? -1 : 1) * setting * setting;
double result = (setting + offset) * factor;
return prop->setDoubleValue(result); return prop->setDoubleValue((setting + offset) * factor);
} }