Merge "Clean up the code to build successfully on macOS" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-animation.h
index f6f619b..0617041 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
+#define DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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/public-api/animation/animation.h>
-#include <dali/internal/update/animation/scene-graph-animator.h>
+
 #include <dali/internal/common/buffer-index.h>
 #include <dali/internal/common/message.h>
-#include <dali/internal/common/event-to-update.h>
+#include <dali/internal/event/common/event-thread-services.h>
+#include <dali/internal/update/animation/scene-graph-animator.h>
 
 namespace Dali
 {
@@ -34,13 +35,6 @@ namespace Internal
 namespace SceneGraph
 {
 
-class Animation;
-
-typedef OwnerContainer< Animation* > AnimationContainer;
-
-typedef AnimationContainer::Iterator AnimationIter;
-typedef AnimationContainer::ConstIterator AnimationConstIter;
-
 /**
  * Animations are used to change the properties of scene graph objects, as part of a scene
  * managers "update" phase. An animation is a container of Animator objects; the actual setting
@@ -50,7 +44,7 @@ class Animation
 {
 public:
 
-  typedef Dali::Animation::EndAction EndAction;
+  using EndAction = Dali::Animation::EndAction;
 
   enum State
   {
@@ -63,15 +57,14 @@ public:
   /**
    * Construct a new Animation.
    * @param[in] durationSeconds The duration of the animation in seconds.
-   * @param[in] isLooping Whether the animation will loop.
+   * @param[in] speedFactor Multiplier to the animation velocity.
+   * @param[in] playRange Minimum and maximum progress between which the animation will play.
+   * @param[in] loopCount The number of times the animation will loop. ( See SetLoopCount() )
    * @param[in] endAction The action to perform when the animation ends.
-   * @param[in] destroyAction The action to perform when the animation is destroyed.
+   * @param[in] disconnectAction The action to perform when the property owner of an animator is disconnected.
    * @return A new Animation
    */
-  static Animation* New( float durationSeconds, bool isLooping, EndAction endAction, EndAction destroyAction )
-  {
-    return new Animation( durationSeconds, isLooping, endAction, destroyAction );
-  }
+  static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction );
 
   /**
    * Virtual destructor
@@ -79,6 +72,12 @@ public:
   virtual ~Animation();
 
   /**
+   * Overriden delete operator
+   * Deletes the animation from its global memory pool
+   */
+  void operator delete( void* ptr );
+
+  /**
    * Set the duration of an animation.
    * @pre durationSeconds must be greater than zero.
    * @param[in] durationSeconds The duration in seconds.
@@ -86,6 +85,12 @@ public:
   void SetDuration(float durationSeconds);
 
   /**
+   * Set the progress marker to trigger notification
+   * @param[in] progress percent of progress to trigger notification, 0.0f < progress <= 1.0f
+   */
+  void SetProgressNotification( float progress );
+
+  /**
    * Retrieve the duration of the animation.
    * @return The duration in seconds.
    */
@@ -95,10 +100,43 @@ public:
   }
 
   /**
-   * Set whether the animation will loop.
-   * @param[in] looping True if the animation will loop.
+   * Retrieve the current progress of the animation.
+   * @return The current progress as a normalized value between [0,1].
+   */
+  float GetCurrentProgress() const
+  {
+    if( mDurationSeconds > 0.0f )
+    {
+      return mElapsedSeconds / mDurationSeconds;
+    }
+
+    return 0.0f;
+  }
+
+  /**
+   * Sets the progress of the animation.
+   * @param[in] The new progress as a normalized value between [0,1]
+   */
+  void SetCurrentProgress( float progress )
+  {
+    mElapsedSeconds = mDurationSeconds * progress;
+  }
+
+  /**
+   * Specifies a speed factor for the animation.
+   * @param[in] factor A value which will multiply the velocity
+   */
+  void SetSpeedFactor( float factor )
+  {
+    mSpeedFactor = factor;
+  }
+
+  /**
+   * Set the animation loop count.
+   * 0 is loop forever, N loop play N times
+   * @param[in] loopCount The loop count
    */
-  void SetLooping(bool looping);
+  void SetLoopCount(int32_t loopCount);
 
   /**
    * Query whether the animation will loop.
@@ -106,7 +144,16 @@ public:
    */
   bool IsLooping() const
   {
-    return mLooping;
+    return mLoopCount != 1;
+  }
+
+  /**
+   * Get the loop count
+   * @return the loop count
+   */
+  int32_t GetLoopCount() const
+  {
+    return mLoopCount;
   }
 
   /**
@@ -125,28 +172,48 @@ public:
   }
 
   /**
-   * Set the destroy action of the animation.
+   * Set the disconnect action of the animation when connected objects are disconnected.
    * This action is performed during the next update when
-   * the animation is destroyed.
-   * @param[in] action The destroy action.
+   * the connected object is disconnected.
+   * @param[in] action The disconnect action.
    */
-  void SetDestroyAction(EndAction action);
+  void SetDisconnectAction(EndAction action);
 
   /**
    * Retrieve the action performed when the animation is destroyed.
    * @return The destroy action.
    */
