Internal animation changes 56/33156/13
authorFerran Sole <ferran.sole@samsung.com>
Tue, 6 Jan 2015 11:09:48 +0000 (11:09 +0000)
committerFerran Sole <ferran.sole@samsung.com>
Thu, 8 Jan 2015 16:02:29 +0000 (16:02 +0000)
 - Changed animation system to avoid creating/destroying SceneGraph::Animators each time the target object is connected/disconnected from the stage
 - Removed use of boost::function for animator functions

[Problem]  AnimatorConnector will create a new SceneGraph::Animator each time the target object gets connected to the stage.
           SceneGraph::Animators will be deleted by the SceneGraph::Animation whenever the target object is disconnected.
[Cause]    n/a
[Solution] AnimatorConnector creates a SceneGraph::Animator once and notifies to it whenever the target object is connected/disconnected.
           SceneGraph::Animation will only remove Animators when the target object has been destroyed.

Change-Id: I0f35e85b8bf150cd954197fe6d213aad2d9f9c89

dali/internal/event/animation/animation-impl.cpp
dali/internal/event/animation/animator-connector.h
dali/internal/update/animation/scene-graph-animation.cpp
dali/internal/update/animation/scene-graph-animation.h
dali/internal/update/animation/scene-graph-animator.h
dali/internal/update/animation/scene-graph-constraint-base.h
dali/internal/update/common/property-owner.cpp
dali/internal/update/common/property-owner.h
dali/internal/update/node-attachments/scene-graph-mesh-attachment.h
dali/internal/update/nodes/node.cpp

index 7a04d21..c99cb83 100644 (file)
@@ -289,7 +289,7 @@ void Animation::AnimateBy(Property& target, Property::Value& relativeValue, Alph
       AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
                                                           target.propertyIndex,
                                                           target.componentIndex,
-                                                          AnimateByBoolean(relativeValue.Get<bool>()),
+                                                          new AnimateByBoolean(relativeValue.Get<bool>()),
                                                           alpha,
                                                           period ) );
       break;
@@ -300,7 +300,7 @@ void Animation::AnimateBy(Property& target, Property::Value& relativeValue, Alph
       AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
                                                            target.propertyIndex,
                                                            target.componentIndex,
-                                                           AnimateByFloat(relativeValue.Get<float>()),
+                                                           new AnimateByFloat(relativeValue.Get<float>()),
                                                            alpha,
                                                            period ) );
       break;
@@ -311,7 +311,7 @@ void Animation::AnimateBy(Property& target, Property::Value& relativeValue, Alph
       AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
                                                          target.propertyIndex,
                                                          target.componentIndex,
-                                                         AnimateByInteger(relativeValue.Get<int>()),
+                                                         new AnimateByInteger(relativeValue.Get<int>()),
                                                          alpha,
                                                          period ) );
       break;
@@ -322,7 +322,7 @@ void Animation::AnimateBy(Property& target, Property::Value& relativeValue, Alph
       AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
                                                              target.propertyIndex,
                                                              target.componentIndex,
-                                                             AnimateByVector2(relativeValue.Get<Vector2>()),
+                                                             new AnimateByVector2(relativeValue.Get<Vector2>()),
                                                              alpha,
                                                              period ) );
       break;
@@ -333,7 +333,7 @@ void Animation::AnimateBy(Property& target, Property::Value& relativeValue, Alph
       AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
                                                              target.propertyIndex,
                                                              target.componentIndex,
-                                                             AnimateByVector3(relativeValue.Get<Vector3>()),
+                                                             new AnimateByVector3(relativeValue.Get<Vector3>()),
                                                              alpha,
                                                              period ) );
       break;
@@ -344,7 +344,7 @@ void Animation::AnimateBy(Property& target, Property::Value& relativeValue, Alph
       AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
                                                              target.propertyIndex,
                                                              target.componentIndex,
-                                                             AnimateByVector4(relativeValue.Get<Vector4>()),
+                                                             new AnimateByVector4(relativeValue.Get<Vector4>()),
                                                              alpha,
                                                              period ) );
       break;
@@ -357,7 +357,7 @@ void Animation::AnimateBy(Property& target, Property::Value& relativeValue, Alph
       AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
                                                                 target.propertyIndex,
                                                                 target.componentIndex,
-                                                                RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
+                                                                new RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
                                                                 alpha,
                                                                 period ) );
       break;
@@ -414,7 +414,7 @@ void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPrope
       AddAnimatorConnector( AnimatorConnector<bool>::New(targetObject,
                                                          targetPropertyIndex,
                                                          componentIndex,
-                                                         AnimateToBoolean(destinationValue.Get<bool>()),
+                                                         new AnimateToBoolean(destinationValue.Get<bool>()),
                                                          alpha,
                                                          period) );
       break;
@@ -425,7 +425,7 @@ void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPrope
       AddAnimatorConnector( AnimatorConnector<float>::New(targetObject,
                                                           targetPropertyIndex,
                                                           componentIndex,
-                                                          AnimateToFloat(destinationValue.Get<float>()),
+                                                          new AnimateToFloat(destinationValue.Get<float>()),
                                                           alpha,
                                                           period) );
       break;
@@ -436,7 +436,7 @@ void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPrope
       AddAnimatorConnector( AnimatorConnector<int>::New(targetObject,
                                                         targetPropertyIndex,
                                                         componentIndex,
-                                                        AnimateToInteger(destinationValue.Get<int>()),
+                                                        new AnimateToInteger(destinationValue.Get<int>()),
                                                         alpha,
                                                         period) );
       break;
@@ -447,7 +447,7 @@ void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPrope
       AddAnimatorConnector( AnimatorConnector<Vector2>::New(targetObject,
                                                             targetPropertyIndex,
                                                             componentIndex,
-                                                            AnimateToVector2(destinationValue.Get<Vector2>()),
+                                                            new AnimateToVector2(destinationValue.Get<Vector2>()),
                                                             alpha,
                                                             period) );
       break;
@@ -469,7 +469,7 @@ void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPrope
       AddAnimatorConnector( AnimatorConnector<Vector3>::New(targetObject,
                                                             targetPropertyIndex,
                                                             componentIndex,
-                                                            AnimateToVector3(destinationValue.Get<Vector3>()),
+                                                            new AnimateToVector3(destinationValue.Get<Vector3>()),
                                                             alpha,
                                                             period) );
       break;
@@ -480,7 +480,7 @@ void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPrope
       AddAnimatorConnector( AnimatorConnector<Vector4>::New(targetObject,
                                                             targetPropertyIndex,
                                                             componentIndex,
-                                                            AnimateToVector4(destinationValue.Get<Vector4>()),
+                                                            new AnimateToVector4(destinationValue.Get<Vector4>()),
                                                             alpha,
                                                             period) );
       break;
@@ -491,7 +491,7 @@ void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPrope
       AddAnimatorConnector( AnimatorConnector<Quaternion>::New(targetObject,
                                                                targetPropertyIndex,
                                                                componentIndex,
-                                                               RotateToQuaternion(destinationValue.Get<Quaternion>()),
+                                                               new RotateToQuaternion(destinationValue.Get<Quaternion>()),
                                                                alpha,
                                                                period) );
       break;
