X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fprops%2Fcondition.cxx;h=85c539cfe7183e001cb164a32538fe5c8ce4d0e2;hb=708ae35068499af33329f9db91f55441f4956acb;hp=014aff4596639790268236db06871d7e7f5cae8b;hpb=d22640ef4e938b523bdc30cd83370977d30de856;p=simgear.git diff --git a/simgear/props/condition.cxx b/simgear/props/condition.cxx index 014aff45..85c539cf 100644 --- a/simgear/props/condition.cxx +++ b/simgear/props/condition.cxx @@ -8,22 +8,142 @@ // $Id$ #ifdef HAVE_CONFIG_H -# include +# include #endif -// #include STL_IOSTREAM +// #include #include #include "props.hxx" #include "condition.hxx" -SG_USING_STD(istream); -SG_USING_STD(ostream); +#include +#include +using std::istream; +using std::ostream; + +/** + * Condition for a single property. + * + * This condition is true only if the property returns a boolean + * true value. + */ +class SGPropertyCondition : public SGCondition +{ +public: + SGPropertyCondition ( SGPropertyNode *prop_root, + const char * propname ); + virtual ~SGPropertyCondition (); + virtual bool test () const { return _node->getBoolValue(); } +private: + SGConstPropertyNode_ptr _node; +}; + +/** + * Condition with constant value + * + */ +class SGConstantCondition : public SGCondition +{ +public: + SGConstantCondition (bool v) : _value(v) { ; } + virtual bool test () const { return _value; } +private: + bool _value; +}; + +/** + * Condition for a 'not' operator. + * + * This condition is true only if the child condition is false. + */ +class SGNotCondition : public SGCondition +{ +public: + SGNotCondition (SGCondition * condition); + virtual ~SGNotCondition (); + virtual bool test () const; +private: + SGSharedPtr _condition; +}; + + +/** + * Condition for an 'and' group. + * + * This condition is true only if all of the conditions + * in the group are true. + */ +class SGAndCondition : public SGCondition +{ +public: + SGAndCondition (); + virtual ~SGAndCondition (); + virtual bool test () const; + // transfer pointer ownership + virtual void addCondition (SGCondition * condition); +private: + std::vector > _conditions; +}; + + +/** + * Condition for an 'or' group. + * + * This condition is true if at least one of the conditions in the + * group is true. + */ +class SGOrCondition : public SGCondition +{ +public: + SGOrCondition (); + virtual ~SGOrCondition (); + virtual bool test () const; + // transfer pointer ownership + virtual void addCondition (SGCondition * condition); +private: + std::vector > _conditions; +}; + + +/** + * Abstract base class for property comparison conditions. + */ +class SGComparisonCondition : public SGCondition +{ +public: + enum Type { + LESS_THAN, + GREATER_THAN, + EQUALS + }; + SGComparisonCondition (Type type, bool reverse = false); + virtual ~SGComparisonCondition (); + virtual bool test () const; + virtual void setLeftProperty( SGPropertyNode *prop_root, + const char * propname ); + virtual void setRightProperty( SGPropertyNode *prop_root, + const char * propname ); + // will make a local copy + virtual void setLeftValue (const SGPropertyNode * value); + virtual void setRightValue (const SGPropertyNode * value); + + void setLeftDExpression(SGExpressiond* dexp); + void setRightDExpression(SGExpressiond* dexp); + +private: + Type _type; + bool _reverse; + SGPropertyNode_ptr _left_property; + SGPropertyNode_ptr _right_property; + + SGSharedPtr _left_dexp; + SGSharedPtr _right_dexp; +}; - //////////////////////////////////////////////////////////////////////// // Implementation of SGCondition. //////////////////////////////////////////////////////////////////////// @@ -65,7 +185,6 @@ SGNotCondition::SGNotCondition (SGCondition * condition) SGNotCondition::~SGNotCondition () { - delete _condition; } bool @@ -86,8 +205,6 @@ SGAndCondition::SGAndCondition () SGAndCondition::~SGAndCondition () { - for (unsigned int i = 0; i < _conditions.size(); i++) - delete _conditions[i]; } bool @@ -119,8 +236,6 @@ SGOrCondition::SGOrCondition () SGOrCondition::~SGOrCondition () { - for (unsigned int i = 0; i < _conditions.size(); i++) - delete _conditions[i]; } bool @@ -149,8 +264,9 @@ SGOrCondition::addCondition (SGCondition * condition) static int doComparison (const SGPropertyNode * left, const SGPropertyNode *right) { + using namespace simgear; switch (left->getType()) { - case SGPropertyNode::BOOL: { + case props::BOOL: { bool v1 = left->getBoolValue(); bool v2 = right->getBoolValue(); if (v1 < v2) @@ -161,7 +277,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right) return SGComparisonCondition::EQUALS; break; } - case SGPropertyNode::INT: { + case props::INT: { int v1 = left->getIntValue(); int v2 = right->getIntValue(); if (v1 < v2) @@ -172,7 +288,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right) return SGComparisonCondition::EQUALS; break; } - case SGPropertyNode::LONG: { + case props::LONG: { long v1 = left->getLongValue(); long v2 = right->getLongValue(); if (v1 < v2) @@ -183,7 +299,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right) return SGComparisonCondition::EQUALS; break; } - case SGPropertyNode::FLOAT: { + case props::FLOAT: { float v1 = left->getFloatValue(); float v2 = right->getFloatValue(); if (v1 < v2) @@ -194,7 +310,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right) return SGComparisonCondition::EQUALS; break; } - case SGPropertyNode::DOUBLE: { + case props::DOUBLE: { double v1 = left->getDoubleValue(); double v2 = right->getDoubleValue(); if (v1 < v2) @@ -205,9 +321,9 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right) return SGComparisonCondition::EQUALS; break; } - case SGPropertyNode::STRING: - case SGPropertyNode::NONE: - case SGPropertyNode::UNSPECIFIED: { + case props::STRING: + case props::NONE: + case props::UNSPECIFIED: { string v1 = left->getStringValue(); string v2 = right->getStringValue(); if (v1 < v2) @@ -218,38 +334,41 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right) return SGComparisonCondition::EQUALS; break; } + default: + throw sg_exception("condition: unrecognized node type in comparison"); } - throw sg_exception("Unrecognized node type"); + return 0; } SGComparisonCondition::SGComparisonCondition (Type type, bool reverse) : _type(type), - _reverse(reverse), - _left_property(0), - _right_property(0), - _right_value(0) + _reverse(reverse) { } SGComparisonCondition::~SGComparisonCondition () { - delete _right_value; } bool SGComparisonCondition::test () const { // Always fail if incompletely specified - if (_left_property == 0 || - (_right_property == 0 && _right_value == 0)) + if (!_left_property || !_right_property) return false; - // Get LESS_THAN, EQUALS, or GREATER_THAN - int cmp = - doComparison(_left_property, - (_right_property != 0 ? _right_property : _right_value)); + // Get LESS_THAN, EQUALS, or GREATER_THAN + if (_left_dexp) { + _left_property->setDoubleValue(_left_dexp->getValue(NULL)); + } + + if (_right_dexp) { + _right_property->setDoubleValue(_right_dexp->getValue(NULL)); + } + + int cmp = doComparison(_left_property, _right_property); if (!_reverse) return (cmp == _type); else @@ -267,21 +386,35 @@ void SGComparisonCondition::setRightProperty( SGPropertyNode *prop_root, const char * propname ) { - delete _right_value; - _right_value = 0; _right_property = prop_root->getNode(propname, true); } +void +SGComparisonCondition::setLeftValue (const SGPropertyNode *node) +{ + _left_property = new SGPropertyNode(*node); +} + + void SGComparisonCondition::setRightValue (const SGPropertyNode *node) { - _right_property = 0; - delete _right_value; - _right_value = new SGPropertyNode(*node); + _right_property = new SGPropertyNode(*node); } +void +SGComparisonCondition::setLeftDExpression(SGExpressiond* dexp) +{ + _left_property = new SGPropertyNode(); + _left_dexp = dexp; +} - +void +SGComparisonCondition::setRightDExpression(SGExpressiond* dexp) +{ + _right_property = new SGPropertyNode(); + _right_dexp = dexp; +} //////////////////////////////////////////////////////////////////////// // Read a condition and use it if necessary. //////////////////////////////////////////////////////////////////////// @@ -307,7 +440,7 @@ readNotCondition( SGPropertyNode *prop_root, const SGPropertyNode *node ) if (condition != 0) return new SGNotCondition(condition); } - SG_LOG(SG_COCKPIT, SG_ALERT, "Panel: empty 'not' condition"); + SG_LOG(SG_COCKPIT, SG_ALERT, "empty 'not' condition"); return 0; } @@ -346,12 +479,36 @@ readComparison( SGPropertyNode *prop_root, bool reverse) { SGComparisonCondition * condition = new SGComparisonCondition(type, reverse); - condition->setLeftProperty(prop_root, node->getStringValue("property[0]")); - if (node->hasValue("property[1]")) - condition->setRightProperty(prop_root, node->getStringValue("property[1]")); - else - condition->setRightValue(node->getChild("value", 0)); - + if (node->nChildren() != 2) { + throw sg_exception("condition: comparison without two children"); + } + + const SGPropertyNode* left = node->getChild(0), + *right = node->getChild(1); + string leftName(left->getName()); + if (leftName == "property") { + condition->setLeftProperty(prop_root, left->getStringValue()); + } else if (leftName == "value") { + condition->setLeftValue(left); + } else if (leftName == "expression") { + SGExpressiond* exp = SGReadDoubleExpression(prop_root, left->getChild(0)); + condition->setLeftDExpression(exp); + } else { + throw sg_exception("Unknown condition comparison left child:" + leftName); + } + + string rightName(right->getName()); + if (rightName == "property") { + condition->setRightProperty(prop_root, right->getStringValue()); + } else if (rightName == "value") { + condition->setRightValue(right); + } else if (rightName == "expression") { + SGExpressiond* exp = SGReadDoubleExpression(prop_root, right->getChild(0)); + condition->setRightDExpression(exp); + } else { + throw sg_exception("Unknown condition comparison right child:" + rightName); + } + return condition; } @@ -384,6 +541,10 @@ readCondition( SGPropertyNode *prop_root, const SGPropertyNode *node ) false); else if (name == "not-equals") return readComparison(prop_root, node, SGComparisonCondition::EQUALS, true); + else if (name == "false") + return new SGConstantCondition(false); + else if (name == "true") + return new SGConstantCondition(true); else return 0; } @@ -401,13 +562,11 @@ SGConditional::SGConditional () SGConditional::~SGConditional () { - delete _condition; } void SGConditional::setCondition (SGCondition * condition) { - delete _condition; _condition = condition; }