Added PathConstrainer and LinearConstrainer support to builder 45/38145/14
authorFerran Sole <ferran.sole@samsung.com>
Mon, 13 Apr 2015 15:02:37 +0000 (16:02 +0100)
committerFerran Sole <ferran.sole@samsung.com>
Thu, 14 May 2015 16:02:53 +0000 (17:02 +0100)
constrainers are defined like this

  "constrainers":
  {
    "constrainer0":
    {
      "type":"PathConstrainer",
      "points":[[100.0, 500.0, 0.0],[400.0, 500.0, 0.0]] ,
      "control-points":[[200.0, 100.0, 0.0],[300.0, 100.0, 0.0]],
      "forward":[1.0,0.0,0.0]
    },
    "constrainer1":
    {
      "type":"LinearConstrainer",
      "values":[0,400,200,0],
      "progress":[0.0,0.25,0.75,1.0]
    }
  }

And they can be applied or remove using signals like this:

  ...
  "signals":
  [
    {
      "name": "on-stage",
      "action": "applyConstraint",
      "constrainer": "constrainer0",
      "properties":
      [
        {
          "target":"targetActor",
          "targetProperty":"position",
          "source":"sourceActor",
          "sourceProperty":"position-y",
          "range":[-120.0,300.0]
        },
        {
          "target":"targetActor",
          "targetProperty":"orientation",
          "source":"sourceActor",
          "sourceProperty":"position-y",
          "range":[-120.0,300.0]
        }
      ]
    },

    ...
  {
    "name": "touched",
    "action": "removeConstraints",
    "constrainer": "constrainer0",
    "properties":
    [
      {
        "target":"targetActor"
      }
    ]
  }

Change-Id: I182c5ac2ad53f36fcb17bdcde6c47b9facf12bf0

dali-toolkit/internal/builder/builder-impl.cpp
dali-toolkit/internal/builder/builder-impl.h
dali-toolkit/internal/builder/builder-signals.cpp
dali-toolkit/public-api/builder/builder.cpp
dali-toolkit/public-api/builder/builder.h

index fd58ec3..b103bf3 100644 (file)
@@ -815,6 +815,212 @@ Path Builder::GetPath( const std::string& name )
   return ret;
 }
 
   return ret;
 }
 