@@ -554,7 +554,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
                                                           target.propertyIndex,
                                                           target.componentIndex,
-                                                          KeyFrameBooleanFunctor(kfCopy),
+                                                          new KeyFrameBooleanFunctor(kfCopy),
                                                           alpha,
                                                           period ) );
       break;
@@ -568,7 +568,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
                                                            target.propertyIndex,
                                                            target.componentIndex,
-                                                           KeyFrameNumberFunctor(kfCopy,interpolation),
+                                                           new KeyFrameNumberFunctor(kfCopy,interpolation),
                                                            alpha,
                                                            period ) );
       break;
@@ -582,7 +582,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
                                                          target.propertyIndex,
                                                          target.componentIndex,
-                                                         KeyFrameIntegerFunctor(kfCopy,interpolation),
+                                                         new KeyFrameIntegerFunctor(kfCopy,interpolation),
                                                          alpha,
                                                          period ) );
       break;
@@ -596,7 +596,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
                                                              target.propertyIndex,
                                                              target.componentIndex,
-                                                             KeyFrameVector2Functor(kfCopy,interpolation),
+                                                             new KeyFrameVector2Functor(kfCopy,interpolation),
                                                              alpha,
                                                              period ) );
       break;
@@ -610,7 +610,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
                                                              target.propertyIndex,
                                                              target.componentIndex,
-                                                             KeyFrameVector3Functor(kfCopy,interpolation),
+                                                             new KeyFrameVector3Functor(kfCopy,interpolation),
                                                              alpha,
                                                              period ) );
       break;
@@ -624,7 +624,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
                                                              target.propertyIndex,
                                                              target.componentIndex,
-                                                             KeyFrameVector4Functor(kfCopy,interpolation),
+                                                             new KeyFrameVector4Functor(kfCopy,interpolation),
                                                              alpha,
                                                              period ) );
       break;
@@ -638,7 +638,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
       AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
                                                                 target.propertyIndex,
                                                                 target.componentIndex,
-                                                                KeyFrameQuaternionFunctor(kfCopy),
+                                                                new KeyFrameQuaternionFunctor(kfCopy),
                                                                 alpha,
                                                                 period ) );
       break;
@@ -744,7 +744,7 @@ void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward,
   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
                                                          Dali::Actor::POSITION,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         PathPositionFunctor( pathCopy ),
+                                                         new PathPositionFunctor( pathCopy ),
                                                          alpha,
                                                          period ) );
 
@@ -755,7 +755,7 @@ void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward,
     AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
                                                               Dali::Actor::ROTATION,
                                                               Property::INVALID_COMPONENT_INDEX,
-                                                              PathRotationFunctor( pathCopy, forward ),
+                                                              new PathRotationFunctor( pathCopy, forward ),
                                                               alpha,
                                                               period ) );
   }
@@ -778,7 +778,7 @@ void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction
   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
                                                          Dali::Actor::POSITION,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateByVector3(displacement),
+                                                         new AnimateByVector3(displacement),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -800,7 +800,7 @@ void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alph
   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
                                                          Dali::Actor::POSITION,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateToVector3(position),
+                                                         new AnimateToVector3(position),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -822,7 +822,7 @@ void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaF
   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
                                                             Dali::Actor::ROTATION,
                                                             Property::INVALID_COMPONENT_INDEX,
-                                                            RotateByAngleAxis(angle, axis),
+                                                            new RotateByAngleAxis(angle, axis),
                                                             alpha,
                                                             TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -874,7 +874,7 @@ void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction
   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
                                                             Dali::Actor::ROTATION,
                                                             Property::INVALID_COMPONENT_INDEX,
-                                                            RotateToQuaternion(rotation),
+                                                            new RotateToQuaternion(rotation),
                                                             alpha,
                                                             TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -896,7 +896,7 @@ void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha,
   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
                                                          Dali::Actor::SCALE,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateByVector3(scale),
+                                                         new AnimateByVector3(scale),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -918,7 +918,7 @@ void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha,
   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
                                                          Dali::Actor::SCALE,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateToVector3(scale),
+                                                         new AnimateToVector3(scale),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -930,7 +930,7 @@ void Animation::Show(Actor& actor, float delaySeconds)
   AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
                                                       Dali::Actor::VISIBLE,
                                                       Property::INVALID_COMPONENT_INDEX,
-                                                      AnimateToBoolean(SHOW_VALUE),
+                                                      new AnimateToBoolean(SHOW_VALUE),
                                                       AlphaFunctions::Default,
                                                       TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
 }
@@ -942,7 +942,7 @@ void Animation::Hide(Actor& actor, float delaySeconds)
   AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
                                                       Dali::Actor::VISIBLE,
                                                       Property::INVALID_COMPONENT_INDEX,
-                                                      AnimateToBoolean(HIDE_VALUE),
+                                                      new AnimateToBoolean(HIDE_VALUE),
                                                       AlphaFunctions::Default,
                                                       TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
 }
@@ -964,7 +964,7 @@ void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, floa
   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
                                                          Dali::Actor::COLOR,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateByOpacity(opacity),
+                                                         new AnimateByOpacity(opacity),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -986,7 +986,7 @@ void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, floa
   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
                                                          Dali::Actor::COLOR,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateToOpacity(opacity),
+                                                         new AnimateToOpacity(opacity),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -1008,7 +1008,7 @@ void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha,
   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
                                                          Dali::Actor::COLOR,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateByVector4(color),
+                                                         new AnimateByVector4(color),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -1030,7 +1030,7 @@ void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha,
   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
                                                          Dali::Actor::COLOR,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateToVector4(color),
+                                                         new AnimateToVector4(color),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -1057,7 +1057,7 @@ void Animation::Resize(Actor& actor, float width, float height, AlphaFunction al
   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
                                                          Dali::Actor::SIZE,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateToVector3(targetSize),
+                                                         new AnimateToVector3(targetSize),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
@@ -1082,7 +1082,7 @@ void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, f
   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
                                                          Dali::Actor::SIZE,
                                                          Property::INVALID_COMPONENT_INDEX,
-                                                         AnimateToVector3(size),
+                                                         new AnimateToVector3(size),
                                                          alpha,
                                                          TimePeriod(delaySeconds, durationSeconds) ) );
 }
index 1c535c2..da800cc 100644 (file)
@@ -18,9 +18,6 @@
  *
  */
 
-// EXTERNAL INCLUDES
-#include <boost/function.hpp>
-
 // INTERNAL INCLUDES
 #include <dali/internal/event/common/proxy-object.h>
 #include <dali/internal/event/animation/animator-connector-base.h>
