+
+
+/**
+ * An animator for a specific property type PropertyType.
+ */
+template <typename T, typename PropertyAccessorType>
+class AnimatorTransformProperty : public AnimatorBase, public PropertyOwner::Observer
+{
+public:
+
+ /**
+ * Construct a new property animator.
+ * @param[in] property The animatable property; only valid while the Animator is attached.
+ * @param[in] animatorFunction The function used to animate the property.
+ * @param[in] alphaFunction The alpha function to apply.
+ * @param[in] timePeriod The time period of this animation.
+ * @return A newly allocated animator.
+ */
+ static AnimatorBase* New( const PropertyOwner& propertyOwner,
+ const PropertyBase& property,
+ AnimatorFunctionBase* animatorFunction,
+ AlphaFunction alphaFunction,
+ const TimePeriod& timePeriod )
+ {
+
+ // The property was const in the actor-thread, but animators are used in the scene-graph thread.
+ AnimatorTransformProperty* animator = new AnimatorTransformProperty( const_cast<PropertyOwner*>( &propertyOwner ),
+ const_cast<PropertyBase*>( &property ),
+ animatorFunction );
+
+ animator->SetAlphaFunction( alphaFunction );
+ animator->SetIntervalDelay( timePeriod.delaySeconds );
+ animator->SetDuration( timePeriod.durationSeconds );
+
+ return animator;
+ }
+
+ /**
+ * Virtual destructor.
+ */
+ virtual ~AnimatorTransformProperty()
+ {
+ if (mPropertyOwner && mConnectedToSceneGraph)
+ {
+ mPropertyOwner->RemoveObserver(*this);
+ }
+
+ delete mAnimatorFunction;
+ }
+
+ /**
+ * Called when Animator is added to the scene-graph in update-thread.
+ */
+ virtual void ConnectToSceneGraph()
+ {
+ mConnectedToSceneGraph = true;
+ mPropertyOwner->AddObserver(*this);
+ }
+
+ /**
+ * Called when mPropertyOwner is connected to the scene graph.
+ */
+ virtual void PropertyOwnerConnected( PropertyOwner& owner )
+ {
+ mEnabled = true;
+ }
+
+ /**
+ * Called when mPropertyOwner is disconnected from the scene graph.
+ */
+ virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
+ {
+ // If we are active, then bake the value if required
+ if ( mActive && mDisconnectAction != Dali::Animation::Discard )
+ {
+ // Bake to target-value if BakeFinal, otherwise bake current value
+ Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true );
+ }
+
+ mActive = false;
+ mEnabled = false;
+ }
+
+ /**
+ * Called shortly before mPropertyOwner is destroyed
+ */
+ virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
+ {
+ mPropertyOwner = NULL;
+ }
+
+ /**
+ * From AnimatorBase.
+ */
+ virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
+ {
+ if( mLoopCount >= 0 )
+ {
+ // Update the progress value
+ progress = SetProgress( progress );
+ }
+
+ float alpha = ApplyAlphaFunction( progress );
+
+ const T& current = mPropertyAccessor.Get( bufferIndex );
+
+ // need to cast the return value in case property is integer
+ T result = static_cast<T>( (*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:
+
+ /**
+ * Private constructor; see also Animator::New().
+ */
+ AnimatorTransformProperty( PropertyOwner* propertyOwner,
+ PropertyBase* property,
+ AnimatorFunctionBase* animatorFunction )
+ : mPropertyOwner( propertyOwner ),
+ mPropertyAccessor( property ),
+ mAnimatorFunction( animatorFunction ),
+ mCurrentProgress( 0.0f )
+ {
+ // WARNING - this object is created in the event-thread
+ // The scene-graph mPropertyOwner object cannot be observed here
+ }
+
+ // Undefined
+ AnimatorTransformProperty( const AnimatorTransformProperty& );
+
+ // Undefined
+ AnimatorTransformProperty& operator=( const AnimatorTransformProperty& );
+
+protected:
+
+ PropertyOwner* mPropertyOwner;
+ PropertyAccessorType mPropertyAccessor;
+
+ AnimatorFunctionBase* mAnimatorFunction;
+ float mCurrentProgress;
+};
+