X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fstructure%2FSGExpression.hxx;h=2cfa3dc8909d629959816210282535f3be13f37c;hb=b2c3a90adfb6c0285d02355fd8ab061b7f2f1e6c;hp=2dac8efb1863c105bfd78b045af4289180df6c06;hpb=efec9070e178c9aef98332cb03d967868179ae4a;p=simgear.git diff --git a/simgear/structure/SGExpression.hxx b/simgear/structure/SGExpression.hxx index 2dac8efb..2cfa3dc8 100644 --- a/simgear/structure/SGExpression.hxx +++ b/simgear/structure/SGExpression.hxx @@ -24,6 +24,9 @@ #include #include +#include +#include +#include #include #include @@ -31,6 +34,7 @@ #include #include #include +#include /// Expression tree implementation. @@ -121,6 +125,9 @@ public: T getValue(const simgear::expression::Binding* binding = 0) const { T value; eval(value, binding); return value; } + double getDoubleValue(const simgear::expression::Binding* binding = 0) const + { T value; eval(value, binding); return value; } + virtual bool isConst() const { return false; } virtual SGExpression* simplify(); virtual simgear::expression::Type getType() const @@ -131,6 +138,8 @@ public: { return simgear::expression::TypeTraits::typeTag; } + virtual void collectDependentProperties(std::set& props) const + { } }; /// Constant value expression @@ -179,7 +188,9 @@ public: _expression = _expression->simplify(); return SGExpression::simplify(); } - + + virtual void collectDependentProperties(std::set& props) const + { _expression->collectDependentProperties(props); } protected: SGUnaryExpression(SGExpression* expression = 0) { setOperand(expression); } @@ -191,11 +202,11 @@ private: template class SGBinaryExpression : public SGExpression { public: - const SGExpression* getOperand(unsigned i) const + const SGExpression* getOperand(size_t i) const { return _expressions[i]; } - SGExpression* getOperand(unsigned i) + SGExpression* getOperand(size_t i) { return _expressions[i]; } - void setOperand(unsigned i, SGExpression* expression) + void setOperand(size_t i, SGExpression* expression) { if (!expression) expression = new SGConstExpression(T()); @@ -213,6 +224,12 @@ public: return SGExpression::simplify(); } + virtual void collectDependentProperties(std::set& props) const + { + _expressions[0]->collectDependentProperties(props); + _expressions[1]->collectDependentProperties(props); + } + protected: SGBinaryExpression(SGExpression* expr0, SGExpression* expr1) { setOperand(0, expr0); setOperand(1, expr1); } @@ -224,16 +241,16 @@ private: template class SGNaryExpression : public SGExpression { public: - unsigned getNumOperands() const + size_t getNumOperands() const { return _expressions.size(); } - const SGExpression* getOperand(unsigned i) const + const SGExpression* getOperand(size_t i) const { return _expressions[i]; } - SGExpression* getOperand(unsigned i) + SGExpression* getOperand(size_t i) { return _expressions[i]; } - unsigned addOperand(SGExpression* expression) + size_t addOperand(SGExpression* expression) { if (!expression) - return ~unsigned(0); + return ~size_t(0); _expressions.push_back(expression); return _expressions.size() - 1; } @@ -249,18 +266,23 @@ public: virtual bool isConst() const { - for (unsigned i = 0; i < _expressions.size(); ++i) + for (size_t i = 0; i < _expressions.size(); ++i) if (!_expressions[i]->isConst()) return false; return true; } virtual SGExpression* simplify() { - for (unsigned i = 0; i < _expressions.size(); ++i) + for (size_t i = 0; i < _expressions.size(); ++i) _expressions[i] = _expressions[i]->simplify(); return SGExpression::simplify(); } + virtual void collectDependentProperties(std::set& props) const + { + for (size_t i = 0; i < _expressions.size(); ++i) + _expressions[i]->collectDependentProperties(props); + } protected: SGNaryExpression() { } @@ -283,6 +305,9 @@ public: { _prop = prop; } virtual void eval(T& value, const simgear::expression::Binding*) const { doEval(value); } + + virtual void collectDependentProperties(std::set& props) const + { props.insert(_prop.get()); } private: void doEval(float& value) const { if (_prop) value = _prop->getFloatValue(); } @@ -318,7 +343,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = acos(SGMisc::clip(getOperand()->getValue(b), -1, 1)); } + { value = acos((double)SGMisc::clip(getOperand()->getValue(b), -1, 1)); } using SGUnaryExpression::getOperand; }; @@ -331,7 +356,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = asin(SGMisc::clip(getOperand()->getValue(b), -1, 1)); } + { value = asin((double)SGMisc::clip(getOperand()->getValue(b), -1, 1)); } using SGUnaryExpression::getOperand; }; @@ -344,7 +369,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = atan(getOperand()->getValue(b)); } + { value = atan(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -357,7 +382,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = ceil(getOperand()->getValue(b)); } + { value = ceil(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -370,7 +395,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = cos(getOperand()->getValue(b)); } + { value = cos(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -383,7 +408,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = cosh(getOperand()->getValue(b)); } + { value = cosh(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -396,7 +421,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = exp(getOperand()->getValue(b)); } + { value = exp(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -409,7 +434,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = floor(getOperand()->getValue(b)); } + { value = floor(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -422,7 +447,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = log(getOperand()->getValue(b)); } + { value = log(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -435,7 +460,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = log10(getOperand()->getValue(b)); } + { value = log10(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -448,7 +473,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = sin(getOperand()->getValue(b)); } + { value = sin(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -461,7 +486,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = sinh(getOperand()->getValue(b)); } + { value = sinh(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -487,7 +512,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = sqrt(getOperand()->getValue(b)); } + { value = sqrt(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -500,7 +525,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = tan(getOperand()->getValue(b)); } + { value = tan(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -513,7 +538,7 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = tanh(getOperand()->getValue(b)); } + { value = tanh(getOperand()->getDoubleValue(b)); } using SGUnaryExpression::getOperand; }; @@ -661,24 +686,16 @@ public: private: T apply_mods(T property) const { - T modprop; - if (_step > 0) { - T scrollval = 0; - if(_scroll > 0) { - // calculate scroll amount (for odometer like movement) - T remainder = _step - fmod(fabs(property), _step); - if (remainder < _scroll) { - scrollval = (_scroll - remainder) / _scroll * _step; - } - } - // apply stepping of input value - if(property > 0) - modprop = ((floor(property/_step) * _step) + scrollval); - else - modprop = ((ceil(property/_step) * _step) + scrollval); - } else { - modprop = property; - } + if( _step <= SGLimits::min() ) return property; + + // apply stepping of input value + T modprop = floor(property/_step)*_step; + + // calculate scroll amount (for odometer like movement) + T remainder = property <= SGLimits::min() ? -fmod(property,_step) : (_step - fmod(property,_step)); + if( remainder > SGLimits::min() && remainder < _scroll ) + modprop += (_scroll - remainder) / _scroll * _step; + return modprop; } @@ -716,6 +733,12 @@ public: return getOperand()->simplify(); return SGUnaryExpression::simplify(); } + + virtual void collectDependentProperties(std::set& props) const + { + SGUnaryExpression::collectDependentProperties(props); + _enable->collectDependentProperties(props); + } using SGUnaryExpression::getOperand; private: @@ -730,7 +753,7 @@ public: : SGBinaryExpression(expr0, expr1) { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = atan2(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); } + { value = atan2(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); } using SGBinaryExpression::getOperand; }; @@ -770,7 +793,7 @@ public: : SGBinaryExpression(expr0, expr1) { } virtual void eval(T& value, const simgear::expression::Binding* b) const - { value = pow(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); } + { value = pow(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); } using SGBinaryExpression::getOperand; }; @@ -785,14 +808,33 @@ public: virtual void eval(T& value, const simgear::expression::Binding* b) const { value = T(0); - unsigned sz = SGNaryExpression::getNumOperands(); - for (unsigned i = 0; i < sz; ++i) + size_t sz = SGNaryExpression::getNumOperands(); + for (size_t i = 0; i < sz; ++i) value += getOperand(i)->getValue(b); } using SGNaryExpression::getValue; using SGNaryExpression::getOperand; }; +template +class SGDifferenceExpression : public SGNaryExpression { +public: + SGDifferenceExpression() + { } + SGDifferenceExpression(SGExpression* expr0, SGExpression* expr1) + : SGNaryExpression(expr0, expr1) + { } + virtual void eval(T& value, const simgear::expression::Binding* b) const + { + value = getOperand(0)->getValue(b); + size_t sz = SGNaryExpression::getNumOperands(); + for (size_t i = 1; i < sz; ++i) + value -= getOperand(i)->getValue(b); + } + using SGNaryExpression::getValue; + using SGNaryExpression::getOperand; +}; + template class SGProductExpression : public SGNaryExpression { public: @@ -804,8 +846,8 @@ public: virtual void eval(T& value, const simgear::expression::Binding* b) const { value = T(1); - unsigned sz = SGNaryExpression::getNumOperands(); - for (unsigned i = 0; i < sz; ++i) + size_t sz = SGNaryExpression::getNumOperands(); + for (size_t i = 0; i < sz; ++i) value *= getOperand(i)->getValue(b); } using SGNaryExpression::getValue; @@ -822,12 +864,12 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const { - unsigned sz = SGNaryExpression::getNumOperands(); + size_t sz = SGNaryExpression::getNumOperands(); if (sz < 1) return; value = getOperand(0)->getValue(b); - for (unsigned i = 1; i < sz; ++i) + for (size_t i = 1; i < sz; ++i) value = SGMisc::min(value, getOperand(i)->getValue(b)); } using SGNaryExpression::getOperand; @@ -843,12 +885,12 @@ public: { } virtual void eval(T& value, const simgear::expression::Binding* b) const { - unsigned sz = SGNaryExpression::getNumOperands(); + size_t sz = SGNaryExpression::getNumOperands(); if (sz < 1) return; value = getOperand(0)->getValue(b); - for (unsigned i = 1; i < sz; ++i) + for (size_t i = 1; i < sz; ++i) value = SGMisc::max(value, getOperand(i)->getValue(b)); } using SGNaryExpression::getOperand; @@ -859,6 +901,11 @@ typedef SGExpression SGExpressionf; typedef SGExpression SGExpressiond; typedef SGExpression SGExpressionb; +typedef SGSharedPtr SGExpressioni_ref; +typedef SGSharedPtr SGExpressionf_ref; +typedef SGSharedPtr SGExpressiond_ref; +typedef SGSharedPtr SGExpressionb_ref; + /** * Global function to make an expression out of properties. @@ -903,7 +950,7 @@ namespace simgear { struct ParseError : public sg_exception { - ParseError(const string& message = std::string()) + ParseError(const std::string& message = std::string()) : sg_exception(message) {} }; @@ -967,8 +1014,8 @@ namespace simgear class BindingLayout { public: - int addBinding(const std::string& name, expression::Type type); - bool findBinding(const string& name, VariableBinding& result) const; + size_t addBinding(const std::string& name, expression::Type type); + bool findBinding(const std::string& name, VariableBinding& result) const; std::vector bindings; }; @@ -985,7 +1032,7 @@ namespace simgear ParserMap& map = getParserMap(); ParserMap::iterator itr = map.find(exp->getName()); if (itr == map.end()) - throw ParseError(string("unknown expression ") + exp->getName()); + throw ParseError(std::string("unknown expression ") + exp->getName()); exp_parser parser = itr->second; return (*parser)(exp, this); } @@ -1009,10 +1056,16 @@ namespace simgear class ExpressionParser : public Parser { public: - ParserMap& getParserMap() { return _parserTable; } + ParserMap& getParserMap() + { + return ParserMapSingleton::instance()->_parserTable; + } static void addExpParser(const std::string&, exp_parser); protected: - static ParserMap _parserTable; + struct ParserMapSingleton : public simgear::Singleton + { + ParserMap _parserTable; + }; }; /** @@ -1054,16 +1107,16 @@ namespace simgear class GeneralNaryExpression : public ::SGExpression { public: typedef OpType operand_type; - unsigned getNumOperands() const + size_t getNumOperands() const { return _expressions.size(); } - const ::SGExpression* getOperand(unsigned i) const + const ::SGExpression* getOperand(size_t i) const { return _expressions[i]; } - ::SGExpression* getOperand(unsigned i) + ::SGExpression* getOperand(size_t i) { return _expressions[i]; } - unsigned addOperand(::SGExpression* expression) + size_t addOperand(::SGExpression* expression) { if (!expression) - return ~unsigned(0); + return ~size_t(0); _expressions.push_back(expression); return _expressions.size() - 1; } @@ -1079,14 +1132,14 @@ namespace simgear virtual bool isConst() const { - for (unsigned i = 0; i < _expressions.size(); ++i) + for (size_t i = 0; i < _expressions.size(); ++i) if (!_expressions[i]->isConst()) return false; return true; } virtual ::SGExpression* simplify() { - for (unsigned i = 0; i < _expressions.size(); ++i) + for (size_t i = 0; i < _expressions.size(); ++i) _expressions[i] = _expressions[i]->simplify(); return SGExpression::simplify(); } @@ -1123,7 +1176,7 @@ namespace simgear } virtual void eval(bool& value, const simgear::expression::Binding* b) const { - unsigned sz = this->getNumOperands(); + size_t sz = this->getNumOperands(); if (sz != 2) return; value = _pred(this->getOperand(0)->getValue(b), @@ -1195,7 +1248,7 @@ namespace simgear void eval(bool& value, const expression::Binding* b) const { value = false; - for (int i = 0; i < getNumOperands(); ++i) { + for (int i = 0; i < (int)getNumOperands(); ++i) { value = value || getOperand(i)->getValue(b); if (value) return; @@ -1209,7 +1262,7 @@ namespace simgear void eval(bool& value, const expression::Binding* b) const { value = true; - for (int i = 0; i < getNumOperands(); ++i) { + for (int i = 0; i < (int)getNumOperands(); ++i) { value = value && getOperand(i)->getValue(b); if (!value) return; @@ -1227,7 +1280,7 @@ namespace simgear ConvertExpression() {} ConvertExpression(::SGExpression* expr0) { - addOperand(expr0); + this->addOperand(expr0); } virtual void eval(T& value, const simgear::expression::Binding* b) const {