@@ -51,7 +48,6 @@ class AnimatorConnector : public AnimatorConnectorBase, public ProxyObject::Obse
 {
 public:
 
-  typedef boost::function< PropertyType (float, const PropertyType&) > AnimatorFunction;
   typedef SceneGraph::Animator< PropertyType, PropertyAccessor<PropertyType> > AnimatorType;
   typedef SceneGraph::AnimatableProperty< PropertyType > PropertyInterfaceType;
 
@@ -68,7 +64,7 @@ public:
   static AnimatorConnectorBase* New( ProxyObject& proxy,
                                      Property::Index propertyIndex,
                                      int componentIndex,
-                                     const AnimatorFunction& animatorFunction,
+                                     AnimatorFunctionBase* animatorFunction,
                                      AlphaFunction alpha,
                                      const TimePeriod& period )
   {
@@ -90,8 +86,13 @@ public:
       mProxy->RemoveObserver( *this );
     }
 
-    // Removing animators via Animation is not necessary.
-    // The corresponding scene graph animation will destroy any animators that become disconnected.
+    //If there is not a SceneGraph::Animator, the AnimatorConnector is responsible for deleting the mAnimatorFunction
+    //otherwise, the animator function ownership is transferred to the SceneGraph::Animator
+    if( !mAnimator )
+    {
+      delete mAnimatorFunction;
+      mAnimatorFunction = 0;
+    }
   }
 
   /**
@@ -103,14 +104,9 @@ public:
     DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent" );
     mParent = &parent;
 
-    if( mProxy )
+    if( mProxy && mProxy->GetSceneObject() )
     {
-      // Connect an animator, if the proxy has added an object to the scene-graph
-      const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
-      if( object )
-      {
-        ConnectAnimator( *object );
-      }
+      CreateAnimator();
     }
   }
 
@@ -122,15 +118,15 @@ private:
   AnimatorConnector( ProxyObject& proxy,
                      Property::Index propertyIndex,
                      int componentIndex,
-                     const AnimatorFunction& animatorFunction,
+                     Internal::AnimatorFunctionBase* animatorFunction,
                      AlphaFunction alpha,
                      const TimePeriod& period )
   : AnimatorConnectorBase( alpha, period ),
     mProxy( &proxy ),
+    mAnimator(0),
     mPropertyIndex( propertyIndex ),
     mComponentIndex( componentIndex ),
-    mAnimatorFunction( animatorFunction ),
-    mConnected( false )
+    mAnimatorFunction( animatorFunction )
   {
     proxy.AddObserver( *this );
   }
@@ -146,184 +142,18 @@ private:
    */
   virtual void SceneObjectAdded( ProxyObject& proxy )
   {
-    const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
-    DALI_ASSERT_DEBUG( NULL != object );
-
-    ConnectAnimator( *object );
-  }
-
-  /**
-   * From ProxyObject::Observer
-   */
-  virtual void SceneObjectRemoved( ProxyObject& proxy )
-  {
-    // Removing animators via Animation is not necessary.
-    // The corresponding scene graph animation will destroy any animators that become disconnected.
-    mConnected = false;
-  }
-
-  /**
-   * From ProxyObject::Observer
-   */
-  virtual void ProxyDestroyed( ProxyObject& proxy )
-  {
-    mConnected = false;
-    mProxy = NULL;
-  }
-
-  /**
-   * Create and connect an animator via update manager
-   */
-  void ConnectAnimator( const SceneGraph::PropertyOwner& object )
-  {
-    DALI_ASSERT_DEBUG( false == mConnected ); // Guard against double connections
-    DALI_ASSERT_DEBUG( NULL != mParent );
-
-    const SceneGraph::PropertyBase* base = mProxy->GetSceneObjectAnimatableProperty( mPropertyIndex );
-
-    const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
-    DALI_ASSERT_DEBUG( NULL != sceneProperty && "Animating property with invalid type" );
-
-    SceneGraph::AnimatorBase* animator = AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
-    DALI_ASSERT_DEBUG( NULL != animator );
-
-    const SceneGraph::Animation* animation = mParent->GetSceneObject();
-    DALI_ASSERT_DEBUG( NULL != animation );
-
-    AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *animator, object );
-
-    mConnected = true; // not really necessary, but useful for asserts
-  }
-
-protected:
-
-  ProxyObject* mProxy; ///< Not owned by the animator connector. Valid until ProxyDestroyed() is called.
-
-  Property::Index mPropertyIndex;
-
-  int mComponentIndex;
-
-  AnimatorFunction mAnimatorFunction;
-
-  bool mConnected; ///< Used to guard against double connections
-};
-
-/**
- * Variant which allows float components to be animated individually.
- */
-template <>
-class AnimatorConnector<float> : public AnimatorConnectorBase, public ProxyObject::Observer
-{
-public:
-
-  typedef boost::function< float (float, const float&) > AnimatorFunction;
-  typedef SceneGraph::Animator< float, PropertyAccessor<float> > AnimatorType;
-
-  /**
-   * Construct a new animator connector.
-   * @param[in] proxy The proxy for a scene-graph object to animate.
-   * @param[in] propertyIndex The index of a property provided by the object.
-   * @param[in] componentIndex Index to a sub component of a property, for use with Vector2, Vector3 and Vector4
-   * @param[in] animatorFunction A function used to animate the property.
-   * @param[in] alpha The alpha function to apply.
-   * @param[in] period The time period of the animator.
-   * @return A pointer to a newly allocated animator connector.
-   */
-  static AnimatorConnectorBase* New( ProxyObject& proxy,
-                                     Property::Index propertyIndex,
-                                     int componentIndex,
-                                     const AnimatorFunction& animatorFunction,
-                                     AlphaFunction alpha,
-                                     const TimePeriod& period )
-  {
-    return new AnimatorConnector<float>( proxy,
-                                         propertyIndex,
-                                         componentIndex,
-                                         animatorFunction,
-                                         alpha,
-                                         period );
-  }
-
-  /**
-   * Virtual destructor.
-   */
-  virtual ~AnimatorConnector()
-  {
-    if( mProxy )
-    {
-      mProxy->RemoveObserver( *this );
-    }
-
-    // Removing animators via Animation is not necessary.
-    // The corresponding scene graph animation will destroy any animators that become disconnected.
-  }
-
-  /**
-   * From AnimatorConnectorBase.
-   * This is only expected to be called once, when added to an Animation.
-   */
-  void SetParent( Animation& parent )
-  {
-    DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent");
-    mParent = &parent;
-
-    if( mProxy )
+    //If the animator has not been created yet, create it now.
+    if( !mAnimator )
     {
-      // Connect an animator, if the proxy has added an object to the scene-graph
-      const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
-      if( object )
-      {
-        ConnectAnimator( *object );
-      }
+      CreateAnimator();
     }
   }
 
-private:
-
-  /**
-   * Private constructor; see also AnimatorConnector::New().
-   */
-  AnimatorConnector( ProxyObject& proxy,
-                     Property::Index propertyIndex,
-                     int componentIndex,
-                     const AnimatorFunction& animatorFunction,
-                     AlphaFunction alpha,
-                     const TimePeriod& period )
-  : AnimatorConnectorBase( alpha, period ),
-    mProxy( &proxy ),
-    mPropertyIndex( propertyIndex ),
-    mComponentIndex( componentIndex ),
-    mAnimatorFunction( animatorFunction ),
-    mConnected( false )
-  {
-    proxy.AddObserver( *this );
-  }
-
-  // Undefined
-  AnimatorConnector( const AnimatorConnector& );
-
-  // Undefined
-  AnimatorConnector& operator=( const AnimatorConnector& rhs );
-
-  /**
-   * From ProxyObject::Observer
-   */
-  virtual void SceneObjectAdded( ProxyObject& proxy )
-  {
-    const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
-    DALI_ASSERT_DEBUG( NULL != object );
-
-    ConnectAnimator( *object );
-  }
-
   /**
    * From ProxyObject::Observer
    */
   virtual void SceneObjectRemoved( ProxyObject& proxy )
   {
-    // Removing animators via Animation is not necessary.
-    // The corresponding scene graph animation will destroy any animators that become disconnected.
-    mConnected = false;
   }
 
   /**
@@ -331,123 +161,172 @@ private:
    */
   virtual void ProxyDestroyed( ProxyObject& proxy )
   {
-    mConnected = false;
     mProxy = NULL;
   }
 
-  /**
-   * Create and connect an animator via update manager
+   /**
+   * Helper function to create a Scenegraph::Animator and add it to its correspondent SceneGraph::Animation.
+   * @note This function will only be called the first time the object is added to the scene or at creation time if
+   * the object was already in the scene
    */
-  void ConnectAnimator( const SceneGraph::PropertyOwner& object )
+  void CreateAnimator()
   {
-    DALI_ASSERT_DEBUG( false == mConnected ); // Guard against double connections
-    DALI_ASSERT_DEBUG( NULL != mParent );
+    DALI_ASSERT_DEBUG( mAnimator == NULL );
+    DALI_ASSERT_DEBUG( mAnimatorFunction != NULL );
+    DALI_ASSERT_DEBUG( mParent != NULL );
 
-    const SceneGraph::PropertyBase* base = mProxy->GetSceneObjectAnimatableProperty( mPropertyIndex );
-    DALI_ASSERT_DEBUG( NULL != base );
+    //Get the PropertyOwner the animator is going to animate
+    const SceneGraph::PropertyOwner* propertyOwner = mProxy->GetSceneObject();
 
-    SceneGraph::AnimatorBase* animator( NULL );
+    //Get SceneGraph::BaseProperty
+    const SceneGraph::PropertyBase* baseProperty = mProxy->GetSceneObjectAnimatableProperty( mPropertyIndex );
 
+    //Check if property is a component of another property
     const int componentIndex = mProxy->GetPropertyComponentIndex( mPropertyIndex );
     if( componentIndex != Property::INVALID_COMPONENT_INDEX )
     {
       mComponentIndex = componentIndex;
     }
 
-    if ( Property::INVALID_COMPONENT_INDEX == mComponentIndex )
+    if( mComponentIndex == Property::INVALID_COMPONENT_INDEX )
     {
-      // Not a Vector3 or Vector4 component, expecting float type
-      DALI_ASSERT_DEBUG( PropertyTypes::Get< float >() == base->GetType() );
+      ///Animating the whole property
+
+      //Cast to AnimatableProperty
+      const PropertyInterfaceType* animatableProperty = dynamic_cast< const PropertyInterfaceType* >( baseProperty );
 
-      typedef SceneGraph::AnimatableProperty< float > PropertyInterfaceType;
+      //Dynamic cast will fail if BaseProperty is not an AnimatableProperty
+      DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
 
-      const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
-      DALI_ASSERT_DEBUG( NULL != sceneProperty );
+      //Create the animator
+      mAnimator = AnimatorType::New( *propertyOwner, *animatableProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
 
-      animator = AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
     }
     else
     {
-      // Expecting Vector3 or Vector4 type
+      ///Animating a component of the property
 
-      if ( PropertyTypes::Get< Vector3 >() == base->GetType() )
+      //Vector3
+      if ( PropertyTypes::Get< Vector3 >() == baseProperty->GetType() )
       {
-        // Animate float component of Vector3 property
-        typedef SceneGraph::AnimatableProperty< Vector3 > PropertyInterfaceType;
+        // Cast to AnimatableProperty of type Vector3
+        const SceneGraph::AnimatableProperty<Vector3>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( baseProperty );
 
-        const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
-        DALI_ASSERT_DEBUG( NULL != sceneProperty );
+        //Dynamic cast will fail if BaseProperty is not a Vector3 AnimatableProperty
+        DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
 
-        if ( 0 == mComponentIndex )
+        switch( mComponentIndex )
         {
-          typedef SceneGraph::Animator< float, PropertyComponentAccessorX<Vector3> > Vector3AnimatorType;
-          animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
-        }
-        else if ( 1 == mComponentIndex )
-        {
-          typedef SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> > Vector3AnimatorType;
-          animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
-        }
-        else if ( 2 == mComponentIndex )
-        {
-          typedef SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> > Vector3AnimatorType;
-          animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
+          case 0:
+          {
+            mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector3> >::New( *propertyOwner,
+                                                                                                 *animatableProperty,
+                                                                                                 mAnimatorFunction,
+                                                                                                 mAlphaFunction,
+                                                                                                 mTimePeriod );
+            break;
+          }
+          case 1:
+          {
+            mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> >::New( *propertyOwner,
+                                                                                                 *animatableProperty,
+                                                                                                 mAnimatorFunction,
+                                                                                                 mAlphaFunction,
+                                                                                                 mTimePeriod );
+            break;
+          }
+          case 2:
+          {
+            mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> >::New( *propertyOwner,
+                                                                                                 *animatableProperty,
+                                                                                                 mAnimatorFunction,
+                                                                                                 mAlphaFunction,
+                                                                                                 mTimePeriod );
+            break;
+          }
+          default:
+          {
+            break;
+          }
         }
       }
-      else if ( PropertyTypes::Get< Vector4 >() == base->GetType() )
+      else if ( PropertyTypes::Get< Vector4 >() == baseProperty->GetType() )
       {
         // Animate float component of Vector4 property
-        typedef SceneGraph::AnimatableProperty< Vector4 > PropertyInterfaceType;
 
-        const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
-        DALI_ASSERT_DEBUG( NULL != sceneProperty );
+        // Cast to AnimatableProperty of type Vector4
+        const SceneGraph::AnimatableProperty<Vector4>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( baseProperty );
 
-        if ( 0 == mComponentIndex )
-        {
-          typedef SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> > Vector4AnimatorType;
-          animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
-        }
-        else if ( 1 == mComponentIndex )
-        {
-          typedef SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> > Vector4AnimatorType;
-          animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
-        }
-        else if ( 2 == mComponentIndex )
-        {
-          typedef SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> > Vector4AnimatorType;
-          animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
-        }
-        else if ( 3 == mComponentIndex )
+        //Dynamic cast will fail if BaseProperty is not a Vector4 AnimatableProperty
+        DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
+
+        switch( mComponentIndex )
         {
-          typedef SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> > Vector4AnimatorType;
-          animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
+          case 0:
+          {
+            mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> >::New( *propertyOwner,
+                                                                                                 *animatableProperty,
+                                                                                                 mAnimatorFunction,
+                                                                                                 mAlphaFunction,
+                                                                                                 mTimePeriod );
+            break;
+          }
+          case 1:
+          {
+            mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> >::New( *propertyOwner,
+                                                                                                 *animatableProperty,
+                                                                                                 mAnimatorFunction,
+                                                                                                 mAlphaFunction,
+                                                                                                 mTimePeriod );
+            break;
+          }
+          case 2:
+          {
+            mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> >::New( *propertyOwner,
+                                                                                                 *animatableProperty,
+                                                                                                 mAnimatorFunction,
+                                                                                                 mAlphaFunction,
+                                                                                                 mTimePeriod );
+            break;
+          }
+          case 3:
+          {
+            mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> >::New( *propertyOwner,
+                                                                                                 *animatableProperty,
+                                                                                                 mAnimatorFunction,
+                                                                                                 mAlphaFunction,
+                                                                                                 mTimePeriod );
+            break;
+          }
+
+          default:
+          {
+            break;
+          }
         }
       }
     }
 
-    DALI_ASSERT_DEBUG( NULL != animator && "Animating property with invalid type" );
+    DALI_ASSERT_DEBUG( mAnimator != NULL );
 
+    //Add the new SceneGraph::Animator to its correspondent SceneGraph::Animation via message to UpdateManager
     const SceneGraph::Animation* animation = mParent->GetSceneObject();
     DALI_ASSERT_DEBUG( NULL != animation );
-
-    AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *animator, object );
-
-    mConnected = true; // not really necessary, but useful for asserts
+    AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *mAnimator );
   }
 
 protected:
 
   ProxyObject* mProxy; ///< Not owned by the animator connector. Valid until ProxyDestroyed() is called.
