]> git.mxchange.org Git - simgear.git/commitdiff
Fixes for technique predicates
authortimoore <timoore>
Wed, 15 Jul 2009 23:11:55 +0000 (23:11 +0000)
committerTim Moore <timoore@redhat.com>
Thu, 16 Jul 2009 10:09:44 +0000 (12:09 +0200)
Get tests based on properties and OpenGL extensions working.

simgear/scene/material/Effect.cxx
simgear/scene/material/Technique.cxx
simgear/scene/material/Technique.hxx
simgear/structure/SGExpression.cxx
simgear/structure/SGExpression.hxx

index 3969419dac8b87bb6188c493c5ae6dcd098a4198..dbfd286bf7aaf159a1e932da91aa37ff58f79aeb 100644 (file)
@@ -828,11 +828,13 @@ void buildTechnique(Effect* effect, const SGPropertyNode* prop,
         tniq->setAlwaysValid(true);
     } else {
         try {
         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
             int contextLoc = layout.addBinding("__contextId", expression::INT);
             SGExpressionb* validExp
-                = dynamic_cast<SGExpressionb*>(expression::read(predProp
-                                                                ->getChild(0)));
+                = dynamic_cast<SGExpressionb*>(parser.read(predProp
+                                                           ->getChild(0)));
             if (validExp)
                 tniq->setValidExpression(validExp, layout);
             else
             if (validExp)
                 tniq->setValidExpression(validExp, layout);
             else
index 19699607c9a4415df051e4ac97fd73afbd07abbe..c3f6b45505f5c4d77066c5a610611582fed8e6d7 100644 (file)
@@ -214,7 +214,11 @@ class GLVersionExpression : public SGExpression<float>
 public:
     void eval(float& value, const expression::Binding*) const
     {
 public:
     void eval(float& value, const expression::Binding*) const
     {
+#ifdef TECHNIQUE_TEST_EXTENSIONS
+        value = 1.1;
+#else
         value = getGLVersionNumber();
         value = getGLVersionNumber();
+#endif
     }
 };
 
     }
 };
 
@@ -250,8 +254,16 @@ Expression* extensionSupportedParser(const SGPropertyNode* exp,
                                      expression::Parser* parser)
 {
     if (exp->getType() == props::STRING
                                      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<int>* contextExp
+            = new VariableExpression<int>(location);
+        esp->addOperand(contextExp);
+        return esp;
+    }
     throw expression::ParseError("extension-supported expression has wrong type");
 }
 
     throw expression::ParseError("extension-supported expression has wrong type");
 }
 
@@ -270,11 +282,6 @@ void Technique::setGLExtensionsPred(float glVersion,
     SGExpression<bool>* versionTest
         = makePredicate<std::less_equal>(new SGConstExpression<float>(glVersion),
                         new GLVersionExpression);
     SGExpression<bool>* versionTest
         = makePredicate<std::less_equal>(new SGConstExpression<float>(glVersion),
                         new GLVersionExpression);
-#if 0
-    LessEqualExpression<float>* versionTest
-        = new LessEqualExpression<float>(new SGConstExpression<float>(glVersion),
-                                         new GLVersionExpression);
-#endif
     AndExpression* extensionsExp = 0;
     for (vector<string>::const_iterator itr = extensions.begin(),
              e = extensions.end();
     AndExpression* extensionsExp = 0;
     for (vector<string>::const_iterator itr = extensions.begin(),
              e = extensions.end();
@@ -299,6 +306,16 @@ void Technique::setGLExtensionsPred(float glVersion,
     setValidExpression(predicate, layout);
 }
 
     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<const Technique&>(obj);
 bool Technique_writeLocalData(const Object& obj, osgDB::Output& fw)
 {
     const Technique& tniq = static_cast<const Technique&>(obj);
index 9ada783c1192fa7cdcec6c5aa3a6fe4c33a41ae7..596d4dd9e8a0f96b3038fe45b76d7c108c545d17 100644 (file)
@@ -97,6 +97,7 @@ public:
                             const simgear::expression::BindingLayout&);
     void setGLExtensionsPred(float glVersion,
                              const std::vector<std::string>& extensions);
                             const simgear::expression::BindingLayout&);
     void setGLExtensionsPred(float glVersion,
                              const std::vector<std::string>& extensions);
+    void refreshValidity();
 protected:
     // Validity of technique in a graphics context.
     struct ContextInfo : public osg::Referenced
 protected:
     // Validity of technique in a graphics context.
     struct ContextInfo : public osg::Referenced
@@ -116,5 +117,17 @@ protected:
     SGSharedPtr<SGExpressionb> _validExpression;
     int _contextIdLocation;
 };
     SGSharedPtr<SGExpressionb> _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<Technique> _tniq;
+    // osg::ref_ptr<Effect> _effect;
+};
 }
 #endif
 }
 #endif