+PathConstrainer Builder::GetPathConstrainer( const std::string& name )
+{
+  DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
+
+  //Search the pathConstrainer in the LUT
+  size_t count( mPathConstrainerLut.size() );
+  for( size_t i(0); i!=count; ++i )
+  {
+    if( mPathConstrainerLut[i].name == name )
+    {
+      //PathConstrainer has already been created
+      return mPathConstrainerLut[i].pathConstrainer;
+    }
+  }
+
+  //Create a new PathConstrainer
+  PathConstrainer ret;
+  if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") )
+  {
+    if( OptionalChild pathConstrainer = IsChild( *constrainers, name ) )
+    {
+      OptionalString constrainerType(IsString(IsChild(*pathConstrainer, "type")));
+      if(!constrainerType)
+      {
+        DALI_SCRIPT_WARNING("Constrainer type not specified for constrainer '%s'\n", name.c_str() );
+      }
+      else if( *constrainerType == "PathConstrainer")
+      {
+        //points property
+        if( OptionalChild pointsProperty = IsChild( *pathConstrainer, "points") )
+        {
+          Dali::Property::Value points(Property::ARRAY);
+          if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
+          {
+            ret = PathConstrainer::New();
+            ret.SetProperty( PathConstrainer::Property::POINTS, points);
+
+            //control-points property
+            if( OptionalChild pointsProperty = IsChild( *pathConstrainer, "control-points") )
+            {
+              Dali::Property::Value points(Property::ARRAY);
+              if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
+              {
+                ret.SetProperty( PathConstrainer::Property::CONTROL_POINTS, points);
+              }
+
+              //Forward vector
+              OptionalVector3 forward( IsVector3( IsChild(*pathConstrainer, "forward" ) ) );
+              if( forward )
+              {
+                ret.SetProperty( PathConstrainer::Property::FORWARD, *forward);
+              }
+
+              //Add the new constrainer to the vector of PathConstrainer
+              PathConstrainerEntry entry = {name,ret};
+              mPathConstrainerLut.push_back( entry );
+            }
+            else
+            {
+              //Control points not specified
+              DALI_SCRIPT_WARNING("Control points not specified for pathConstrainer '%s'\n", name.c_str() );
+            }
+          }
+        }
+        else
+        {
+          //Interpolation points not specified
+          DALI_SCRIPT_WARNING("Interpolation points not specified for pathConstrainer '%s'\n", name.c_str() );
+        }
+      }
+      else
+      {
+        DALI_SCRIPT_WARNING("Constrainer '%s' is not a PathConstrainer\n", name.c_str() );
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool Builder::IsPathConstrainer( const std::string& name )
+{
+  size_t count( mPathConstrainerLut.size() );
+  for( size_t i(0); i!=count; ++i )
+  {
+    if( mPathConstrainerLut[i].name == name )
+    {
+      return true;
+    }
+  }
+
+  if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") )
+  {
+    if( OptionalChild constrainer = IsChild( *constrainers, name ) )
+    {
+      OptionalString constrainerType(IsString(IsChild(*constrainer, "type")));
+      if(!constrainerType)
+      {
+        return false;
+      }
+      else
+      {
+         return *constrainerType == "PathConstrainer";
+      }
+    }
+  }
+  return false;
+}
+
+Dali::LinearConstrainer Builder::GetLinearConstrainer( const std::string& name )
+{
+  DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
+
+  //Search the LinearConstrainer in the LUT
+  size_t count( mLinearConstrainerLut.size() );
+  for( size_t i(0); i!=count; ++i )
+  {
+    if( mLinearConstrainerLut[i].name == name )
+    {
+      //LinearConstrainer has already been created
+      return mLinearConstrainerLut[i].linearConstrainer;
+    }
+  }
+
+  //Create a new LinearConstrainer
+  LinearConstrainer ret;
+  if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") )
+  {
+    if( OptionalChild linearConstrainer = IsChild( *constrainers, name ) )
+    {
+      OptionalString constrainerType(IsString(IsChild(*linearConstrainer, "type")));
+      if(!constrainerType)
+      {
+        DALI_SCRIPT_WARNING("Constrainer type not specified for constrainer '%s'\n", name.c_str() );
+      }
+      else if( *constrainerType == "LinearConstrainer")
+      {
+        //points property
+        if( OptionalChild pointsProperty = IsChild( *linearConstrainer, "value") )
+        {
+          Dali::Property::Value points(Property::ARRAY);
+          if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
+          {
+            ret = Dali::LinearConstrainer::New();
+            ret.SetProperty( LinearConstrainer::Property::VALUE, points);
+
+            //control-points property
+            if( OptionalChild pointsProperty = IsChild( *linearConstrainer, "progress") )
+            {
+              Dali::Property::Value points(Property::ARRAY);
+              if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
+              {
+                ret.SetProperty( LinearConstrainer::Property::PROGRESS, points);
+              }
+            }
+            //Add the new constrainer to vector of LinearConstrainer
+            LinearConstrainerEntry entry = {name,ret};
+            mLinearConstrainerLut.push_back( entry );
+          }
+        }
+        else
+        {
+          //Interpolation points not specified
+          DALI_SCRIPT_WARNING("Values not specified for LinearConstrainer '%s'\n", name.c_str() );
+        }
+      }
+      else
+      {
+        DALI_SCRIPT_WARNING("Constrainer '%s' is not a LinearConstrainer\n", name.c_str() );
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool Builder::IsLinearConstrainer( const std::string& name )
+{
+  //Search the LinearConstrainer in the LUT
+  size_t count( mLinearConstrainerLut.size() );
+  for( size_t i(0); i!=count; ++i )
+  {
+    if( mLinearConstrainerLut[i].name == name )
+    {
+      return true;
+    }
+  }
+
+  if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") )
+  {
+    if( OptionalChild constrainer = IsChild( *constrainers, name ) )
+    {
+      OptionalString constrainerType(IsString(IsChild(*constrainer, "type")));
+      if(!constrainerType)
+      {
+        return false;
+      }
+      else
+      {
+         return *constrainerType == "LinearConstrainer";
+      }
+    }
+  }
+  return false;
+}
+
 Toolkit::Builder::BuilderSignalType& Builder::QuitSignal()
 {
   return mQuitSignal;
 Toolkit::Builder::BuilderSignalType& Builder::QuitSignal()
 {
   return mQuitSignal;
index 4fb7aba..af1c85c 100644 (file)
@@ -186,6 +186,33 @@ public:
    * @copydoc Toolkit::Builder::GetPath
    */
   Path GetPath( const std::string &name );
    * @copydoc Toolkit::Builder::GetPath
    */
   Path GetPath( const std::string &name );
+
+  /**
+   * @copydoc Toolkit::Builder::GetPathConstrainer
+   */
+  Dali::PathConstrainer GetPathConstrainer( const std::string& name );
+
+  /*
+   * Check if a given constrainer is of type PathConstrainer
+   * @param[in] name The name of the constrainer
+   * @return True if constainer is of type PathConstrainer, False otherwise
+   *
+   */
+  bool IsPathConstrainer( const std::string& name );
+
+  /**
+   * @copydoc Toolkit::Builder::GetLinearConstrainer
+   */
+  Dali::LinearConstrainer GetLinearConstrainer( const std::string& name );
+
+  /*
+   * Check if a given constrainer is of type LinearConstrainer
+   * @param[in] name The name of the constrainer
+   * @return True if constainer is of type LinearConstrainer, False otherwise
+   *
+   */
+  bool IsLinearConstrainer( const std::string& name );
+
   /**
    * @copydoc Toolkit::Builder::QuitSignal
    */
   /**
    * @copydoc Toolkit::Builder::QuitSignal
    */
@@ -219,6 +246,14 @@ private:
   typedef std::map<const std::string, Path> PathLut;
   PathLut mPathLut;
 
   typedef std::map<const std::string, Path> PathLut;
   PathLut mPathLut;
 
+  typedef struct{ std::string name; Dali::PathConstrainer pathConstrainer; } PathConstrainerEntry;
+  typedef std::vector<PathConstrainerEntry> PathConstrainerLut;
+  PathConstrainerLut mPathConstrainerLut;
+
+  typedef struct{ std::string name; Dali::LinearConstrainer linearConstrainer; } LinearConstrainerEntry;
+  typedef std::vector<LinearConstrainerEntry> LinearConstrainerLut;
+  LinearConstrainerLut mLinearConstrainerLut;
+
   SlotDelegate<Builder> mSlotDelegate;
 
   Property::Map mReplacementMap;
   SlotDelegate<Builder> mSlotDelegate;
 
   Property::Map mReplacementMap;
index f832721..804deb3 100644 (file)
 // EXTERNAL INCLUDES
 #include <boost/function.hpp>
 #include <dali/public-api/actors/layer.h>
 // EXTERNAL INCLUDES
 #include <boost/function.hpp>
 #include <dali/public-api/actors/layer.h>
+#include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/object/type-info.h>
 #include <dali/public-api/object/property-notification.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/object/type-info.h>
 #include <dali/public-api/object/property-notification.h>
 #include <dali/integration-api/debug.h>
+#include <limits>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/builder/builder-impl.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/builder/builder-impl.h>
@@ -142,6 +144,182 @@ struct DelayedAnimationPlay
   };
 };
 
   };
 };
 
+// Delay a pathConstrainer apply
+struct DelayedConstrainerApply
+{
+  std::string     constrainerName;
+
+  std::vector<std::string> targetActorNames;
+  std::vector<std::string> sourceActorNames;
+  std::vector<std::string> targetPropertyNames;
+  std::vector<std::string> sourcePropertyNames;
+  std::vector<Vector2>  ranges;
+  std::vector<Vector2>  wrapRanges;
+
+  Dali::IntrusivePtr<Dali::Toolkit::Internal::Builder>  builder;
+
+  /*
+   * Helper function to get the parameters to apply each constraint
+   * @param[in] i i-essim element
+   * @param[out] tagetActor Target actor for the constraint
+   * @param[out] tagetPropertyIndex Target property index for the constraint
+   * @param[out] sourceActor Source actor for the constraint
+   * @param[out] sourcePropertyIndex Source property index for the constraint
+   */
+  bool GetApplyParameters( size_t i,
+                           Actor& targetActor, Property::Index& targetPropertyIndex,
+                           Actor& sourceActor, Property::Index& sourcePropertyIndex)
+  {
+
+    targetActor = Stage::GetCurrent().GetRootLayer().FindChildByName(targetActorNames[i]);
+    targetPropertyIndex = Property::INVALID_INDEX;
+    if(targetActor)
+    {
+      targetPropertyIndex = targetActor.GetPropertyIndex(targetPropertyNames[i]);
+      if( targetPropertyIndex ==  Property::INVALID_INDEX )
+      {
+        DALI_SCRIPT_WARNING("Property '%s' not founded in actor '%s'\n", targetPropertyNames[i].c_str(), targetActorNames[i].c_str() );
+        return false;
+      }
+    }
+    else
+    {
+      DALI_SCRIPT_WARNING("Actor '%s' not founded\n", targetActorNames[i].c_str() );
+      return false;
+    }
+
+
+    sourceActor = Stage::GetCurrent().GetRootLayer().FindChildByName(sourceActorNames[i]);
+    sourcePropertyIndex = Property::INVALID_INDEX;
+    if(sourceActor)
+    {
+      sourcePropertyIndex = sourceActor.GetPropertyIndex(sourcePropertyNames[i]);
+      if( sourcePropertyIndex ==  Property::INVALID_INDEX )
+      {
+        DALI_SCRIPT_WARNING("Property '%s' not founded in actor '%s'\n", sourcePropertyNames[i].c_str(), sourceActorNames[i].c_str() );
+        return false;
+      }
+    }
+    else
+    {
+      DALI_SCRIPT_WARNING("Actor '%s' not founded\n", targetActorNames[i].c_str() );
+      return false;
+    }
+    return true;
+  }
+
+  void operator()(void)
+  {
+    Actor sourceActor, targetActor;
+    Property::Index targetPropertyIndex(Property::INVALID_INDEX);
+    Property::Index sourcePropertyIndex(Property::INVALID_INDEX);
+    size_t actorCount( targetActorNames.size() );
+    if( builder.Get()->IsPathConstrainer( constrainerName ))
+    {
+      PathConstrainer constrainer = builder.Get()->GetPathConstrainer(constrainerName);
+      if( constrainer )
+      {
+        for(size_t i(0); i<actorCount; ++i )
+        {
+
+          if( GetApplyParameters( i, targetActor, targetPropertyIndex, sourceActor, sourcePropertyIndex ) )
+          {
+            constrainer.Apply( Property(targetActor,targetPropertyIndex),
+                               Property(sourceActor,sourcePropertyIndex),
+                               ranges[i],
+                               wrapRanges[i]);
+          }
+        }
+      }
+      else
+      {
+        DALI_SCRIPT_WARNING("Constrainer %s not found\n", constrainerName.c_str());
+      }
+    }
+    else if( builder.Get()->IsLinearConstrainer( constrainerName ) )
+    {
+      Dali::LinearConstrainer constrainer( builder.Get()->GetLinearConstrainer(constrainerName));
+      if( constrainer )
+      {
+        for(size_t i(0); i<actorCount; ++i )
+        {
+
+          if( GetApplyParameters( i, targetActor, targetPropertyIndex, sourceActor, sourcePropertyIndex ) )
+          {
+            constrainer.Apply( Property(targetActor,targetPropertyIndex),
+                               Property(sourceActor,sourcePropertyIndex),
+                               ranges[i],
+                               wrapRanges[i]);
+          }
+        }
+      }
+      else
+      {
+        DALI_SCRIPT_WARNING("Constrainer %s not found\n", constrainerName.c_str());
+      }
+    }
+    else
+    {
+      DALI_SCRIPT_WARNING("Constrainer %s is not of a valid type\n", constrainerName.c_str());
+    }
+  }
+};
+
+// Delay a pathConstrainer remove
+struct DelayedConstrainerRemove
+{
+  std::string     constrainerName;
+  std::vector<std::string> targetActorNames;
+  Dali::IntrusivePtr<Dali::Toolkit::Internal::Builder>  builder;
+
+  void operator()(void)
+  {
+    size_t actorCount( targetActorNames.size() );
+    if( builder.Get()->IsPathConstrainer( constrainerName ))
+    {
+      PathConstrainer constrainer = builder.Get()->GetPathConstrainer(constrainerName);
+      if( constrainer )
+      {
+        for(size_t i(0); i<actorCount; ++i )
+        {
+          Actor targetActor = Stage::GetCurrent().GetRootLayer().FindChildByName(targetActorNames[i]);
+          if(targetActor)
+          {
+            constrainer.Remove( targetActor );
+          }
+        }
+      }
+      else
+      {
+        DALI_SCRIPT_WARNING("Constrainer %s not found\n", constrainerName.c_str());
+      }
+    }
+    else if(builder.Get()->IsLinearConstrainer( constrainerName ))
+    {
+      LinearConstrainer constrainer = builder.Get()->GetLinearConstrainer(constrainerName);
+      if( constrainer )
+      {
+        for(size_t i(0); i<actorCount; ++i )
+        {
+          Actor targetActor = Stage::GetCurrent().GetRootLayer().FindChildByName(targetActorNames[i]);
+          if(targetActor)
+          {
+            constrainer.Remove( targetActor );
+          }
+        }
+      }
+      else
+      {
+        DALI_SCRIPT_WARNING("Constrainer %s not found\n", constrainerName.c_str());
+      }
+    }
+    else
+    {
+      DALI_SCRIPT_WARNING("Constrainer %s is not of a valid type\n", constrainerName.c_str());
+    }
+  }
+};
+
 /*
  * Gets Property::Value from child
  */
 /*
  * Gets Property::Value from child
  */
@@ -298,6 +476,115 @@ boost::function<void (void)> GetAction(const TreeNode &root, const TreeNode &chi
       DALI_SCRIPT_WARNING("Cannot find animations section\n");
     }
   }
       DALI_SCRIPT_WARNING("Cannot find animations section\n");
     }
   }
+  else if("applyConstraint" == *actionName )
+  {
+    OptionalString constrainerName = IsString( IsChild(child, "constrainer") );
+    if( !constrainerName )
+    {
+      DALI_SCRIPT_WARNING("Need to specify a constrainer\n");
+    }
+    else
+    {
+      DelayedConstrainerApply action;
+      action.constrainerName = *constrainerName;
+      action.builder = builder;
+      OptionalChild propertiesNode = IsChild(child, "properties");
+      if(propertiesNode)
+      {
+        const TreeNode::ConstIterator endIter = (*propertiesNode).CEnd();
+        for( TreeNode::ConstIterator iter = (*propertiesNode).CBegin(); endIter != iter; ++iter )
+        {
+          const TreeNode::KeyNodePair& pKeyChild = *iter;
+          OptionalString sourceActorName(IsString(IsChild(pKeyChild.second, "source")));
+          if(!sourceActorName)
+          {
+            DALI_SCRIPT_WARNING("Need to specify source actor to apply the constraint\n");
+            continue;
+          }
+          OptionalString sourcePropertyName( IsString( IsChild(pKeyChild.second, "sourceProperty" ) ) );
+          if(!sourcePropertyName)
+          {
+            DALI_SCRIPT_WARNING("Need to specify source property to apply the constraint\n");
+            continue;
+          }
+
+          OptionalString targetActorName(IsString(IsChild(pKeyChild.second, "target")));
+          if(!targetActorName)
+          {
+            DALI_SCRIPT_WARNING("Need to specify target actor to apply the constraint\n");
+            continue;
+          }
+
+          OptionalString targetPropertyName( IsString( IsChild(pKeyChild.second, "targetProperty" ) ) );
+          if(!targetPropertyName)
+          {
+            DALI_SCRIPT_WARNING("Need to specify target property name to apply the constraint\n");
+            continue;
+          }
+
+          OptionalVector2 range(IsVector2(IsChild(pKeyChild.second, "range")));
+          if(!range)
+          {
+            DALI_SCRIPT_WARNING("Constrainer range not specified\n");
+            continue;
+          }
+
+          Vector2 wrap(-std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
+          OptionalVector2 wrapRange(IsVector2(IsChild(pKeyChild.second, "wrap")));
+          if(wrapRange)
+          {
+            wrap = *wrapRange;
+          }
+
+          action.sourceActorNames.push_back(*sourceActorName);
+          action.sourcePropertyNames.push_back(*sourcePropertyName);
+          action.targetActorNames.push_back(*targetActorName);
+          action.targetPropertyNames.push_back(*targetPropertyName);
+          action.ranges.push_back(*range);
+          action.wrapRanges.push_back(wrap);
+        }
+
+        callback = action;
+      }
+    }
+
+
+  }
+  else if("removeConstraints" == *actionName )
+  {
+    OptionalString constrainerName = IsString( IsChild(child, "constrainer") );
+    if( !constrainerName )
+    {
+      DALI_SCRIPT_WARNING("Need to specify a constrainer\n");
+    }
+    else
+    {
+
+      DelayedConstrainerRemove action;
+      action.constrainerName = *constrainerName;
+      action.builder = builder;
+      OptionalChild propertiesNode = IsChild(child, "properties");
+      if(propertiesNode)
+      {
+        const TreeNode::ConstIterator endIter = (*propertiesNode).CEnd();
+        for( TreeNode::ConstIterator iter = (*propertiesNode).CBegin(); endIter != iter; ++iter )
+        {
+          const TreeNode::KeyNodePair& pKeyChild = *iter;
+          OptionalString targetActorName(IsString(IsChild(pKeyChild.second, "target")));
+          if(targetActorName)
+          {
+            action.targetActorNames.push_back(*targetActorName);
+          }
+          else
+          {
+            DALI_SCRIPT_WARNING("Need to specify target actor to remove the constraint\n");
+            continue;
+          }
+        }
+      }
+      callback = action;
+    }
+  }
   else
   {
     // no named actor; presume self
   else
   {
     // no named actor; presume self
index 3ab0ba8..f89b622 100644 (file)
@@ -149,6 +149,16 @@ Path Builder::GetPath( const std::string &name )
   return GetImpl(*this).GetPath( name );
 }
 
   return GetImpl(*this).GetPath( name );
 }
 
+PathConstrainer Builder::GetPathConstrainer( const std::string& pathConstrainerName )
+{
+  return GetImpl(*this).GetPathConstrainer( pathConstrainerName );
+}
+
+LinearConstrainer Builder::GetLinearConstrainer( const std::string& linearConstrainerName )
+{
+  return GetImpl(*this).GetLinearConstrainer( linearConstrainerName );
+}
+
 Builder::BuilderSignalType& Builder::QuitSignal()
 {
   return GetImpl( *this ).QuitSignal();
 Builder::BuilderSignalType& Builder::QuitSignal()
 {
   return GetImpl( *this ).QuitSignal();
index a975014..51dd743 100644 (file)
@@ -21,6 +21,8 @@
 // EXTERNAL INCLUDES
 #include <dali/public-api/actors/actor.h>
 #include <dali/public-api/animation/animation.h>
 // EXTERNAL INCLUDES
 #include <dali/public-api/actors/actor.h>
 #include <dali/public-api/animation/animation.h>
+#include <dali/public-api/animation/linear-constrainer.h>
+#include <dali/public-api/animation/path-constrainer.h>
 #include <dali/public-api/images/frame-buffer-image.h>
 #include <dali/public-api/shader-effects/shader-effect.h>
 
 #include <dali/public-api/images/frame-buffer-image.h>
 #include <dali/public-api/shader-effects/shader-effect.h>
 
@@ -408,6 +410,30 @@ class DALI_IMPORT_API Builder : public BaseHandle
    */
   Path GetPath( const std::string &name );
 
    */
   Path GetPath( const std::string &name );
 
+  /**
+   * Get or create a PathConstrainer from the set of known PathConstrainers
+   * e.g.
+   *   PathConstrainer a = builder.GetPathConstrainer( "my-path-constrainer");
+   *
+   * @pre The Builder has been initialized.
+   * @pre The pathConstrainerName exists in the Constrainers section of the data representation
+   * @param pathConstrainerName The name of the PathConstrainer
+   * @returns A handle to a PathConstrainer if found, otherwise empty
+   */
+  PathConstrainer GetPathConstrainer( const std::string& pathConstrainerName );
+
+  /**
+   * Get or create a LinearConstrainer from the set of known LinearConstrainers
+   * e.g.
+   *   LinearConstrainer a = builder.GetLinearConstrainer( "my-linear-constrainer");
+   *
+   * @pre The Builder has been initialized.
+   * @pre The linearConstrainerName exists in the Constrainers section of the data representation
+   * @param linearConstrainerName The name of the LinearConstrainer
+   * @returns A handle to a LinearConstrainer if found, otherwise empty
+   */
+  LinearConstrainer GetLinearConstrainer( const std::string& linearConstrainerName );
+
   // Signals
 
   /**
   // Signals
 
   /**