-  EndAction GetDestroyAction()
+  EndAction GetDisconnectAction()
   {
-    return mDestroyAction;
+    return mDisconnectAction;
   }
 
   /**
+   * Set the playing range. The animation will only play between the minimum and maximum progress
+   * speficied.
+   *
+   * @param[in] range Two values between [0,1] to specify minimum and maximum progress.
+   */
+  void SetPlayRange( const Vector2& range );
+
+  /**
    * Play the animation.
    */
   void Play();
 
   /**
+   * Play the animation from a given point
+   * @param[in] progress A value between [0,1] form where the animation should start playing
+   */
+  void PlayFrom( float progress );
+
+  /**
+   * @brief Play the animation after a given delay time.
+   * @param[in] delaySeconds The delay time
+   */
+  void PlayAfter( float delaySeconds );
+
+  /**
    * Pause the animation.
    */
   void Pause();
@@ -160,7 +227,7 @@ public:
 
   /**
    * Called shortly before the animation is destroyed.
-   * @param[in] bufferIndex The buffer to update when mDestroyAction == Bake.
+   * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
    */
   void OnDestroy(BufferIndex bufferIndex);
 
@@ -178,37 +245,56 @@ public:
    * Retrive a count of the number of times the animation has been played to completion.
    * This can be used to emit "Finised" signals from the public-api
    */
-  int GetPlayCount() const
+  int32_t GetPlayedCount() const
   {
-    return mPlayCount;
+    return mPlayedCount;
   }
 
   /**
-   * Add a newly created animator.
-   * Animators are automatically removed, when orphaned from an animatable scene object.
-   * @param[in] animator The animator to add.
-   * @param[in] propertyOwner The scene-object that owns the animatable property.
-   * @post The animator is owned by this animation.
+   * Get the current loop count from zero to GetLoopCount().
    */
-  void AddAnimator( AnimatorBase* animator, PropertyOwner* propertyOwner );
+  int32_t GetCurrentLoop() const
+  {
+    return mCurrentLoop;
+  }
 
   /**
-   * Retrieve the animators from an animation.
-   * @return The container of animators.
+   * Query whether the animation is currently active (i.e. at least one of the animators has been updated in either frame)
+   * @return True if the animation is currently active
    */
-  AnimatorContainer& GetAnimators()
+  bool IsActive() const
   {
-    return mAnimators;
+    // As we have double buffering, if animator is updated in either frame, it needs to be rendered.
+    return mIsActive[0] || mIsActive[1];
   }
 
   /**
+   * @brief Sets the looping mode.
+   *
+   * Animation plays forwards and then restarts from the beginning or runs backwards again.
+   * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
+   */
+  void SetLoopingMode( bool loopingMode );
+
+  /**
+   * Add a newly created animator.
+   * Animators are automatically removed, when orphaned from an animatable scene object.
+   * @param[in] animator The animator to add.
+   * @param[in] propertyOwner The scene-object that owns the animatable property.
+   * @post The animator is owned by this animation.
+   */
+  void AddAnimator( OwnerPointer<AnimatorBase>& animator );
+
+  /**
    * This causes the animators to change the properties of objects in the scene graph.
    * @pre The animation is playing or paused.
    * @param[in] bufferIndex The buffer to update.
    * @param[in] elapsedSeconds The time elapsed since the previous frame.
-   * @return True if the animation has finished.
+   * @param[out] looped True if the animation looped
+   * @param[out] finished True if the animation has finished.
+   * @param[out] progressReached True if progress marker reached
    */
-  bool Update(BufferIndex bufferIndex, float elapsedSeconds);
+  void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached );
 
 
 protected:
@@ -216,7 +302,7 @@ protected:
   /**
    * Protected constructor. See New()
    */
-  Animation( float durationSeconds, bool isLooping, EndAction endAction, EndAction destroyAction );
+  Animation( float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction );
 
 
 private:
@@ -225,8 +311,23 @@ private:
    * Helper for Update, also used to bake when the animation is stopped or destroyed.
    * @param[in] bufferIndex The buffer to update.
    * @param[in] bake True if the final result should be baked.
+   * @param[in] animationFinished True if the animation has finished.
    */
-  void UpdateAnimators(BufferIndex bufferIndex, bool bake);
+  void UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished );
+
+  /**
+   * Helper function to bake the result of the animation when it is stopped or
+   * destroyed.
+   * @param[in] bufferIndex The buffer to update.
+   * @param[in] action The end action specified.
+   */
+  void Bake(BufferIndex bufferIndex, EndAction action );
+
+  /**
+   * Helper function to set active state of animators.
+   * @param[in] active Every animator is set to this state
+   */
+  void SetAnimatorsActive( bool active );
 
   // Undefined
   Animation(const Animation&);
@@ -236,16 +337,29 @@ private:
 
 protected:
 
+  OwnerContainer< AnimatorBase* > mAnimators;
+
+  Vector2 mPlayRange;
+
   float mDurationSeconds;