index 4c746d885d74a34e5314058ab1706c86c71b7004..fa6650300fce9a0bf55f395b91b805ae4f6eb01b 100644 (file)
@@ -682,44 +682,6 @@ namespace simgear
 namespace expression
 {
 
 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<Expression*>& result);
-protected:
-    typedef std::map<const std::string, exp_parser> ParserMap;
-    ParserMap _parserTable;
-};
-
-class ExpressionParser : public Parser, public Singleton<ExpressionParser>
-{
-};
-
-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<Expression*>& result)
 {
 bool Parser::readChildren(const SGPropertyNode* exp,
                           vector<Expression*>& result)
 {
@@ -728,6 +690,13 @@ bool Parser::readChildren(const SGPropertyNode* exp,
     return true;
 }
 
     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()) {
 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<AndExpression>);
 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
 
 ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
 
-
 int BindingLayout::addBinding(const string& name, Type type)
 {
     //XXX error checkint
 int BindingLayout::addBinding(const string& name, Type type)
 {
     //XXX error checkint
+    vector<VariableBinding>::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;
     int result = bindings.size();
     bindings.push_back(VariableBinding(name, type, bindings.size()));
     return result;
index 82dd8bbdc70138e67f49be47768e4cb005eab022..2dac8efb1863c105bfd78b045af4289180df6c06 100644 (file)
@@ -901,96 +901,131 @@ namespace simgear
 {
   namespace expression
   {
 {
   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())
       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;
       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
       {
       const Value* getBindings() const
       {
-        if (_bindings.empty())
-          return 0;
-        else
-          return &_bindings[0];
+          if (_bindings.empty())
+              return 0;
+          else
+              return &_bindings[0];
       }
       Value* getBindings()
       {
       }
       Value* getBindings()
       {
-        if (_bindings.empty())
-          return 0;
-        else
-          return &_bindings[0];
+          if (_bindings.empty())
+              return 0;
+          else
+              return &_bindings[0];
       }
       std::vector<Value> _bindings;
       }
       std::vector<Value> _bindings;
-    };
+  };
 
 
-    template<int Size> class FixedLengthBinding : public Binding
-    {
-    public:
+  template<int Size> class FixedLengthBinding : public Binding
+  {
+  public:
       Value* getBindings()
       {
       Value* getBindings()
       {
-        return &_bindings[0];
+          return &_bindings[0];
       }
       const Value* getBindings() const
       {
       }
       const Value* getBindings() const
       {
-        return &_bindings[0];
+          return &_bindings[0];
       }
       Value _bindings[Size];
       }
       Value _bindings[Size];
-    };
+  };
 
 
-    struct VariableBinding
-    {
+  struct VariableBinding
+  {
       VariableBinding() : type(expression::DOUBLE), location(-1) {}
 
       VariableBinding(const std::string& name_, expression::Type type_,
                       int location_)
       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;
       {
       }
       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;
       int addBinding(const std::string& name, expression::Type type);
       bool findBinding(const string& name, VariableBinding& result) const;
-    protected:
       std::vector<VariableBinding> bindings;
       std::vector<VariableBinding> 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<Expression*>& result);
+      /**
+       * Function that parses a property tree, producing an expression.
+       */
+      typedef std::map<const std::string, exp_parser> 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);
+      }
+  };
+
   }
 
   /**
   }
 
   /**