Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / constraint-impl.h
index 0fc820d..1fdb68e 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_ACTIVE_CONSTRAINT_H__
-#define __DALI_INTERNAL_ACTIVE_CONSTRAINT_H__
+#ifndef DALI_INTERNAL_ACTIVE_CONSTRAINT_H
+#define DALI_INTERNAL_ACTIVE_CONSTRAINT_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 // INTERNAL INCLUDES
 #include <dali/internal/common/message.h>
-#include <dali/internal/event/common/event-thread-services.h>
-#include <dali/internal/event/common/object-impl.h>
-#include <dali/internal/event/common/thread-local-storage.h>
-#include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/animation/constraint-base.h>
 #include <dali/internal/event/animation/constraint-source-impl.h>
 #include <dali/internal/event/animation/property-constraint-ptr.h>
+#include <dali/internal/event/common/event-thread-services.h>
+#include <dali/internal/event/common/object-impl.h>
+#include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/event/common/thread-local-storage.h>
+#include <dali/internal/update/animation/property-accessor.h>
+#include <dali/internal/update/animation/property-component-accessor.h>
+#include <dali/internal/update/animation/scene-graph-constraint.h>
 #include <dali/internal/update/common/animatable-property.h>
-#include <dali/internal/update/common/property-owner.h>
 #include <dali/internal/update/common/property-owner-messages.h>
+#include <dali/internal/update/common/property-owner.h>
 #include <dali/internal/update/common/property-resetter.h>
