-#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) 2019 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
{
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
{
public:
- typedef Dali::Animation::EndAction EndAction;
+ using EndAction = Dali::Animation::EndAction;
enum State
{
* @param[in] durationSeconds The duration of the animation in seconds.
* @param[in] speedFactor Multiplier to the animation velocity.
* @param[in] playRange Minimum and maximum progress between which the animation will play.
- * @param[in] isLooping Whether the animation will loop.
+ * @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] disconnectAction The action to perform when the property owner of an animator is disconnected.
* @return A new Animation
*/
- static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction disconnectAction )
- {
- return new Animation( durationSeconds, speedFactor, playRange, isLooping, endAction, disconnectAction );
- }
+ static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction );
/**
* Virtual destructor
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.
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.
*/
return mDurationSeconds;
}
- /*
+ /**
* Retrieve the current progress of the animation.
* @return The current progress as a normalized value between [0,1].
*/
return 0.0f;
}
- /*
+ /**
* Sets the progress of the animation.
* @param[in] The new progress as a normalized value between [0,1]
*/
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 whether the animation will loop.
- * @param[in] looping True if the animation will loop.
+ * 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.
*/
bool IsLooping() const
{
- return mLooping;
+ return mLoopCount != 1;
+ }
+
+ /**
+ * Get the loop count
+ * @return the loop count
+ */
+ int32_t GetLoopCount() const
+ {
+ return mLoopCount;
}
/**
*/
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();
* 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;
}
/**
+ * Get the current loop count from zero to GetLoopCount().
+ */
+ int32_t GetCurrentLoop() const
+ {
+ return mCurrentLoop;
+ }
+
+ /**
+ * @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( AnimatorBase* animator );
-
- /**
- * Retrieve the animators from an animation.
- * @return The container of animators.
- */
- AnimatorContainer& GetAnimators()
- {
- return mAnimators;
- }
+ 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:
/**
* Protected constructor. See New()
*/
- Animation( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction disconnectAction );
+ Animation( float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction );
private:
protected:
+ OwnerContainer< AnimatorBase* > mAnimators;
+
+ Vector2 mPlayRange;
+
float mDurationSeconds;
+ float mDelaySeconds;
+ float mElapsedSeconds;
float mSpeedFactor;
- bool mLooping;
+ 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 mDisconnectAction;
State mState;
- float mElapsedSeconds;
- int mPlayCount;
- Vector2 mPlayRange;
- AnimatorContainer mAnimators;
+ bool mProgressReachedSignalRequired; // Flag to indicate the progress marker was hit
+ bool mAutoReverseEnabled; // Flag to identify that the looping mode is auto reverse.
};
}; //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 )
{
- typedef MessageValue1< Animation, bool > 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::SetLooping, looping );
+ new (slot) LocalType( &animation, &Animation::SetProgressNotification, progress );
}
-inline void SetEndActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
+
+inline void SetLoopingMessage( EventThreadServices& eventThreadServices, const Animation& animation, int32_t loopCount )
{
- typedef MessageValue1< Animation, Dali::Animation::EndAction > 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::SetLoopCount, loopCount );
+}
+
+inline void SetEndActionMessage( 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::SetEndAction, action );
}
-inline void SetDisconnectActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
+inline void SetDisconnectActionMessage( 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::SetDisconnectAction, action );
}
-inline void SetCurrentProgressMessage( EventToUpdate& eventToUpdate, const Animation& animation, float progress )
+inline void SetCurrentProgressMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
{
- 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::SetCurrentProgress, progress );
}
-inline void SetSpeedFactorMessage( EventToUpdate& eventToUpdate, const Animation& animation, float factor )
+inline void SetSpeedFactorMessage( EventThreadServices& eventThreadServices, const Animation& animation, float factor )
{
- 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::SetSpeedFactor, factor );
}
-inline void SetPlayRangeMessage( EventToUpdate& eventToUpdate, const Animation& animation, const Vector2& range )
+inline void SetPlayRangeMessage( EventThreadServices& eventThreadServices, const Animation& animation, const Vector2& range )
{
- typedef MessageValue1< Animation, Vector2 > LocalType;
+ using LocalType = MessageValue1< Animation, Vector2 >;
// 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::SetPlayRange, range );
}
-inline void PlayAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
+inline void PlayAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
{
- typedef Message< Animation > LocalType;
+ using LocalType = Message< Animation >;
// 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::Play );
}
-inline void PlayAnimationFromMessage( EventToUpdate& eventToUpdate, const Animation& animation, float progress )
+inline void PlayAnimationFromMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
{
- 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::PlayFrom, progress );
}
-inline void PauseAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
+inline void PauseAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
{
- typedef Message< Animation > LocalType;
+ using LocalType = Message< Animation >;
// 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::Pause );
}
-inline void AddAnimatorMessage( EventToUpdate& eventToUpdate, const Animation& animation, AnimatorBase& animator )
+inline void AddAnimatorMessage( EventThreadServices& eventThreadServices, const Animation& animation, AnimatorBase& animator )
{
- typedef MessageValue1< Animation, OwnerPointer<AnimatorBase> > LocalType;
+ using LocalType = MessageValue1< Animation, OwnerPointer<AnimatorBase> >;
// 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 );
+ 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 )
+{
+ using LocalType = MessageValue1< Animation, bool >;
+
+ // 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::SetLoopingMode, loopingMode );
+}
} // namespace SceneGraph
} // namespace Dali
-#endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H