-  bool mLooping;
+  float mDelaySeconds;
+  float mElapsedSeconds;
+  float mSpeedFactor;
+  float mProgressMarker;         // Progress marker to trigger a notification
+
+  int32_t mPlayedCount;              // Incremented at end of animation or completion of all loops
+                                 // Never incremented when looping forever. Event thread tracks to signal end.
+  int32_t mLoopCount;                // N loop setting
+  int32_t mCurrentLoop;              // Current loop number
+
   EndAction mEndAction;
-  EndAction mDestroyAction;
+  EndAction mDisconnectAction;
 
   State mState;
-  float mElapsedSeconds;
-  int mPlayCount;
 
-  AnimatorContainer mAnimators;
+  bool mProgressReachedSignalRequired;  // Flag to indicate the progress marker was hit
+  bool mAutoReverseEnabled;             // Flag to identify that the looping mode is auto reverse.
+  bool mIsActive[2];                    // Flag to indicate whether the animation is active in the current frame (which is double buffered)
 };
 
 }; //namespace SceneGraph
@@ -258,81 +372,160 @@ namespace SceneGraph
 
 // Messages for Animation
 
-inline void SetDurationMessage( EventToUpdate& eventToUpdate, const Animation& animation, float durationSeconds )
+inline void SetDurationMessage( EventThreadServices& eventThreadServices, const Animation& animation, float durationSeconds )
 {
-  typedef MessageValue1< Animation, float > LocalType;
+  using LocalType = MessageValue1< Animation, float >;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.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::SetDuration, durationSeconds );
 }
 
-inline void SetLoopingMessage( EventToUpdate& eventToUpdate, const Animation& animation, bool looping )
+inline void SetProgressNotificationMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
+{
+  using LocalType = MessageValue1< Animation, float >;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.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::SetProgressNotification, progress );
+}
+
+
+inline void SetLoopingMessage( EventThreadServices& eventThreadServices, const Animation& animation, int32_t loopCount )
 {
-  typedef MessageValue1< Animation, bool > LocalType;
+  using LocalType = MessageValue1< Animation, int32_t >;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.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::SetLooping, looping );
+  new (slot) LocalType( &animation, &Animation::SetLoopCount, loopCount );
 }
 
-inline void SetEndActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
+inline void SetEndActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
 {
-  typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
+  using LocalType = MessageValue1< Animation, Dali::Animation::EndAction >;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.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::SetEndAction, action );
 }
 
-inline void SetDestroyActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
+inline void SetDisconnectActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
+{
+  using LocalType = MessageValue1< Animation, Dali::Animation::EndAction >;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.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::SetDisconnectAction, action );
+}
+
+inline void SetCurrentProgressMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
 {
-  typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
+  using LocalType = MessageValue1< Animation, float >;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.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::SetDestroyAction, action );
+  new (slot) LocalType( &animation, &Animation::SetCurrentProgress, progress );
 }
 
-inline void PlayAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
+inline void SetSpeedFactorMessage( EventThreadServices& eventThreadServices, const Animation& animation, float factor )
 {
-  typedef Message< Animation > LocalType;
+  using LocalType = MessageValue1< Animation, float >;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.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::SetSpeedFactor, factor );
+}
+
+inline void SetPlayRangeMessage( EventThreadServices& eventThreadServices, const Animation& animation, const Vector2& range )
+{
+  using LocalType = MessageValue1< Animation, Vector2 >;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.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::SetPlayRange, range );
+}
+
+inline void PlayAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
+{
+  using LocalType = Message< Animation >;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.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::Play );
 }
 
-inline void PauseAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
+inline void PlayAnimationFromMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
 {
-  typedef Message< Animation > LocalType;
+  using LocalType = MessageValue1< Animation, float >;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.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::PlayFrom, progress );
+}
+
+inline void PauseAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
+{
+  using LocalType = Message< Animation >;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.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::Pause );
 }
 
-inline void AddAnimatorMessage( EventToUpdate& eventToUpdate, const Animation& animation, AnimatorBase& animator, const PropertyOwner& owner )
+inline void AddAnimatorMessage( EventThreadServices& eventThreadServices, const Animation& animation, AnimatorBase& animator )
+{
+  using LocalType = MessageValue1< Animation, OwnerPointer<AnimatorBase> >;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  OwnerPointer<AnimatorBase> parameter( &animator );
+  new (slot) LocalType( &animation, &Animation::AddAnimator, parameter );
+}
+
+inline void PlayAfterMessage( EventThreadServices& eventThreadServices, const Animation& animation, float delaySeconds )
+{
+  using LocalType = MessageValue1< Animation, float >;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.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::PlayAfter, delaySeconds );
+}
+
+inline void SetLoopingModeMessage( EventThreadServices& eventThreadServices, const Animation& animation, bool loopingMode )
 {
-  typedef MessageValue2< Animation, OwnerPointer<AnimatorBase>, PropertyOwner* > LocalType;
+  using LocalType = MessageValue1< Animation, bool >;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.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::SetLoopingMode, loopingMode );
 }
 
 } // namespace SceneGraph
@@ -341,4 +534,4 @@ inline void AddAnimatorMessage( EventToUpdate& eventToUpdate, const Animation& a
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H