+  SceneGraph::AnimatorBase* mAnimator;
 
   Property::Index mPropertyIndex;
-
   int mComponentIndex;
 
-  AnimatorFunction mAnimatorFunction;
-
-  bool mConnected; ///< Used to guard against double connections
+  Internal::AnimatorFunctionBase* mAnimatorFunction;  ///< Owned by the animator connector until an Scenegraph::Animator is created
 };
 
+
 } // namespace Internal
 
 } // namespace Dali
index c1a3d04..4449e7f 100644 (file)
@@ -198,11 +198,9 @@ void Animation::OnDestroy(BufferIndex bufferIndex)
   mState = Destroyed;
 }
 
-void Animation::AddAnimator( AnimatorBase* animator, PropertyOwner* propertyOwner )
+void Animation::AddAnimator( AnimatorBase* animator )
 {
-  animator->Attach( propertyOwner );
   animator->SetDisconnectAction( mDisconnectAction );
-
   mAnimators.PushBack( animator );
 }
 
@@ -255,44 +253,55 @@ bool Animation::Update(BufferIndex bufferIndex, float elapsedSeconds)
 void Animation::UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished )
 {
   float elapsedSecondsClamped = Clamp( mElapsedSeconds, mPlayRange.x * mDurationSeconds,mPlayRange.y * mDurationSeconds );
+
+  //Loop through all animators
+  bool applied(true);
   for ( AnimatorIter iter = mAnimators.Begin(); iter != mAnimators.End(); )
   {
-    // If an animator is not successfully applied, then it has been orphaned
-    bool applied(true);
-
     AnimatorBase *animator = *iter;
-    const float initialDelay(animator->GetInitialDelay());
 
-    if (elapsedSecondsClamped >= initialDelay || mSpeedFactor < 0.0f )
+    if( animator->Orphan() )
+    {
+      //Remove animators whose PropertyOwner has been destroyed
+      iter = mAnimators.Erase(iter);
+    }
+    else
     {
-      // Calculate a progress specific to each individual animator
-      float progress(1.0f);
-      const float animatorDuration = animator->GetDuration();
-      if (animatorDuration > 0.0f) // animators can be "immediate"
+      if( animator->IsEnabled() )
+      {
+        const float initialDelay(animator->GetInitialDelay());
+        if (elapsedSecondsClamped >= initialDelay || mSpeedFactor < 0.0f )
+        {
+          // Calculate a progress specific to each individual animator
+          float progress(1.0f);
+          const float animatorDuration = animator->GetDuration();
+          if (animatorDuration > 0.0f) // animators can be "immediate"
+          {
+            progress = Clamp((elapsedSecondsClamped - initialDelay) / animatorDuration, 0.0f , 1.0f );
+          }
+          animator->Update(bufferIndex, progress, bake);
+        }
+        applied = true;
+      }
+      else
       {
-        progress = Clamp((elapsedSecondsClamped - initialDelay) / animatorDuration, 0.0f , 1.0f );
+        applied = false;
       }
 
-      applied = animator->Update(bufferIndex, progress, bake);
-    }
+      if ( animationFinished )
+      {
+        animator->SetActive( false );
+      }
 
-    if ( animationFinished )
-    {
-      animator->SetActive( false );
-    }
+      if (applied)
+      {
+        INCREASE_COUNTER(PerformanceMonitor::ANIMATORS_APPLIED);
+      }
 
-    // Animators are automatically removed, when orphaned from animatable scene objects.
-    if (!applied)
-    {
-      iter = mAnimators.Erase(iter);
-    }
-    else
-    {
       ++iter;
-
-      INCREASE_COUNTER(PerformanceMonitor::ANIMATORS_APPLIED);
     }
   }
+
 }
 
 } // namespace SceneGraph
