/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2020 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #ifndef OSGEARTHSYMBOLOGY_EXPRESSION_H #define OSGEARTHSYMBOLOGY_EXPRESSION_H 1 #include #include #include #include #include #include namespace osgEarth { /** * Simple numeric expression evaluator with variables. */ class OSGEARTH_EXPORT NumericExpression { public: typedef std::pair Variable; typedef std::vector Variables; public: NumericExpression(); NumericExpression( const Config& conf ); /** Construct a new expression from the infix string. */ NumericExpression( const std::string& expr ); /** Construct a new static expression from a value */ NumericExpression( double staticValue ); /** Copy ctor. */ NumericExpression( const NumericExpression& rhs ); /** dtor */ virtual ~NumericExpression() { } /** Set the result to a literal value. */ void setLiteral( double staticValue ); /** Access the expression variables. */ const Variables& variables() const { return _vars; } /** Set the value of a variable. */ void set( const Variable& var, double value ); /** Evaluate the expression. */ double eval() const; /** Gets the expression string. */ const std::string& expr() const { return _src; } /** Whether the expression is empty */ bool empty() const { return _src.empty(); } public: Config getConfig() const; void mergeConfig( const Config& conf ); private: enum Op { OPERAND, VARIABLE, ADD, SUB, MULT, DIV, MOD, MIN, MAX, LPAREN, RPAREN, COMMA }; // in low-high precedence order typedef std::pair Atom; typedef std::vector AtomVector; typedef std::stack AtomStack; std::string _src; AtomVector _rpn; Variables _vars; double _value; bool _dirty; void init(); }; //-------------------------------------------------------------------- /** * Simple string expression evaluator with variables. */ class OSGEARTH_EXPORT StringExpression { public: typedef std::pair Variable; typedef std::vector Variables; public: StringExpression(); StringExpression( const Config& conf ); /** Construct a new expression from the infix string. */ StringExpression( const std::string& expr ); /** Construct an expression from the infix string and a URI context. */ StringExpression( const std::string& expr, const URIContext& uriContext ); /** Copy ctor. */ StringExpression( const StringExpression& rhs ); /** dtor */ virtual ~StringExpression() { } /** Set the infix expr. */ void setInfix( const std::string& infix ); /** Set the infix expr to a literal string */ void setLiteral( const std::string& value ); /** Access the expression variables. */ const Variables& variables() const { return _vars; } /** Set the value of a variable. */ void set( const Variable& var, const std::string& value ); /** Set the value of a names variable if it exists */ void set( const std::string& varName, const std::string& value ); /** Evaluate the expression. */ const std::string& eval() const; /** Evaluate the expression as a URI. TODO: it would be better to have a whole new subclass URIExpression */ URI evalURI() const; /** Gets the expression string. */ const std::string& expr() const { return _src; } /** Whether the expression is empty */ bool empty() const { return _src.empty(); } void setURIContext( const URIContext& uriContext ) { _uriContext = uriContext; } const URIContext& uriContext() const { return _uriContext; } public: Config getConfig() const; void mergeConfig( const Config& conf ); private: enum Op { OPERAND, VARIABLE }; // in low-high precedence order typedef std::pair Atom; typedef std::vector AtomVector; std::string _src; AtomVector _infix; Variables _vars; std::string _value; bool _dirty; URIContext _uriContext; void init(); }; } // namespace osgEarth OSGEARTH_SPECIALIZE_CONFIG(osgEarth::NumericExpression); OSGEARTH_SPECIALIZE_CONFIG(osgEarth::StringExpression); #endif // OSGEARTHSYMBOLOGY_EXPRESSION_H