-#include <dali/internal/update/animation/scene-graph-constraint.h>
-#include <dali/internal/update/animation/property-accessor.h>
-#include <dali/internal/update/animation/property-component-accessor.h>
 #include <memory>
 
 namespace Dali
 {
-
 namespace Internal
 {
-
-/**
- * Helper to add only unique entries to the propertyOwner container
- * @param propertyOwners to add the entries to
- * @param object to add
- */
-inline void AddUnique( SceneGraph::PropertyOwnerContainer& propertyOwners, SceneGraph::PropertyOwner* object )
-{
-  const SceneGraph::PropertyOwnerIter iter = std::find( propertyOwners.Begin(), propertyOwners.End(), object );
-  if( iter == propertyOwners.End() )
-  {
-    // each owner should only be added once
-    propertyOwners.PushBack( object );
-  }
-}
-
 /**
  * Connects a constraint which takes another property as an input.
  */
-template < typename PropertyType >
+template<typename PropertyType>
 class Constraint : public ConstraintBase
 {
 public:
-
-  typedef SceneGraph::Constraint< PropertyType, PropertyAccessor<PropertyType> > SceneGraphConstraint;
-  typedef const SceneGraph::AnimatableProperty<PropertyType>* ScenePropertyPtr;
-  typedef typename PropertyConstraintPtr<PropertyType>::Type ConstraintFunctionPtr;
-  typedef const SceneGraph::TransformManagerPropertyHandler<PropertyType> TransformManagerProperty;
+  using ConstraintFunctionPtr = typename PropertyConstraintPtr<PropertyType>::Type;
 
   /**
    * Construct a new constraint.
@@ -78,128 +57,108 @@ public:
    * @param[in] func The constraint function.
    * @return A newly allocated active-constraint.
    */
-  static ConstraintBase* New( Object& object,
-                              Property::Index targetIndex,
-                              SourceContainer& sources,
-                              ConstraintFunctionPtr func )
+  static ConstraintBase* New(Object&               object,
+                             Property::Index       targetIndex,
+                             SourceContainer&      sources,
+                             ConstraintFunctionPtr func)
   {
-    return new Constraint< PropertyType >( object, targetIndex, sources, func );
+    return new Constraint(object, targetIndex, sources, func);
   }
 
   /**
-   * @copydoc ConstraintBase::Clone()
+   * Virtual destructor.
    */
-  virtual ConstraintBase* Clone( Object& object )
+  ~Constraint() override
   {
-    DALI_ASSERT_ALWAYS( !mSourceDestroyed && "An input source object has been destroyed" );
-
-    ConstraintBase* clone( NULL );
-
-    ConstraintFunctionPtr funcPtr( mUserFunction->Clone() );
-
-    clone = new Constraint< PropertyType >( object,
-                                            mTargetIndex,
-                                            mSources,
-                                            funcPtr );
-
-    clone->SetRemoveAction(mRemoveAction);
-    clone->SetTag( mTag );
-
-    return clone;
+    // This is not responsible for removing constraints.
   }
 
-
+private:
   /**
-   * Virtual destructor.
+   * @copydoc ConstraintBase::DoClone()
    */
-  virtual ~Constraint()
+  ConstraintBase* DoClone(Object& object) final
   {
-    // This is not responsible for removing constraints.
+    ConstraintFunctionPtr funcPtr(mUserFunction->Clone());
+    return new Constraint(object,
+                          mTargetPropertyIndex,
+                          mSources,
+                          funcPtr);
   }
 
-private:
-
   /**
    * Private constructor; see also Constraint::New().
    */
-  Constraint( Object& object,
-              Property::Index targetIndex,
-              SourceContainer& sources,
-              ConstraintFunctionPtr& func )
-  : ConstraintBase( object, targetIndex, sources ),
-    mTargetIndex( targetIndex ),
-    mUserFunction( func )
+  Constraint(Object&                object,
+             Property::Index        targetIndex,
+             SourceContainer&       sources,
+             ConstraintFunctionPtr& func)
+  : ConstraintBase(object, targetIndex, sources),
+    mUserFunction(func)
   {
   }
 
   // Undefined
-  Constraint( const Constraint& );
-
-  // Undefined
-  Constraint& operator=( const Constraint& rhs );
+  Constraint()                  = delete;
+  Constraint(const Constraint&) = delete;
+  Constraint& operator=(const Constraint& rhs) = delete;
 
   /**
-   * Create and connect a constraint and property resetter for a scene-graph property
+   * @copydoc ConstraintBase::ConnectConstraint()
    */
-  void ConnectConstraint()
+  void ConnectConstraint(bool isPreConstraint) final
   {
     // Should not come here if target object has been destroyed
-    DALI_ASSERT_DEBUG( NULL != mTargetObject );
+    DALI_ASSERT_DEBUG(nullptr != mTargetObject);
 
     // Guard against double connections
-    DALI_ASSERT_DEBUG( NULL == mSceneGraphConstraint );
+    DALI_ASSERT_DEBUG(nullptr == mSceneGraphConstraint);
 
-    // Short-circuit until the target scene-object exists
-    SceneGraph::PropertyOwner* targetObject = const_cast< SceneGraph::PropertyOwner* >( mTargetObject->GetSceneObject() );
-    if ( NULL == targetObject )
-    {
-      return;
-    }
+    SceneGraph::PropertyOwner& targetObject = const_cast<SceneGraph::PropertyOwner&>(mTargetObject->GetSceneObject());
 
     // Build a container of property-owners, providing the scene-graph properties
     SceneGraph::PropertyOwnerContainer propertyOwners;
-    propertyOwners.PushBack( targetObject );
+    propertyOwners.PushBack(&targetObject);
 
     // Build the constraint function; this requires a scene-graph property from each source
-    ConstraintFunctionPtr func( ConnectConstraintFunction( propertyOwners ) );
+    ConstraintFunctionPtr func(ConnectConstraintFunction(propertyOwners));
 
-    if ( func )
+    if(func)
     {
-      // Create the SceneGraphConstraint and PropertyResetter, and connect them to the scene-graph
-
-      const SceneGraph::PropertyBase* targetProperty = mTargetObject->GetSceneObjectAnimatableProperty( mTargetIndex );
       OwnerPointer<SceneGraph::PropertyResetterBase> resetter;
-
-      // The targetProperty should exist, when targetObject exists
-      DALI_ASSERT_ALWAYS( NULL != targetProperty && "Constraint target property does not exist" );
-
-      if( targetProperty->IsTransformManagerProperty() )  //It is a property managed by the transform manager
+      // Create the SceneGraphConstraint and PropertyResetter, and connect them to the scene-graph
+      const SceneGraph::PropertyBase* targetProperty = mTargetObject->GetSceneObjectAnimatableProperty(mTargetPropertyIndex);
+      DALI_ASSERT_ALWAYS(targetProperty && "Constraint target property does not exist");
+      if(targetProperty->IsTransformManagerProperty()) //It is a property managed by the transform manager
       {
         // Connect the constraint
-        mSceneGraphConstraint =
-          SceneGraph::Constraint<PropertyType, TransformManagerPropertyAccessor<PropertyType> >::New( *targetProperty,
-                                                                                                      propertyOwners,
-                                                                                                      func,
-                                                                                                      mRemoveAction );
+        mSceneGraphConstraint = SceneGraph::Constraint<PropertyType, TransformManagerPropertyAccessor<PropertyType> >::New(*targetProperty,
+                                                                                                                           propertyOwners,
+                                                                                                                           func,
+                                                                                                                           mRemoveAction);
         // Don't create a resetter for transform manager property, it's less efficient
       }
-      else  //SceneGraph property
+      else //SceneGraph property
       {
         // Connect the constraint
-        mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty,
-                                                           propertyOwners,
-                                                           func,
-                                                           mRemoveAction );
-        // Connect the resetter
-        resetter = SceneGraph::ConstraintResetter::New( *targetObject, *targetProperty, *mSceneGraphConstraint );
-
+        mSceneGraphConstraint = SceneGraph::Constraint<PropertyType, PropertyAccessor<PropertyType> >::New(*targetProperty,
+                                                                                                           propertyOwners,
+                                                                                                           func,
+                                                                                                           mRemoveAction);
+        resetter              = SceneGraph::ConstraintResetter::New(targetObject, *targetProperty, *mSceneGraphConstraint);
       }
-      OwnerPointer< SceneGraph::ConstraintBase > transferOwnership( const_cast< SceneGraph::ConstraintBase* >( mSceneGraphConstraint ) );
-      ApplyConstraintMessage( GetEventThreadServices(), *targetObject, transferOwnership );
-
-      if( resetter != nullptr )
+      OwnerPointer<SceneGraph::ConstraintBase> transferOwnership(const_cast<SceneGraph::ConstraintBase*>(mSceneGraphConstraint));
+      if(isPreConstraint)
+      {
+        ApplyConstraintMessage(GetEventThreadServices(), targetObject, transferOwnership);
+      }
+      else
       {
-        AddResetterMessage( GetEventThreadServices().GetUpdateManager(), resetter );
+        ApplyPostConstraintMessage(GetEventThreadServices(), targetObject, transferOwnership);
+      }
+      if(resetter)
+      {
+        AddResetterMessage(GetEventThreadServices().GetUpdateManager(), resetter);
       }
     }
   }
@@ -208,103 +167,44 @@ private:
    * Helper for ConnectConstraint. Creates a connected constraint-function.
    * Also populates the property-owner container, for each input connected to the constraint-function.
    * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
-   * @return A connected constraint-function, or NULL if the scene-graph properties are not available.
+   * @return A connected constraint-function, or nullptr if the scene-graph properties are not available.
    */
-  PropertyConstraint<PropertyType>* ConnectConstraintFunction( SceneGraph::PropertyOwnerContainer& propertyOwners )
+  PropertyConstraint<PropertyType>* ConnectConstraintFunction(SceneGraph::PropertyOwnerContainer& propertyOwners)
   {
     PropertyConstraint<PropertyType>* func = mUserFunction->Clone();
 
-    for ( SourceIter iter = mSources.begin(); mSources.end() != iter; ++iter )
+    for(auto&& source : mSources)
     {
-      Source& source = *iter;
-
-      PropertyInputImpl* inputProperty( NULL );
-      int componentIndex( Property::INVALID_COMPONENT_INDEX );
-
-      if ( OBJECT_PROPERTY == source.sourceType )
-      {
-        DALI_ASSERT_ALWAYS( source.object->IsPropertyAConstraintInput( source.propertyIndex ) );
-
-        SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( source.object->GetSceneObject() );
-
-        // The property owner will not exist, if the target object is off-stage
-        if( NULL != owner )
-        {
-          AddUnique( propertyOwners, owner );
-          inputProperty = const_cast< PropertyInputImpl* >( source.object->GetSceneObjectInputProperty( source.propertyIndex ) );
-          componentIndex = source.object->GetPropertyComponentIndex( source.propertyIndex );
-
-          // The scene-object property should exist, when the property owner exists
-          DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
-        }
-      }
-      else if ( LOCAL_PROPERTY == source.sourceType )
-      {
-        DALI_ASSERT_ALWAYS( mTargetObject->IsPropertyAConstraintInput( source.propertyIndex ) );
-
-        inputProperty = const_cast< PropertyInputImpl* >( mTargetObject->GetSceneObjectInputProperty( source.propertyIndex ) );
-        componentIndex = mTargetObject->GetPropertyComponentIndex( source.propertyIndex );
+      int32_t            componentIndex = Property::INVALID_COMPONENT_INDEX;
+      PropertyInputImpl* inputProperty  = AddInputProperty(source, propertyOwners, componentIndex);
 
-        // The target scene-object should provide this property
-        DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
-      }
-      else
-      {
-        DALI_ASSERT_ALWAYS( PARENT_PROPERTY == source.sourceType && "Constraint source property type is invalid" );
-
-        Object* objectParent = dynamic_cast< Actor& >( *mTargetObject ).GetParent();
-
-        // This will not exist, if the target object is off-stage
-        if ( NULL != objectParent )
-        {
-          DALI_ASSERT_ALWAYS( objectParent->IsPropertyAConstraintInput( source.propertyIndex ) );
-
-          SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( objectParent->GetSceneObject() );
-
-          // The property owner will not exist, if the parent object is off-stage
-          if ( NULL != owner )
-          {
-            AddUnique( propertyOwners, owner );
-            inputProperty = const_cast< PropertyInputImpl* >( objectParent->GetSceneObjectInputProperty( source.propertyIndex ) );
-            componentIndex = objectParent->GetPropertyComponentIndex( source.propertyIndex );
-
-            // The scene-object property should exist, when the property owner exists
-            DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
-          }
-        }
-      }
-
-      if ( NULL == inputProperty )
+      if(nullptr == inputProperty)
       {
         delete func;
-        func = NULL;
+        func = nullptr;
 
         // Exit if a scene-graph object is not available from one of the sources
         break;
       }
 
-      func->SetInput( ( iter - mSources.begin() ), componentIndex, *inputProperty );
+      func->AddInput(inputProperty, componentIndex);
     }
 
     return func;
   }
 
 protected:
-
-  Property::Index mTargetIndex;
-
   ConstraintFunctionPtr mUserFunction;
 };
 
 /**
- * Variant which allows float components to be animated individually.
+ * Variant which allows float components to be constrained individually.
  */
-template <>
+template<>
 class Constraint<float> : public ConstraintBase
 {
 public:
-
-  typedef typename PropertyConstraintPtr<float>::Type ConstraintFunctionPtr;
+  using ConstraintFunctionPtr = typename PropertyConstraintPtr<float>::Type;
 
   /**
    * Construct a new constraint.
@@ -314,221 +214,108 @@ public:
    * @param[in] func The constraint function.
    * @return A newly allocated constraint.
    */
-  static ConstraintBase* New( Object& object,
-                              Property::Index targetIndex,
-                              SourceContainer& sources,
-                              ConstraintFunctionPtr func )
+  static ConstraintBase* New(Object&               object,
+                             Property::Index       targetIndex,
+                             SourceContainer&      sources,
+                             ConstraintFunctionPtr func)
   {
-    return new Constraint< float >( object, targetIndex, sources, func );
+    return new Constraint(object, targetIndex, sources, func);
   }
 
   /**
-   * @copydoc ConstraintBase::Clone()
+   * Virtual destructor.
    */
-  virtual ConstraintBase* Clone( Object& object )
+  ~Constraint() override
   {
-    DALI_ASSERT_ALWAYS( !mSourceDestroyed && "An input source object has been destroyed" );
-
-    ConstraintBase* clone( NULL );
-
-    ConstraintFunctionPtr funcPtr( mUserFunction->Clone() );
-
-    clone = new Constraint< float >( object,
-                                     mTargetIndex,
-                                     mSources,
-                                     funcPtr );
-
-    clone->SetRemoveAction(mRemoveAction);
-    clone->SetTag( mTag );
-
-    return clone;
+    // This is not responsible for removing constraints.
   }
 
+private:
   /**
-   * Virtual destructor.
+   * @copydoc ConstraintBase::DoClone()
    */
-  virtual ~Constraint()
+  ConstraintBase* DoClone(Object& object) final
   {
-    // This is not responsible for removing constraints.
+    ConstraintFunctionPtr funcPtr(mUserFunction->Clone());
+    return new Constraint(object,
+                          mTargetPropertyIndex,
+                          mSources,
+                          funcPtr);
   }
 
-private:
-
   /**
    * Private constructor; see also Constraint::New().
    */
-  Constraint( Object& object,
-              Property::Index targetIndex,
-              SourceContainer& sources,
-              ConstraintFunctionPtr& func )
-  : ConstraintBase( object, targetIndex, sources ),
-    mTargetIndex( targetIndex ),
-    mUserFunction( func )
+  Constraint(Object&                object,
+             Property::Index        targetIndex,
+             SourceContainer&       sources,
+             ConstraintFunctionPtr& func)
+  : ConstraintBase(object, targetIndex, sources),
+    mUserFunction(func)
   {
   }
 
   // Undefined
-  Constraint( const Constraint& );
-
-  // Undefined
-  Constraint& operator=( const Constraint& rhs );
+  Constraint()                  = delete;
+  Constraint(const Constraint&) = delete;
+  Constraint& operator=(const Constraint& rhs) = delete;
 
   /**
-   * Create and connect a constraint for a scene-object.
+   * @copydoc ConstraintBase::ConnectConstraint()
    */
-  void ConnectConstraint()
+  void ConnectConstraint(bool isPreConstraint) final
   {
-    // Should not come here if target-object has been destroyed
-    DALI_ASSERT_DEBUG( NULL != mTargetObject );
-
+    // Should not come here if target object has been destroyed
+    DALI_ASSERT_DEBUG(nullptr != mTargetObject);
     // Guard against double connections
-    DALI_ASSERT_DEBUG( NULL == mSceneGraphConstraint );
+    DALI_ASSERT_DEBUG(nullptr == mSceneGraphConstraint);
 
-    // Short-circuit until the target scene-object exists
-    SceneGraph::PropertyOwner* targetObject = const_cast< SceneGraph::PropertyOwner* >( mTargetObject->GetSceneObject() );
-    if ( NULL == targetObject )
-    {
-      return;
-    }
+    SceneGraph::PropertyOwner& targetObject = const_cast<SceneGraph::PropertyOwner&>(mTargetObject->GetSceneObject());
 
     // Build a container of property-owners, providing the scene-graph properties
     SceneGraph::PropertyOwnerContainer propertyOwners;
-    propertyOwners.PushBack( targetObject );
+    propertyOwners.PushBack(&targetObject);
 
     // Build the constraint function; this requires a scene-graph property from each source
-    ConstraintFunctionPtr func( ConnectConstraintFunction( propertyOwners ) );
+    ConstraintFunctionPtr func(ConnectConstraintFunction(propertyOwners));
 
-    if ( func )
+    if(func)
     {
       // Create the SceneGraphConstraint, and connect to the scene-graph
-
-      const SceneGraph::PropertyBase* targetProperty = mTargetObject->GetSceneObjectAnimatableProperty( mTargetIndex );
-      OwnerPointer<SceneGraph::PropertyResetterBase> resetter;
-
+      bool                            resetterRequired = false;
+      const SceneGraph::PropertyBase* targetProperty   = mTargetObject->GetSceneObjectAnimatableProperty(mTargetPropertyIndex);
       // The targetProperty should exist, when targetObject exists
-      DALI_ASSERT_ALWAYS( NULL != targetProperty && "Constraint target property does not exist" );
-
-      const int componentIndex = mTargetObject->GetPropertyComponentIndex( mTargetIndex );
-
-      if ( Property::INVALID_COMPONENT_INDEX == componentIndex )
+      DALI_ASSERT_ALWAYS(nullptr != targetProperty && "Constraint target property does not exist");
+      const int32_t componentIndex = mTargetObject->GetPropertyComponentIndex(mTargetPropertyIndex);
+      if(Property::INVALID_COMPONENT_INDEX == componentIndex)
       {
         // Not a Vector2, Vector3 or Vector4 component, expecting float type
-        DALI_ASSERT_DEBUG( PropertyTypes::Get< float >() == targetProperty->GetType() );
-
-        typedef SceneGraph::Constraint< float, PropertyAccessor<float> > SceneGraphConstraint;
+        DALI_ASSERT_DEBUG(PropertyTypes::Get<float>() == targetProperty->GetType());
 
-        mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-        resetter = SceneGraph::ConstraintResetter::New( *targetObject, *targetProperty, *mSceneGraphConstraint );
+        mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyAccessor<float> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
+        resetterRequired      = true;
       }
       else
       {
-        // Expecting Vector2, Vector3 or Vector4 type
-
-        if ( PropertyTypes::Get< Vector2 >() == targetProperty->GetType() )
+        CreateComponentConstraint(targetProperty, componentIndex, propertyOwners, func, resetterRequired);
+      }
+      if(mSceneGraphConstraint)
+      {
+        OwnerPointer<SceneGraph::ConstraintBase> transferOwnership(const_cast<SceneGraph::ConstraintBase*>(mSceneGraphConstraint));
+        if(isPreConstraint)
         {
-          // Constrain float component of Vector2 property
-
-          if ( 0 == componentIndex )
-          {
-            typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector2> > SceneGraphConstraint;
-            mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-          }
-          else if ( 1 == componentIndex )
-          {
-            typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector2> > SceneGraphConstraint;
-            mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-          }
-          if( mSceneGraphConstraint )
-          {
-            resetter = SceneGraph::ConstraintResetter::New( *targetObject, *targetProperty, *mSceneGraphConstraint );
-          }
+          ApplyConstraintMessage(GetEventThreadServices(), targetObject, transferOwnership);
         }
-        else if ( PropertyTypes::Get< Vector3 >() == targetProperty->GetType() )
+        else
         {
-          // Constrain float component of Vector3 property
-          if( targetProperty->IsTransformManagerProperty() )
-          {
-            if ( 0 == componentIndex )
-            {
-              typedef SceneGraph::Constraint< float, TransformManagerPropertyComponentAccessor<Vector3,0> > SceneGraphConstraint;
-              mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-            }
-            else if ( 1 == componentIndex )
-            {
-              typedef SceneGraph::Constraint< float, TransformManagerPropertyComponentAccessor<Vector3,1> > SceneGraphConstraint;
-              mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-            }
-            else if ( 2 == componentIndex )
-            {
-              typedef SceneGraph::Constraint< float, TransformManagerPropertyComponentAccessor<Vector3,2> > SceneGraphConstraint;
-              mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-            }
-            // Do not create a resetter for transform manager property
-          }
-          else
-          {
-            if ( 0 == componentIndex )
-            {
-              typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector3> > SceneGraphConstraint;
-              mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-            }
-            else if ( 1 == componentIndex )
-            {
-              typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector3> > SceneGraphConstraint;
-              mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-            }
-            else if ( 2 == componentIndex )
-            {
-              typedef SceneGraph::Constraint< float, PropertyComponentAccessorZ<Vector3> > SceneGraphConstraint;
-              mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-            }
-            if( mSceneGraphConstraint )
-            {
-              resetter = SceneGraph::ConstraintResetter::New( *targetObject, *targetProperty, *mSceneGraphConstraint );
-            }
-          }
+          ApplyPostConstraintMessage(GetEventThreadServices(), targetObject, transferOwnership);
         }
-        else if ( PropertyTypes::Get< Vector4 >() == targetProperty->GetType() )
+        if(resetterRequired)
         {
-          // Constrain float component of Vector4 property
-
-          if ( 0 == componentIndex )
-          {
-            typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector4> > SceneGraphConstraint;
-            mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-          }
-          else if ( 1 == componentIndex )
-          {
-            typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector4> > SceneGraphConstraint;
-            mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-          }
-          else if ( 2 == componentIndex )
-          {
-            typedef SceneGraph::Constraint< float, PropertyComponentAccessorZ<Vector4> > SceneGraphConstraint;
-            mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-          }
-          else if ( 3 == componentIndex )
-          {
-            typedef SceneGraph::Constraint< float, PropertyComponentAccessorW<Vector4> > SceneGraphConstraint;
-            mSceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mRemoveAction );
-          }
-
-          if( mSceneGraphConstraint )
-          {
-            resetter = SceneGraph::ConstraintResetter::New( *targetObject, *targetProperty, *mSceneGraphConstraint );
-          }
+          OwnerPointer<SceneGraph::PropertyResetterBase> resetter = SceneGraph::ConstraintResetter::New(targetObject, *targetProperty, *mSceneGraphConstraint);
+          AddResetterMessage(GetEventThreadServices().GetUpdateManager(), resetter);
         }
       }
-
-      if( mSceneGraphConstraint )
-      {
-        OwnerPointer< SceneGraph::ConstraintBase > transferOwnership( const_cast< SceneGraph::ConstraintBase* >( mSceneGraphConstraint ) );
-        ApplyConstraintMessage( GetEventThreadServices(), *targetObject, transferOwnership );
-      }
-      if( resetter != nullptr )
-      {
-        AddResetterMessage( GetEventThreadServices().GetUpdateManager(), resetter );
-      }
     }
   }
 
@@ -536,91 +323,126 @@ private:
    * Helper for ConnectConstraint. Creates a connected constraint-function.
    * Also populates the property-owner container, for each input connected to the constraint-function.
    * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
-   * @return A connected constraint-function, or NULL if the scene-graph properties are not available.
+   * @return A connected constraint-function, or nullptr if the scene-graph properties are not available.
    */
-  PropertyConstraint<float>* ConnectConstraintFunction( SceneGraph::PropertyOwnerContainer& propertyOwners )
+  PropertyConstraint<float>* ConnectConstraintFunction(SceneGraph::PropertyOwnerContainer& propertyOwners)
   {
     PropertyConstraint<float>* func = mUserFunction->Clone();
 
-    for ( SourceIter iter = mSources.begin(); mSources.end() != iter; ++iter )
+    for(auto&& source : mSources)
     {
-      Source& source = *iter;
-
-      PropertyInputImpl* inputProperty( NULL );
-      int componentIndex( Property::INVALID_COMPONENT_INDEX );
+      int32_t            componentIndex = Property::INVALID_COMPONENT_INDEX;
+      PropertyInputImpl* inputProperty  = AddInputProperty(source, propertyOwners, componentIndex);
 
-      if ( OBJECT_PROPERTY == source.sourceType )
+      if(nullptr == inputProperty)
       {
-        DALI_ASSERT_ALWAYS( source.object->IsPropertyAConstraintInput( source.propertyIndex ) );
+        delete func;
+        func = nullptr;
 
-        SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( source.object->GetSceneObject() );
+        // Exit if a scene-graph object is not available from one of the sources
+        break;
+      }
 
-        // The property owner will not exist, if the target object is off-stage
-        if( NULL != owner )
-        {
-          AddUnique( propertyOwners, owner );
-          inputProperty = const_cast< PropertyInputImpl* >( source.object->GetSceneObjectInputProperty( source.propertyIndex ) );
-          componentIndex = source.object->GetPropertyComponentIndex( source.propertyIndex );
+      func->AddInput(inputProperty, componentIndex);
+    }
 
-          // The scene-object property should exist, when the property owner exists
-          DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
-        }
+    return func;
+  }
+
+  /**
+   * Creates a component property constraint.
+   * @param[in] targetProperty The target property
+   * @param[in] componentIndex The index of the component
+   * @param[in] propertyOwners The owners of the property
+   * @param[in] func The constraint function
+   * @param[in/out] resetterRequired Set to true if a property resetter is required after creating this constraint
+   */
+  void CreateComponentConstraint(const SceneGraph::PropertyBase* targetProperty, const int32_t componentIndex, SceneGraph::PropertyOwnerContainer& propertyOwners, ConstraintFunctionPtr& func, bool& resetterRequired)
+  {
+    // Expecting Vector2, Vector3 or Vector4 type
+    if(PropertyTypes::Get<Vector2>() == targetProperty->GetType())
+    {
+      // Constrain float component of Vector2 property
+      if(0 == componentIndex)
+      {
+        mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorX<Vector2> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
       }
-      else if ( LOCAL_PROPERTY == source.sourceType )
+      else if(1 == componentIndex)
       {
-        DALI_ASSERT_ALWAYS( mTargetObject->IsPropertyAConstraintInput( source.propertyIndex ) );
-
-        inputProperty = const_cast< PropertyInputImpl* >( mTargetObject->GetSceneObjectInputProperty( source.propertyIndex ) );
-        componentIndex = mTargetObject->GetPropertyComponentIndex( source.propertyIndex );
-
-        // The target scene-object should provide this property
-        DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
+        mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorY<Vector2> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
+      }
+      resetterRequired = (mSceneGraphConstraint != nullptr);
+    }
+    else if(PropertyTypes::Get<Vector3>() == targetProperty->GetType())
+    {
+      // Constrain float component of Vector3 property
+      if(targetProperty->IsTransformManagerProperty())
+      {
+        if(0 == componentIndex)
+        {
+          mSceneGraphConstraint = SceneGraph::Constraint<float, TransformManagerPropertyComponentAccessor<Vector3, 0> >::New(*targetProperty,
+                                                                                                                             propertyOwners,
+                                                                                                                             func,
+                                                                                                                             mRemoveAction);
+        }
+        else if(1 == componentIndex)
+        {
+          mSceneGraphConstraint = SceneGraph::Constraint<float, TransformManagerPropertyComponentAccessor<Vector3, 1> >::New(*targetProperty,
+                                                                                                                             propertyOwners,
+                                                                                                                             func,
+                                                                                                                             mRemoveAction);
+        }
+        else if(2 == componentIndex)
+        {
+          mSceneGraphConstraint = SceneGraph::Constraint<float, TransformManagerPropertyComponentAccessor<Vector3, 2> >::New(*targetProperty,
+                                                                                                                             propertyOwners,
+                                                                                                                             func,
+                                                                                                                             mRemoveAction);
+        }
+        // Do not create a resetter for transform manager property
       }
       else
       {
-        DALI_ASSERT_ALWAYS( PARENT_PROPERTY == source.sourceType && "Constraint source property type is invalid" );
-
-        Object* objectParent = dynamic_cast< Actor& >( *mTargetObject ).GetParent();
-
-        // This will not exist, if the target object is off-stage
-        if ( NULL != objectParent )
+        if(0 == componentIndex)
         {
-          DALI_ASSERT_ALWAYS( objectParent->IsPropertyAConstraintInput( source.propertyIndex ) );
-
-          SceneGraph::PropertyOwner* owner = const_cast< SceneGraph::PropertyOwner* >( objectParent->GetSceneObject() );
-
-          // The property owner will not exist, if the parent object is off-stage
-          if ( NULL != owner )
-          {
-            AddUnique( propertyOwners, owner );
-            inputProperty = const_cast< PropertyInputImpl* >( objectParent->GetSceneObjectInputProperty( source.propertyIndex ) );
-            componentIndex = objectParent->GetPropertyComponentIndex( source.propertyIndex );
-
-            // The scene-object property should exist, when the property owner exists
-            DALI_ASSERT_ALWAYS( NULL != inputProperty && "Constraint source property does not exist" );
-          }
+          mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorX<Vector3> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
         }
+        else if(1 == componentIndex)
+        {
+          mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorY<Vector3> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
+        }
+        else if(2 == componentIndex)
+        {
+          mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorZ<Vector3> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
+        }
+        resetterRequired = (mSceneGraphConstraint != nullptr);
       }
-
-      if ( NULL == inputProperty )
+    }
+    else if(PropertyTypes::Get<Vector4>() == targetProperty->GetType())
+    {
+      // Constrain float component of Vector4 property
+      if(0 == componentIndex)
       {
-        delete func;
-        func = NULL;
-
-        // Exit if a scene-graph object is not available from one of the sources
-        break;
+        mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorX<Vector4> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
+      }
+      else if(1 == componentIndex)
+      {
+        mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorY<Vector4> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
+      }
+      else if(2 == componentIndex)
+      {
+        mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorZ<Vector4> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
+      }
+      else if(3 == componentIndex)
+      {
+        mSceneGraphConstraint = SceneGraph::Constraint<float, PropertyComponentAccessorW<Vector4> >::New(*targetProperty, propertyOwners, func, mRemoveAction);
       }
 
-      func->SetInput( ( iter - mSources.begin() ), componentIndex, *inputProperty );
+      resetterRequired = (mSceneGraphConstraint != nullptr);
     }
-
-    return func;
   }
 
 protected:
-
-  Property::Index mTargetIndex;
-
   ConstraintFunctionPtr mUserFunction;
 };
 
@@ -628,4 +450,4 @@ protected:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_ACTIVE_CONSTRAINT_H__
+#endif // DALI_INTERNAL_ACTIVE_CONSTRAINT_H