index a6c1a5d..234aac9 100644 (file)
@@ -234,7 +234,7 @@ public:
    * @param[in] propertyOwner The scene-object that owns the animatable property.
    * @post The animator is owned by this animation.
    */
-  void AddAnimator( AnimatorBase* animator, PropertyOwner* propertyOwner );
+  void AddAnimator( AnimatorBase* animator );
 
   /**
    * Retrieve the animators from an animation.
@@ -429,17 +429,18 @@ inline void PauseAnimationMessage( EventToUpdate& eventToUpdate, const Animation
   new (slot) LocalType( &animation, &Animation::Pause );
 }
 
-inline void AddAnimatorMessage( EventToUpdate& eventToUpdate, const Animation& animation, AnimatorBase& animator, const PropertyOwner& owner )
+inline void AddAnimatorMessage( EventToUpdate& eventToUpdate, const Animation& animation, AnimatorBase& animator )
 {
-  typedef MessageValue2< Animation, OwnerPointer<AnimatorBase>, PropertyOwner* > LocalType;
+  typedef MessageValue1< Animation, OwnerPointer<AnimatorBase> > LocalType;
 
   // Reserve some memory inside the message queue
   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &animation, &Animation::AddAnimator, &animator, const_cast<PropertyOwner*>( &owner ) );
+  new (slot) LocalType( &animation, &Animation::AddAnimator, &animator );
 }
 
+
 } // namespace SceneGraph
 
 } // namespace Internal
index d6ee8f1..b8d5f58 100644 (file)
@@ -18,9 +18,6 @@
  *
  */
 
-// EXTERNAL INCLUDES
-#include <boost/function.hpp>
-
 // INTERNAL INCLUDES
 #include <dali/internal/common/owner-container.h>
 #include <dali/internal/event/animation/key-frames-impl.h>
@@ -42,6 +39,8 @@ namespace Internal
 
 typedef Dali::Animation::Interpolation Interpolation;
 
