[4.0] Changed Update to reset only target properties each frame
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-animator.h
index b3694b7..b8da716 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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.
@@ -32,7 +32,7 @@
 #include <dali/public-api/math/quaternion.h>
 #include <dali/public-api/math/radian.h>
 #include <dali/internal/update/animation/property-accessor.h>
-
+#include <dali/integration-api/debug.h>
 
 namespace Dali
 {
@@ -65,16 +65,39 @@ public:
   typedef float (*AlphaFunc)(float progress); ///< Definition of an alpha function
 
   /**
+   * Observer to determine when the animator is no longer present
+   */
+  class LifecycleObserver
+  {
+  public:
+    /**
+     * Called shortly before the animator is destroyed.
+     */
+    virtual void ObjectDestroyed() = 0;
+
+  protected:
+    /**
+     * Virtual destructor, no deletion through this interface
+     */
+    virtual ~LifecycleObserver() = default;
+  };
+
+
+  /**
    * Constructor.
    */
   AnimatorBase()
-  : mDurationSeconds(1.0f),
-    mInitialDelaySeconds(0.0f),
+  : mLifecycleObserver(nullptr),
+    mDurationSeconds(1.0f),
+    mIntervalDelaySeconds(0.0f),
+    mSpeedFactor(1.0f),
+    mLoopCount(1),
     mAlphaFunction(AlphaFunction::DEFAULT),
     mDisconnectAction(Dali::Animation::BakeFinal),
     mActive(false),
     mEnabled(true),
-    mConnectedToSceneGraph(false)
+    mConnectedToSceneGraph(false),
+    mAutoReverseEnabled( false )
   {
   }
 
@@ -83,6 +106,20 @@ public:
    */
   virtual ~AnimatorBase()
   {
+    if( mLifecycleObserver != nullptr )
+    {
+      mLifecycleObserver->ObjectDestroyed();
+    }
+  }
+
+  void AddLifecycleObserver( LifecycleObserver& observer )
+  {
+    mLifecycleObserver = &observer;
+  }
+
+  void RemoveLifecycleObserver( LifecycleObserver& observer )
+  {
+    mLifecycleObserver = nullptr;
   }
 
   /**
@@ -106,28 +143,62 @@ public:
    * Retrieve the duration of the animator.
    * @return The duration in seconds.
    */
-  float GetDuration()
+  float GetDuration() const
   {
     return mDurationSeconds;
   }
 
+  void SetSpeedFactor( float factor )
+  {
+    mSpeedFactor = factor;
+  }
+
+  void SetLoopCount(int loopCount)
+  {
+    mLoopCount = loopCount;
+  }
+
+  float SetProgress( float progress )
+  {
+    float value = 0.0f;
+
+    if( mAutoReverseEnabled )
+    {
+      if( mSpeedFactor > 0.0f )
+      {
+        value = 1.0f - 2.0f * std::abs( progress - 0.5f );
+      }
+      // Reverse mode
+      else if( mSpeedFactor < 0.0f )
+      {
+        value = 2.0f * std::abs( progress - 0.5f );
+      }
+    }
+    else
+    {
+      value = progress;
+    }
+
+    return value;
+  }
+
   /**
    * Set the delay before the animator should take effect.
    * The default is zero i.e. no delay.
    * @param [in] seconds The delay in seconds.
    */
-  void SetInitialDelay(float seconds)
+  void SetIntervalDelay(float seconds)
   {
-    mInitialDelaySeconds = seconds;
+    mIntervalDelaySeconds = seconds;
   }
 
   /**
-   * Retrieve the initial delay of the animator.
+   * Retrieve the delay before the animator should take effect.
    * @return The delay in seconds.
    */
-  float GetInitialDelay()
+  float GetIntervalDelay() const
   {
-    return mInitialDelaySeconds;
+    return mIntervalDelaySeconds;
   }
 
   /**
@@ -148,7 +219,7 @@ public:
     return mAlphaFunction;
   }
 
-  /*
+  /**
    * Applies the alpha function to the specified progress
    * @param[in] Current progress
    * @return The progress after the alpha function has been aplied
@@ -317,7 +388,7 @@ public:
     return mActive;
   }
 
-  /*
+  /**
    * Retrive wheter the animator's target object is valid and on the stage.
    * @return The enabled state.
    */
@@ -325,6 +396,16 @@ public:
   {
     return mEnabled;
   }
+
+  /**
+   * @brief Sets the looping mode.
+   * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
+   */
+  void SetLoopingMode( bool loopingMode )
+  {
+    mAutoReverseEnabled = loopingMode;
+  }
+
   /**
    * Returns wheter the target object of the animator is still valid
    * or has been destroyed.
@@ -356,8 +437,12 @@ protected:
     return 3.0f*(1.0f-t)*(1.0f-t)*t*p0 + 3.0f*(1.0f-t)*tSquare*p1 + tSquare*t;
   }
 
+  LifecycleObserver* mLifecycleObserver;
   float mDurationSeconds;
-  float mInitialDelaySeconds;
+  float mIntervalDelaySeconds;
+  float mSpeedFactor;
+
+  int mLoopCount;
 
   AlphaFunction mAlphaFunction;
 
@@ -365,6 +450,7 @@ protected:
   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.
   bool mConnectedToSceneGraph:1;                    ///< True if ConnectToSceneGraph() has been called in update-thread.
+  bool mAutoReverseEnabled:1;
 };
 
 /**
@@ -397,7 +483,7 @@ public:
                                                animatorFunction );
 
     animator->SetAlphaFunction( alphaFunction );
-    animator->SetInitialDelay( timePeriod.delaySeconds );
+    animator->SetIntervalDelay( timePeriod.delaySeconds );
     animator->SetDuration( timePeriod.durationSeconds );
 
     return animator;
@@ -462,7 +548,13 @@ public:
    */
   virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
   {
-    float alpha = ApplyAlphaFunction(progress);
+    if( mLoopCount >= 0 )
+    {
+      // Update the progress value
+      progress = SetProgress( progress );
+    }
+
+    float alpha = ApplyAlphaFunction( progress );
 
     const PropertyType& current = mPropertyAccessor.Get( bufferIndex );
 
@@ -550,7 +642,7 @@ public:
                                                animatorFunction );
 
     animator->SetAlphaFunction( alphaFunction );
-    animator->SetInitialDelay( timePeriod.delaySeconds );
+    animator->SetIntervalDelay( timePeriod.delaySeconds );
     animator->SetDuration( timePeriod.durationSeconds );
 
     return animator;
@@ -615,7 +707,13 @@ public:
    */
   virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
   {
-    float alpha = ApplyAlphaFunction(progress);
+    if( mLoopCount >= 0 )
+    {
+      // Update the progress value
+      progress = SetProgress( progress );
+    }
+
+    float alpha = ApplyAlphaFunction( progress );
 
     const T& current = mPropertyAccessor.Get( bufferIndex );
 
@@ -743,6 +841,7 @@ struct AnimateByInteger : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   float operator()(float alpha, const int& property)
   {
     return int(property + mRelative * alpha + 0.5f );
@@ -758,6 +857,7 @@ struct AnimateToInteger : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   float operator()(float alpha, const int& property)
   {
     return int(property + ((mTarget - property) * alpha) + 0.5f);
@@ -773,6 +873,7 @@ struct AnimateByFloat : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   float operator()(float alpha, const float& property)
   {
     return float(property + mRelative * alpha);
@@ -788,6 +889,7 @@ struct AnimateToFloat : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   float operator()(float alpha, const float& property)
   {
     return float(property + ((mTarget - property) * alpha));
@@ -803,6 +905,7 @@ struct AnimateByVector2 : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector2 operator()(float alpha, const Vector2& property)
   {
     return Vector2(property + mRelative * alpha);
@@ -818,6 +921,7 @@ struct AnimateToVector2 : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector2 operator()(float alpha, const Vector2& property)
   {
     return Vector2(property + ((mTarget - property) * alpha));
@@ -833,6 +937,7 @@ struct AnimateByVector3 : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector3 operator()(float alpha, const Vector3& property)
   {
     return Vector3(property + mRelative * alpha);
@@ -848,6 +953,7 @@ struct AnimateToVector3 : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector3 operator()(float alpha, const Vector3& property)
   {
     return Vector3(property + ((mTarget - property) * alpha));
@@ -863,6 +969,7 @@ struct AnimateByVector4 : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector4 operator()(float alpha, const Vector4& property)
   {
     return Vector4(property + mRelative * alpha);
@@ -878,6 +985,7 @@ struct AnimateToVector4 : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector4 operator()(float alpha, const Vector4& property)
   {
     return Vector4(property + ((mTarget - property) * alpha));
@@ -893,6 +1001,7 @@ struct AnimateByOpacity : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector4 operator()(float alpha, const Vector4& property)
   {
     Vector4 result(property);
@@ -911,6 +1020,7 @@ struct AnimateToOpacity : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector4 operator()(float alpha, const Vector4& property)
   {
     Vector4 result(property);
@@ -929,6 +1039,7 @@ struct AnimateByBoolean : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   bool operator()(float alpha, const bool& property)
   {
     // Alpha is not useful here, just keeping to the same template as other update functors
@@ -945,6 +1056,7 @@ struct AnimateToBoolean : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   bool operator()(float alpha, const bool& property)
   {
     // Alpha is not useful here, just keeping to the same template as other update functors
@@ -962,6 +1074,7 @@ struct RotateByAngleAxis : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Quaternion operator()(float alpha, const Quaternion& rotation)
   {
     if (alpha > 0.0f)
@@ -983,6 +1096,7 @@ struct RotateToQuaternion : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Quaternion operator()(float alpha, const Quaternion& rotation)
   {
     return Quaternion::Slerp(rotation, mTarget, alpha);
@@ -999,6 +1113,7 @@ struct KeyFrameBooleanFunctor : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   bool operator()(float progress, const bool& property)
   {
     if(mKeyFrames->IsActive(progress))
@@ -1018,6 +1133,7 @@ struct KeyFrameIntegerFunctor : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   float operator()(float progress, const int& property)
   {
     if(mKeyFrames->IsActive(progress))
@@ -1038,6 +1154,7 @@ struct KeyFrameNumberFunctor : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   float operator()(float progress, const float& property)
   {
     if(mKeyFrames->IsActive(progress))
@@ -1058,6 +1175,7 @@ struct KeyFrameVector2Functor : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector2 operator()(float progress, const Vector2& property)
   {
     if(mKeyFrames->IsActive(progress))
@@ -1079,6 +1197,7 @@ struct KeyFrameVector3Functor : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector3 operator()(float progress, const Vector3& property)
   {
     if(mKeyFrames->IsActive(progress))
@@ -1099,6 +1218,7 @@ struct KeyFrameVector4Functor : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector4 operator()(float progress, const Vector4& property)
   {
     if(mKeyFrames->IsActive(progress))
@@ -1119,6 +1239,7 @@ struct KeyFrameQuaternionFunctor : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Quaternion operator()(float progress, const Quaternion& property)
   {
     if(mKeyFrames->IsActive(progress))
@@ -1138,6 +1259,7 @@ struct PathPositionFunctor : public AnimatorFunctionBase
   {
   }
 
+  using AnimatorFunctionBase::operator();
   Vector3 operator()(float progress, const Vector3& property)
   {
     Vector3 position(property);
@@ -1157,6 +1279,7 @@ struct PathRotationFunctor : public AnimatorFunctionBase
     mForward.Normalize();
   }
 
+  using AnimatorFunctionBase::operator();
   Quaternion operator()(float progress, const Quaternion& property)
   {
     Vector3 tangent;