From: timoore Date: Wed, 15 Jul 2009 23:11:55 +0000 (+0000) Subject: Fixes for technique predicates X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=efec9070e178c9aef98332cb03d967868179ae4a;p=simgear.git Fixes for technique predicates Get tests based on properties and OpenGL extensions working. --- diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index 3969419d..dbfd286b 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -828,11 +828,13 @@ void buildTechnique(Effect* effect, const SGPropertyNode* prop, tniq->setAlwaysValid(true); } else { try { - expression::BindingLayout layout; + TechniquePredParser parser; + parser.setTechnique(tniq); + expression::BindingLayout& layout = parser.getBindingLayout(); int contextLoc = layout.addBinding("__contextId", expression::INT); SGExpressionb* validExp - = dynamic_cast(expression::read(predProp - ->getChild(0))); + = dynamic_cast(parser.read(predProp + ->getChild(0))); if (validExp) tniq->setValidExpression(validExp, layout); else diff --git a/simgear/scene/material/Technique.cxx b/simgear/scene/material/Technique.cxx index 19699607..c3f6b455 100644 --- a/simgear/scene/material/Technique.cxx +++ b/simgear/scene/material/Technique.cxx @@ -214,7 +214,11 @@ class GLVersionExpression : public SGExpression public: void eval(float& value, const expression::Binding*) const { +#ifdef TECHNIQUE_TEST_EXTENSIONS + value = 1.1; +#else value = getGLVersionNumber(); +#endif } }; @@ -250,8 +254,16 @@ Expression* extensionSupportedParser(const SGPropertyNode* exp, expression::Parser* parser) { if (exp->getType() == props::STRING - || exp->getType() == props::UNSPECIFIED) - return new ExtensionSupportedExpression(exp->getStringValue()); + || exp->getType() == props::UNSPECIFIED) { + ExtensionSupportedExpression* esp + = new ExtensionSupportedExpression(exp->getStringValue()); + int location = parser->getBindingLayout().addBinding("__contextId", + expression::INT); + VariableExpression* contextExp + = new VariableExpression(location); + esp->addOperand(contextExp); + return esp; + } throw expression::ParseError("extension-supported expression has wrong type"); } @@ -270,11 +282,6 @@ void Technique::setGLExtensionsPred(float glVersion, SGExpression* versionTest = makePredicate(new SGConstExpression(glVersion), new GLVersionExpression); -#if 0 - LessEqualExpression* versionTest - = new LessEqualExpression(new SGConstExpression(glVersion), - new GLVersionExpression); -#endif AndExpression* extensionsExp = 0; for (vector::const_iterator itr = extensions.begin(), e = extensions.end(); @@ -299,6 +306,16 @@ void Technique::setGLExtensionsPred(float glVersion, setValidExpression(predicate, layout); } +void Technique::refreshValidity() +{ + for (int i = 0; i < _contextMap.size(); ++i) { + ContextInfo& info = _contextMap[i]; + Status oldVal = info.valid(); + // What happens if we lose the race here? + info.valid.compareAndSwap(oldVal, UNKNOWN); + } +} + bool Technique_writeLocalData(const Object& obj, osgDB::Output& fw) { const Technique& tniq = static_cast(obj); diff --git a/simgear/scene/material/Technique.hxx b/simgear/scene/material/Technique.hxx index 9ada783c..596d4dd9 100644 --- a/simgear/scene/material/Technique.hxx +++ b/simgear/scene/material/Technique.hxx @@ -97,6 +97,7 @@ public: const simgear::expression::BindingLayout&); void setGLExtensionsPred(float glVersion, const std::vector& extensions); + void refreshValidity(); protected: // Validity of technique in a graphics context. struct ContextInfo : public osg::Referenced @@ -116,5 +117,17 @@ protected: SGSharedPtr _validExpression; int _contextIdLocation; }; + +class TechniquePredParser : public expression::ExpressionParser +{ +public: + void setTechnique(Technique* tniq) { _tniq = tniq; } + Technique* getTechnique() { return _tniq.get(); } +// void setEffect(Effect* effect) { _effect = effect; } +// Effect* getEffect() { return _effect.get(); } +protected: + osg::ref_ptr _tniq; + // osg::ref_ptr _effect; +}; } #endif diff --git a/simgear/structure/SGExpression.cxx b/simgear/structure/SGExpression.cxx index 4c746d88..fa665030 100644 --- a/simgear/structure/SGExpression.cxx +++ b/simgear/structure/SGExpression.cxx @@ -682,44 +682,6 @@ namespace simgear namespace expression { -class Parser { -public: - void addParser(const std::string& name, exp_parser parser) - { - _parserTable.insert(std::make_pair(name, parser)); - } - Expression* read(const SGPropertyNode* exp) - { - ParserMap::iterator itr = _parserTable.find(exp->getName()); - if (itr == _parserTable.end()) - throw ParseError(string("unknown expression ") + exp->getName()); - exp_parser parser = itr->second; - return (*parser)(exp, this); - } - // XXX vector of SGSharedPtr? - bool readChildren(const SGPropertyNode* exp, - vector& result); -protected: - typedef std::map ParserMap; - ParserMap _parserTable; -}; - -class ExpressionParser : public Parser, public Singleton -{ -}; - -void addExpParser(const string& token, exp_parser parsefn) -{ - ExpressionParser::instance()->addParser(token, parsefn); -} - -Expression* read(const SGPropertyNode* exp, Parser* parser) -{ - if (!parser) - parser = ExpressionParser::instance(); - return parser->read(exp); -} - bool Parser::readChildren(const SGPropertyNode* exp, vector& result) { @@ -728,6 +690,13 @@ bool Parser::readChildren(const SGPropertyNode* exp, return true; } +Parser::ParserMap ExpressionParser::_parserTable; + +void ExpressionParser::addExpParser(const string& token, exp_parser parsefn) +{ + _parserTable.insert(std::make_pair(token, parsefn)); +} + Expression* valueParser(const SGPropertyNode* exp, Parser* parser) { switch (exp->getType()) { @@ -867,10 +836,14 @@ Expression* logicopParser(const SGPropertyNode* exp, Parser* parser) ExpParserRegistrar andRegistrar("and", logicopParser); ExpParserRegistrar orRegistrar("or", logicopParser); - int BindingLayout::addBinding(const string& name, Type type) { //XXX error checkint + vector::iterator itr + = find_if(bindings.begin(), bindings.end(), + bind(&VariableBinding::name, _1) == name); + if (itr != bindings.end()) + return itr->location; int result = bindings.size(); bindings.push_back(VariableBinding(name, type, bindings.size())); return result; diff --git a/simgear/structure/SGExpression.hxx b/simgear/structure/SGExpression.hxx index 82dd8bbd..2dac8efb 100644 --- a/simgear/structure/SGExpression.hxx +++ b/simgear/structure/SGExpression.hxx @@ -901,96 +901,131 @@ namespace simgear { namespace expression { - class Parser; - /** - * Function that parses a property tree, producing an expression. - */ - typedef Expression* (*exp_parser)(const SGPropertyNode* exp, - Parser* parser); - void addExpParser(const std::string&, exp_parser); - Expression* read(const SGPropertyNode* exp, Parser* parser = 0); - /** - * Constructor for registering parser functions. - */ - struct ExpParserRegistrar - { - ExpParserRegistrar(const std::string& token, exp_parser parser) - { - addExpParser(token, parser); - } - }; - - struct ParseError : public sg_exception - { + struct ParseError : public sg_exception + { ParseError(const string& message = std::string()) - : sg_exception(message) {} - }; + : sg_exception(message) {} + }; - // Support for binding variables around an expression. - class Binding - { - public: + // Support for binding variables around an expression. + class Binding + { + public: virtual ~Binding() {} const virtual Value* getBindings() const = 0; virtual Value* getBindings() = 0; - }; + }; - class VariableLengthBinding : public Binding - { - public: + class VariableLengthBinding : public Binding + { + public: const Value* getBindings() const { - if (_bindings.empty()) - return 0; - else - return &_bindings[0]; + if (_bindings.empty()) + return 0; + else + return &_bindings[0]; } Value* getBindings() { - if (_bindings.empty()) - return 0; - else - return &_bindings[0]; + if (_bindings.empty()) + return 0; + else + return &_bindings[0]; } std::vector _bindings; - }; + }; - template class FixedLengthBinding : public Binding - { - public: + template class FixedLengthBinding : public Binding + { + public: Value* getBindings() { - return &_bindings[0]; + return &_bindings[0]; } const Value* getBindings() const { - return &_bindings[0]; + return &_bindings[0]; } Value _bindings[Size]; - }; + }; - struct VariableBinding - { + struct VariableBinding + { VariableBinding() : type(expression::DOUBLE), location(-1) {} VariableBinding(const std::string& name_, expression::Type type_, int location_) - : name(name_), type(type_), location(location_) + : name(name_), type(type_), location(location_) { } std::string name; expression::Type type; int location; - }; + }; - class BindingLayout - { - public: + class BindingLayout + { + public: int addBinding(const std::string& name, expression::Type type); bool findBinding(const string& name, VariableBinding& result) const; - protected: std::vector bindings; - }; + }; + + class Parser { + public: + typedef Expression* (*exp_parser)(const SGPropertyNode* exp, + Parser* parser); + void addParser(const std::string& name, exp_parser parser) + { + getParserMap().insert(std::make_pair(name, parser)); + } + Expression* read(const SGPropertyNode* exp) + { + ParserMap& map = getParserMap(); + ParserMap::iterator itr = map.find(exp->getName()); + if (itr == map.end()) + throw ParseError(string("unknown expression ") + exp->getName()); + exp_parser parser = itr->second; + return (*parser)(exp, this); + } + // XXX vector of SGSharedPtr? + bool readChildren(const SGPropertyNode* exp, + std::vector& result); + /** + * Function that parses a property tree, producing an expression. + */ + typedef std::map ParserMap; + virtual ParserMap& getParserMap() = 0; + /** + * After an expression is parsed, the binding layout may contain + * references that need to be bound during evaluation. + */ + BindingLayout& getBindingLayout() { return _bindingLayout; } + protected: + BindingLayout _bindingLayout; + }; + + class ExpressionParser : public Parser + { + public: + ParserMap& getParserMap() { return _parserTable; } + static void addExpParser(const std::string&, exp_parser); + protected: + static ParserMap _parserTable; + }; + + /** + * Constructor for registering parser functions. + */ + struct ExpParserRegistrar + { + ExpParserRegistrar(const std::string& token, Parser::exp_parser parser) + { + ExpressionParser::addExpParser(token, parser); + } + }; + } /**