+struct AnimatorFunctionBase;
+
 namespace SceneGraph
 {
 
@@ -70,7 +69,8 @@ public:
     mInitialDelaySeconds(0.0f),
     mAlphaFunc(AlphaFunctions::Linear),
     mDisconnectAction(Dali::Animation::BakeFinal),
-    mActive(false)
+    mActive(false),
+    mEnabled(true)
   {
   }
 
@@ -160,7 +160,7 @@ public:
 
   /**
    * Whether the animator is active or not.
-   * @param [in] action The disconnect action.
+   * @param [in] active The new active state.
    * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected.
    * @note When the property owner is disconnected, the active state is set to false.
    */
@@ -178,28 +178,29 @@ public:
     return mActive;
   }
 
+  /*
+   * Retrive wheter the animator's target object is valid and on the stage.
+   * @return The enabled state.
+   */
+  bool IsEnabled() const
+  {
+    return mEnabled;
+  }
   /**
-   * This must be called when the animator is attached to the scene-graph.
-   * @pre The animatable scene object must also be attached to the scene-graph.
-   * @param[in] propertyOwner The scene-object that owns the animatable property.
+   * Returns wheter the target object of the animator is still valid
+   * or has been destroyed.
+   * @return True if animator is orphan, false otherwise   *
+   * @note The SceneGraph::Animation will delete any orphan animator in its Update method.
    */
-  virtual void Attach( PropertyOwner* propertyOwner ) = 0;
+  virtual bool Orphan() = 0;
 
   /**
    * Update the scene object attached to the animator.
    * @param[in] bufferIndex The buffer to animate.
    * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point.
    * @param[in] bake Bake.
-   * @return True if the update was applied, false if the animator has been orphaned.
    */
-  virtual bool Update(BufferIndex bufferIndex, float progress, bool bake) = 0;
-
-  /**
-   * Query whether the animator is still attached to a scene object.
-   * The attachment will be automatically severed, when the object is destroyed.
-   * @return True if the animator is attached.
-   */
-  virtual bool IsAttached() const = 0;
+  virtual void Update(BufferIndex bufferIndex, float progress, bool bake) = 0;
 
 protected:
 
@@ -208,8 +209,9 @@ protected:
 
   AlphaFunc mAlphaFunc;
 
-  Dali::Animation::EndAction mDisconnectAction;
-  bool mActive:1;
+  Dali::Animation::EndAction mDisconnectAction;     ///< EndAction to apply when target object gets disconnected from the stage.
+  bool mActive:1;                                   ///< Animator is "active" while it's running.
+  bool mEnabled:1;                                  ///< Animator is "enabled" while its target object is valid and on the stage.
 };
 
 /**
@@ -220,8 +222,6 @@ class Animator : public AnimatorBase, public PropertyOwner::Observer
 {
 public:
 
-  typedef boost::function< PropertyType (float, const PropertyType&) > AnimatorFunction;
-
   /**
    * Construct a new property animator.
    * @param[in] property The animatable property; only valid while the Animator is attached.
@@ -230,15 +230,17 @@ public:
    * @param[in] timePeriod The time period of this animation.
    * @return A newly allocated animator.
    */
-  static AnimatorBase* New( const PropertyBase& property,
-                            AnimatorFunction animatorFunction,
+  static AnimatorBase* New( const PropertyOwner& propertyOwner,
+                            const PropertyBase& property,
+                            AnimatorFunctionBase* animatorFunction,
                             AlphaFunction alphaFunction,
                             const TimePeriod& timePeriod )
   {
     typedef Animator< PropertyType, PropertyAccessorType > AnimatorType;
 
     // The property was const in the actor-thread, but animators are used in the scene-graph thread.
-    AnimatorType* animator = new AnimatorType( const_cast<PropertyBase*>( &property ),
+    AnimatorType* animator = new AnimatorType( const_cast<PropertyOwner*>( &propertyOwner ),
+                                               const_cast<PropertyBase*>( &property ),
                                                animatorFunction );
 
     animator->SetAlphaFunc( alphaFunction );
@@ -257,57 +259,19 @@ public:
     {
       mPropertyOwner->RemoveObserver(*this);
     }
-  }
-
-  /**
-   * From AnimatorBase.
-   * @param[in] propertyOwner The scene-object that owns the animatable property.
-   */
-  virtual void Attach( PropertyOwner* propertyOwner )
-  {
-    mPropertyOwner = propertyOwner;
-
-    if (mPropertyOwner)
-    {
-      mPropertyOwner->AddObserver(*this);
-    }
-  }
 
-  /**
-   * From AnimatorBase.
-   */
-  virtual bool Update( BufferIndex bufferIndex, float progress, bool bake )
-  {
-    // If the object dies, the animator has no effect
-    if ( mPropertyOwner )
+    if( mAnimatorFunction )
     {
-      float alpha = mAlphaFunc( progress );
-
-      const PropertyType& current = mPropertyAccessor.Get( bufferIndex );
-
-      const PropertyType result = mAnimatorFunction( alpha, current );
-
-      if ( bake )
-      {
-        mPropertyAccessor.Bake( bufferIndex, result );
-      }
-      else
-      {
-        mPropertyAccessor.Set( bufferIndex, result );
-      }
-
-      mCurrentProgress = progress;
+      delete mAnimatorFunction;
     }
-
-    return IsAttached(); // return false if orphaned
   }
 
   /**
-   * From AnimatorBase.
+   * Called when mPropertyOwner is connected to the scene graph.
    */
-  virtual bool IsAttached() const
+  virtual void PropertyOwnerConnected( PropertyOwner& owner )
   {
-    return NULL != mPropertyOwner;
+    mEnabled = true;
   }
 
   /**
@@ -323,17 +287,46 @@ public:
     }
 
     mActive = false;
-    mPropertyOwner = NULL;
-    mPropertyAccessor.Reset();
+    mEnabled = false;
   }
 
   /**
-   * Called shortly before mPropertyOwner is destroyed, along with its property.
+   * Called shortly before mPropertyOwner is destroyed
    */
   virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
   {
     mPropertyOwner = NULL;
     mPropertyAccessor.Reset();
+    mEnabled = false;
+  }
+
+  /**
+   * From AnimatorBase.
+   */
+  virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
+  {
+    float alpha = mAlphaFunc( progress );
+    const PropertyType& current = mPropertyAccessor.Get( bufferIndex );
+
+    const PropertyType result = (*mAnimatorFunction)( alpha, current );
+    if ( bake )
+    {
+      mPropertyAccessor.Bake( bufferIndex, result );
+    }
+    else
+    {
+      mPropertyAccessor.Set( bufferIndex, result );
+    }
+
+    mCurrentProgress = progress;
+  }
+
+  /**
+   * From AnimatorBase.
+   */
+  virtual bool Orphan()
+  {
+    return (mPropertyOwner == NULL);
   }
 
 private:
@@ -341,13 +334,15 @@ private:
   /**
    * Private constructor; see also Animator::New().
    */
-  Animator( PropertyBase* property,
-            AnimatorFunction animatorFunction )
-  : mPropertyOwner( NULL ),
+  Animator( PropertyOwner* propertyOwner,
+            PropertyBase* property,
+            AnimatorFunctionBase* animatorFunction )
+  : mPropertyOwner( propertyOwner ),
     mPropertyAccessor( property ),
     mAnimatorFunction( animatorFunction ),
     mCurrentProgress( 0.0f )
   {
+    mPropertyOwner->AddObserver(*this);
   }
 
   // Undefined
@@ -361,16 +356,68 @@ protected:
   PropertyOwner* mPropertyOwner;
   PropertyAccessorType mPropertyAccessor;
 
-  AnimatorFunction mAnimatorFunction;
+  AnimatorFunctionBase* mAnimatorFunction;
   float mCurrentProgress;
 };
 
 } // namespace SceneGraph
 
+/*
+ * AnimatorFunction base class.
+ * All update functions must inherit from AnimatorFunctionBase and overload the appropiate "()" operator
+ */
+struct AnimatorFunctionBase
+{
+  /**
+   * Constructor
+   */
+  AnimatorFunctionBase(){}
+
+  /*
+   * Virtual destructor (Intended as base class)
+   */
+  virtual ~AnimatorFunctionBase(){}
+
+  ///Stub "()" operators.
+  virtual float operator()(float progress, const int& property)
+  {
+    return property;
+  }
+
+  virtual float operator()(float progress, const float& property)
+  {
+    return property;
+  }
+
+  virtual bool operator()(float progress, const bool& property)
+  {
+    return property;
+  }
+
+  virtual Vector2 operator()(float progress, const Vector2& property)
+  {
+    return property;
+  }
+
+  virtual Vector3 operator()(float progress, const Vector3& property)
+  {
+    return property;
+  }
+
+  virtual Vector4 operator()(float progress, const Vector4& property)
+  {
+    return property;
+  }
+
+  virtual Quaternion operator()(float progress, const Quaternion& property)
+  {
+    return property;
+  }
+};
 
-// Common Update functions
+// Update functions
 
-struct AnimateByFloat
+struct AnimateByFloat : public AnimatorFunctionBase
 {
   AnimateByFloat(const float& relativeValue)
   : mRelative(relativeValue)
@@ -385,7 +432,7 @@ struct AnimateByFloat
   float mRelative;
 };
 
-struct AnimateToFloat
+struct AnimateToFloat : public AnimatorFunctionBase
 {
   AnimateToFloat(const float& targetValue)
   : mTarget(targetValue)
@@ -400,7 +447,7 @@ struct AnimateToFloat
   float mTarget;
 };
 
-struct AnimateByInteger
+struct AnimateByInteger : public AnimatorFunctionBase
 {
   AnimateByInteger(const int& relativeValue)
   : mRelative(relativeValue)
@@ -415,7 +462,7 @@ struct AnimateByInteger
   int mRelative;
 };
 
-struct AnimateToInteger
+struct AnimateToInteger : public AnimatorFunctionBase
 {
   AnimateToInteger(const int& targetValue)
   : mTarget(targetValue)
@@ -430,7 +477,7 @@ struct AnimateToInteger
   int mTarget;
 };
 
-struct AnimateByVector2
+struct AnimateByVector2 : public AnimatorFunctionBase
 {
   AnimateByVector2(const Vector2& relativeValue)
   : mRelative(relativeValue)
@@ -445,7 +492,7 @@ struct AnimateByVector2
   Vector2 mRelative;
 };
 
-struct AnimateToVector2
+struct AnimateToVector2 : public AnimatorFunctionBase
 {
   AnimateToVector2(const Vector2& targetValue)
   : mTarget(targetValue)
@@ -460,7 +507,7 @@ struct AnimateToVector2
   Vector2 mTarget;
 };
 
-struct AnimateByVector3
+struct AnimateByVector3 : public AnimatorFunctionBase
 {
   AnimateByVector3(const Vector3& relativeValue)
   : mRelative(relativeValue)
@@ -475,7 +522,7 @@ struct AnimateByVector3
   Vector3 mRelative;
 };
 
-struct AnimateToVector3
+struct AnimateToVector3 : public AnimatorFunctionBase
 {
   AnimateToVector3(const Vector3& targetValue)
   : mTarget(targetValue)
@@ -490,7 +537,7 @@ struct AnimateToVector3
   Vector3 mTarget;
 };
 
-struct AnimateByVector4
+struct AnimateByVector4 : public AnimatorFunctionBase
 {
   AnimateByVector4(const Vector4& relativeValue)
   : mRelative(relativeValue)
@@ -505,7 +552,7 @@ struct AnimateByVector4
   Vector4 mRelative;
 };
 
-struct AnimateToVector4
+struct AnimateToVector4 : public AnimatorFunctionBase
 {
   AnimateToVector4(const Vector4& targetValue)
   : mTarget(targetValue)
@@ -520,7 +567,7 @@ struct AnimateToVector4
   Vector4 mTarget;
 };
 
-struct AnimateByOpacity
+struct AnimateByOpacity : public AnimatorFunctionBase
 {
   AnimateByOpacity(const float& relativeValue)
   : mRelative(relativeValue)
@@ -538,7 +585,7 @@ struct AnimateByOpacity
   float mRelative;
 };
 
-struct AnimateToOpacity
+struct AnimateToOpacity : public AnimatorFunctionBase
 {
   AnimateToOpacity(const float& targetValue)
   : mTarget(targetValue)
@@ -556,7 +603,7 @@ struct AnimateToOpacity
   float mTarget;
 };
 
-struct AnimateByBoolean
+struct AnimateByBoolean : public AnimatorFunctionBase
 {
   AnimateByBoolean(bool relativeValue)
   : mRelative(relativeValue)
@@ -572,7 +619,7 @@ struct AnimateByBoolean
   bool mRelative;
 };
 
-struct AnimateToBoolean
+struct AnimateToBoolean : public AnimatorFunctionBase
 {
   AnimateToBoolean(bool targetValue)
   : mTarget(targetValue)
@@ -588,7 +635,7 @@ struct AnimateToBoolean
   bool mTarget;
 };
 
-struct RotateByAngleAxis
+struct RotateByAngleAxis : public AnimatorFunctionBase
 {
   RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
   : mAngleRadians(angleRadians),
@@ -610,7 +657,7 @@ struct RotateByAngleAxis
   Vector4 mAxis;
 };
 
-struct RotateToQuaternion
+struct RotateToQuaternion : public AnimatorFunctionBase
 {
   RotateToQuaternion(const Quaternion& targetValue)
   : mTarget(targetValue)
@@ -626,7 +673,7 @@ struct RotateToQuaternion
 };
 
 
-struct KeyFrameBooleanFunctor
+struct KeyFrameBooleanFunctor : public AnimatorFunctionBase
 {
   KeyFrameBooleanFunctor(KeyFrameBooleanPtr keyFrames)
   : mKeyFrames(keyFrames)
@@ -645,7 +692,7 @@ struct KeyFrameBooleanFunctor
   KeyFrameBooleanPtr mKeyFrames;
 };
 
-struct KeyFrameNumberFunctor
+struct KeyFrameNumberFunctor : public AnimatorFunctionBase
 {
   KeyFrameNumberFunctor(KeyFrameNumberPtr keyFrames, Interpolation interpolation)
   : mKeyFrames(keyFrames),mInterpolation(interpolation)
@@ -665,7 +712,7 @@ struct KeyFrameNumberFunctor
   Interpolation mInterpolation;
 };
 
-struct KeyFrameIntegerFunctor
+struct KeyFrameIntegerFunctor : public AnimatorFunctionBase
 {
   KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames, Interpolation interpolation)
   : mKeyFrames(keyFrames),mInterpolation(interpolation)
@@ -685,7 +732,7 @@ struct KeyFrameIntegerFunctor
   Interpolation mInterpolation;
 };
 
-struct KeyFrameVector2Functor
+struct KeyFrameVector2Functor : public AnimatorFunctionBase
 {
   KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames, Interpolation interpolation)
   : mKeyFrames(keyFrames),mInterpolation(interpolation)
@@ -706,7 +753,7 @@ struct KeyFrameVector2Functor
 };
 
 
-struct KeyFrameVector3Functor
+struct KeyFrameVector3Functor : public AnimatorFunctionBase
 {
   KeyFrameVector3Functor(KeyFrameVector3Ptr keyFrames, Interpolation interpolation)
   : mKeyFrames(keyFrames),mInterpolation(interpolation)
@@ -726,7 +773,7 @@ struct KeyFrameVector3Functor
   Interpolation mInterpolation;
 };
 
-struct KeyFrameVector4Functor
+struct KeyFrameVector4Functor : public AnimatorFunctionBase
 {
   KeyFrameVector4Functor(KeyFrameVector4Ptr keyFrames, Interpolation interpolation)
   : mKeyFrames(keyFrames),mInterpolation(interpolation)
@@ -746,7 +793,7 @@ struct KeyFrameVector4Functor
   Interpolation mInterpolation;
 };
 
-struct KeyFrameQuaternionFunctor
+struct KeyFrameQuaternionFunctor : public AnimatorFunctionBase
 {
   KeyFrameQuaternionFunctor(KeyFrameQuaternionPtr keyFrames)
   : mKeyFrames(keyFrames)
@@ -765,7 +812,7 @@ struct KeyFrameQuaternionFunctor
   KeyFrameQuaternionPtr mKeyFrames;
 };
 
-struct PathPositionFunctor
+struct PathPositionFunctor : public AnimatorFunctionBase
 {
   PathPositionFunctor( PathPtr path )
   : mPath(path)
@@ -780,7 +827,7 @@ struct PathPositionFunctor
   PathPtr mPath;
 };
 
-struct PathRotationFunctor
+struct PathRotationFunctor : public AnimatorFunctionBase
 {
   PathRotationFunctor( PathPtr path, const Vector3& forward )
   : mPath(path),
index 05bbda5..aba1a57 100644 (file)
@@ -168,11 +168,27 @@ private:
   }
 
   /**
+   * @copydoc PropertyOwner::Observer::PropertyOwnerConnected()
+   */
+  virtual void PropertyOwnerConnected( PropertyOwner& owner )
+  {
+  }
+
+  /**
    * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected()
    */
   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
   {
-    PropertyOwnerDestroyed( owner );
+    if ( !mDisconnected )
+    {
+      // Stop observing property owners
+      StopObservation();
+
+      // Notification for derived class
+      OnDisconnect();
+
+      mDisconnected = true;
+    }
   }
 
   /**
@@ -182,20 +198,22 @@ private:
   {
     if ( !mDisconnected )
     {
-      // Discard pointer to disconnected property owner
+      // Discard pointer to destroyed property owner. Otherwise StopObservation() would crash when trying to remove
+      //the constraint from the destroyed PropertyOwner's observers list
       PropertyOwnerIter iter = std::find( mObservedOwners.Begin(), mObservedOwners.End(), &owner );
       if( mObservedOwners.End() != iter )
       {
         mObservedOwners.Erase( iter );
+      }
 
-        // Stop observing the remaining property owners
-        StopObservation();
+      // Stop observing the rest of property owners
+      StopObservation();
 
-        // Notification for derived class
-        OnDisconnect();
+      // Notification for derived class
+      OnDisconnect();
+
+      mDisconnected = true;
 
-        mDisconnected = true;
-      }
     }
   }
 
index 19389b8..e6cfa77 100644 (file)
@@ -87,6 +87,16 @@ void PropertyOwner::Destroy()
   mConstraints.Clear();
 }
 
+void PropertyOwner::ConnectToSceneGraph()
+{
+  // Notification for observers
+  const ConstObserverIter endIter = mObservers.End();
+  for( ConstObserverIter iter = mObservers.Begin(); iter != endIter; ++iter)
+  {
+    (*iter)->PropertyOwnerConnected( *this );
+  }
+}
+
 void PropertyOwner::DisconnectFromSceneGraph( BufferIndex updateBufferIndex )
 {
   // Notification for observers
@@ -96,9 +106,6 @@ void PropertyOwner::DisconnectFromSceneGraph( BufferIndex updateBufferIndex )
     (*iter)->PropertyOwnerDisconnected( updateBufferIndex, *this );
   }
 
-  // Clear observers as they are not interested in destroyed if they have received a disconnect
-  mObservers.Clear();
-
   // Remove all constraints when disconnected from scene-graph
   mConstraints.Clear();
 }
index ffce83f..b60a838 100644 (file)
@@ -55,10 +55,15 @@ public:
   public:
 
     /**
+     * Called when the observable object is connected to the scene graph.
+     * @param[in] owner A reference to the connected PropertyOwner
+     */
+    virtual void PropertyOwnerConnected( PropertyOwner& owner ) = 0;
+
+    /**
      * Called when the observable object is disconnected from the scene graph.
      * @param[in] currentBufferIndex The buffer to reset.
-     * @post The observer is automatically disconnected
-     * (observer will not receive the PropertyOwnerDestroyed callback after this)
+     * @param[in] owner A reference to the disconnected PropertyOwner
      */
     virtual void PropertyOwnerDisconnected( BufferIndex updateBufferIndex, PropertyOwner& owner ) = 0;
 
@@ -110,7 +115,13 @@ public:
   void Destroy();
 
   /**
-   * Disconnect all observers and remove constraints.
+   * Notify all observers that the object has been connected
+   * This occurs when the object is connected to the scene-graph during UpdateManager::Update().
+   */
+  void ConnectToSceneGraph();
+
+  /**
+   * Notify all observers that the object has been disconnected and remove constraints.
    * This occurs when the object is disconnected from the scene-graph during UpdateManager::Update().
    * @param[in] currentBufferIndex The current update buffer.
    */
index 40229a4..1cb2019 100644 (file)
@@ -165,6 +165,11 @@ public:
 private:
 
   /**
+    * @copydoc PropertyOwner::Observer::PropertyOwnerConnected()
+    */
+   virtual void PropertyOwnerConnected( PropertyOwner& owner ){}
+
+  /**
    * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected()
    */
   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner );
index dda0a87..7b39c79 100644 (file)
@@ -126,6 +126,8 @@ void Node::ConnectChild( Node* childNode, int index )
   {
     mChildren.Insert(mChildren.Begin()+index, childNode);
   }
+
+  childNode->ConnectToSceneGraph();
 }
 
 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )