1 #ifndef DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
2 #define DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
5 * Copyright (c) 2024 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <dali/public-api/animation/animation.h>
24 #include <dali/internal/common/buffer-index.h>
25 #include <dali/internal/common/message.h>
26 #include <dali/internal/event/common/event-thread-services.h>
27 #include <dali/internal/event/common/notifier-interface.h>
28 #include <dali/internal/update/animation/scene-graph-animator.h>
37 * Animations are used to change the properties of scene graph objects, as part of a scene
38 * managers "update" phase. An animation is a container of Animator objects; the actual setting
39 * of object values is done by the animators.
41 class Animation : public NotifierInterface
44 using EndAction = Dali::Animation::EndAction;
55 * Construct a new Animation.
56 * @param[in] durationSeconds The duration of the animation in seconds.
57 * @param[in] speedFactor Multiplier to the animation velocity.
58 * @param[in] playRange Minimum and maximum progress between which the animation will play.
59 * @param[in] loopCount The number of times the animation will loop. ( See SetLoopCount() )
60 * @param[in] endAction The action to perform when the animation ends.
61 * @param[in] disconnectAction The action to perform when the property owner of an animator is disconnected.
62 * @return A new Animation
64 static Animation* New(float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction);
72 * Overriden delete operator
73 * Deletes the animation from its global memory pool
75 void operator delete(void* ptr);
78 * Set the duration of an animation.
79 * @pre durationSeconds must be greater than zero.
80 * @param[in] durationSeconds The duration in seconds.
82 void SetDuration(float durationSeconds);
85 * Set the progress marker to trigger notification
86 * @param[in] progress percent of progress to trigger notification, 0.0f < progress <= 1.0f
88 void SetProgressNotification(float progress);
91 * Retrieve the duration of the animation.
92 * @return The duration in seconds.
94 float GetDuration() const
96 return mDurationSeconds;
100 * Retrieve the current progress of the animation.
101 * @return The current progress as a normalized value between [0,1].
103 float GetCurrentProgress() const
105 if(mDurationSeconds > 0.0f)
107 return mElapsedSeconds / mDurationSeconds;
114 * Sets the progress of the animation.
115 * @param[in] The new progress as a normalized value between [0,1]
117 void SetCurrentProgress(float progress)
119 mElapsedSeconds = mDurationSeconds * progress;
123 * Specifies a speed factor for the animation.
124 * @param[in] factor A value which will multiply the velocity
126 void SetSpeedFactor(float factor)
128 mSpeedFactor = factor;
132 * Set the animation loop count.
133 * 0 is loop forever, N loop play N times
134 * @param[in] loopCount The loop count
136 void SetLoopCount(int32_t loopCount);
139 * Query whether the animation will loop.
140 * @return True if the animation will loop.
142 bool IsLooping() const
144 return mLoopCount != 1;
149 * @return the loop count
151 int32_t GetLoopCount() const
157 * Set the end action of the animation.
158 * @param[in] action The end action.
160 void SetEndAction(EndAction action);
163 * Retrieve the action performed when the animation ends.
164 * @return The end action.
166 EndAction GetEndAction()
172 * Set the disconnect action of the animation when connected objects are disconnected.
173 * This action is performed during the next update when
174 * the connected object is disconnected.
175 * @param[in] action The disconnect action.
177 void SetDisconnectAction(EndAction action);
180 * Retrieve the action performed when the animation is destroyed.
181 * @return The destroy action.
183 EndAction GetDisconnectAction()
185 return mDisconnectAction;
189 * Set the playing range. The animation will only play between the minimum and maximum progress
192 * @param[in] range Two values between [0,1] to specify minimum and maximum progress.
194 void SetPlayRange(const Vector2& range);
197 * @brief Sets the blend point to interpolate animate property
199 * @param[in] blendPoint A value between [0,1], If the value of the keyframe whose progress is 0 is different from the current value,
200 * the property is animated as it smoothly blends until the progress reaches the blendPoint.
201 * @note The blendPoint only affects animation registered with AnimateBetween. Other animations operate the same as when Play() is called.
203 void SetBlendPoint(float blendPoint);
206 * Play the animation.
211 * Play the animation from a given point
212 * @param[in] progress A value between [0,1] form where the animation should start playing
214 void PlayFrom(float progress);
217 * @brief Play the animation after a given delay time.
218 * @param[in] delaySeconds The delay time
220 void PlayAfter(float delaySeconds);
223 * Pause the animation.
228 * Stop the animation.
229 * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
230 * @return True if the animation has finished (otherwise it wasn't playing)
232 bool Stop(BufferIndex bufferIndex);
235 * Clear the animator. It will stop animation, clear all animators, and make this animation never played before.
236 * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
238 void ClearAnimator(BufferIndex bufferIndex);
241 * Called shortly before the animation is destroyed.
242 * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
244 void OnDestroy(BufferIndex bufferIndex);
247 * Query whether the animation is playing, paused or stopped.
248 * Note that even when paused, the Update() method should be called,
249 * since the current progress must be reapplied each frame.
251 State GetState() const
257 * Retrive a count of the number of times the animation has been played to completion.
258 * This can be used to emit "Finised" signals from the public-api
260 int32_t GetPlayedCount() const
266 * Get the current loop count from zero to GetLoopCount().
268 int32_t GetCurrentLoop() const
274 * Query whether the animation is currently active (i.e. at least one of the animators has been updated in either frame)
275 * @return True if the animation is currently active
277 bool IsActive() const
279 // As we have double buffering, if animator is updated in either frame, it needs to be rendered.
280 return mIsActive[0] || mIsActive[1];
284 * @brief Sets the looping mode.
286 * Animation plays forwards and then restarts from the beginning or runs backwards again.
287 * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
289 void SetLoopingMode(bool loopingMode);
292 * Add a newly created animator.
293 * Animators are automatically removed, when orphaned from an animatable scene object.
294 * @param[in] animator The animator to add.
295 * @param[in] propertyOwner The scene-object that owns the animatable property.
296 * @post The animator is owned by this animation.
298 void AddAnimator(OwnerPointer<AnimatorBase>& animator);
301 * This causes the animators to change the properties of objects in the scene graph.
302 * @pre The animation is playing or paused.
303 * @param[in] bufferIndex The buffer to update.
304 * @param[in] elapsedSeconds The time elapsed since the previous frame.
305 * @param[out] stopped True if the animation stopped this loop
306 * @param[out] finished True if the animation has finished.
307 * @param[out] progressReached True if progress marker reached
309 void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& stopped, bool& finished, bool& progressReached);
311 static uint32_t GetMemoryPoolCapacity();
315 * Protected constructor. See New()
317 Animation(float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction);
321 * Helper for Update, also used to bake when the animation is stopped or destroyed.
322 * @param[in] bufferIndex The buffer to update.
323 * @param[in] bake True if the final result should be baked.
324 * @param[in] animationFinished True if the animation has finished.
326 void UpdateAnimators(BufferIndex bufferIndex, bool bake, bool animationFinished);
329 * Helper function to bake the result of the animation when it is stopped or
331 * @param[in] bufferIndex The buffer to update.
332 * @param[in] action The end action specified.
334 void Bake(BufferIndex bufferIndex, EndAction action);
337 * Helper function to set active state of animators.
338 * @param[in] active Every animator is set to this state
340 void SetAnimatorsActive(bool active);
343 Animation(const Animation&);
346 Animation& operator=(const Animation& rhs);
349 OwnerContainer<AnimatorBase*> mAnimators;
353 float mDurationSeconds;
355 float mElapsedSeconds;
357 float mProgressMarker; // Progress marker to trigger a notification
360 int32_t mPlayedCount; // Incremented at end of animation or completion of all loops
361 // Never incremented when looping forever. Event thread tracks to signal end.
362 int32_t mLoopCount; // N loop setting
363 int32_t mCurrentLoop; // Current loop number
365 EndAction mEndAction;
366 EndAction mDisconnectAction;
370 bool mProgressReachedSignalRequired; // Flag to indicate the progress marker was hit
371 bool mAutoReverseEnabled; // Flag to identify that the looping mode is auto reverse.
372 bool mAnimatorSortRequired; // Flag to whether we need to sort animator or not.
373 bool mIsActive[2]; // Flag to indicate whether the animation is active in the current frame (which is double buffered)
375 bool mIsStopped; // Flag to whether this animation call stoped by user at this frame.
378 }; // namespace SceneGraph
380 // value types used by messages
382 struct ParameterType<Dali::Animation::EndAction> : public BasicType<Dali::Animation::EndAction>
388 // Messages for Animation
390 inline void SetDurationMessage(EventThreadServices& eventThreadServices, const Animation& animation, float durationSeconds)
392 using LocalType = MessageValue1<Animation, float>;
394 // Reserve some memory inside the message queue
395 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
397 // Construct message in the message queue memory; note that delete should not be called on the return value
398 new(slot) LocalType(&animation, &Animation::SetDuration, durationSeconds);
401 inline void SetProgressNotificationMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
403 using LocalType = MessageValue1<Animation, float>;
405 // Reserve some memory inside the message queue
406 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
408 // Construct message in the message queue memory; note that delete should not be called on the return value
409 new(slot) LocalType(&animation, &Animation::SetProgressNotification, progress);
412 inline void SetLoopingMessage(EventThreadServices& eventThreadServices, const Animation& animation, int32_t loopCount)
414 using LocalType = MessageValue1<Animation, int32_t>;
416 // Reserve some memory inside the message queue
417 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
419 // Construct message in the message queue memory; note that delete should not be called on the return value
420 new(slot) LocalType(&animation, &Animation::SetLoopCount, loopCount);
423 inline void SetEndActionMessage(EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action)
425 using LocalType = MessageValue1<Animation, Dali::Animation::EndAction>;
427 // Reserve some memory inside the message queue
428 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
430 // Construct message in the message queue memory; note that delete should not be called on the return value
431 new(slot) LocalType(&animation, &Animation::SetEndAction, action);
434 inline void SetDisconnectActionMessage(EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action)
436 using LocalType = MessageValue1<Animation, Dali::Animation::EndAction>;
438 // Reserve some memory inside the message queue
439 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
441 // Construct message in the message queue memory; note that delete should not be called on the return value
442 new(slot) LocalType(&animation, &Animation::SetDisconnectAction, action);
445 inline void SetCurrentProgressMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
447 using LocalType = MessageValue1<Animation, float>;
449 // Reserve some memory inside the message queue
450 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
452 // Construct message in the message queue memory; note that delete should not be called on the return value
453 new(slot) LocalType(&animation, &Animation::SetCurrentProgress, progress);
456 inline void SetSpeedFactorMessage(EventThreadServices& eventThreadServices, const Animation& animation, float factor)
458 using LocalType = MessageValue1<Animation, float>;
460 // Reserve some memory inside the message queue
461 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
463 // Construct message in the message queue memory; note that delete should not be called on the return value
464 new(slot) LocalType(&animation, &Animation::SetSpeedFactor, factor);
467 inline void SetPlayRangeMessage(EventThreadServices& eventThreadServices, const Animation& animation, const Vector2& range)
469 using LocalType = MessageValue1<Animation, Vector2>;
471 // Reserve some memory inside the message queue
472 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
474 // Construct message in the message queue memory; note that delete should not be called on the return value
475 new(slot) LocalType(&animation, &Animation::SetPlayRange, range);
478 inline void SetBlendPointMessage(EventThreadServices& eventThreadServices, const Animation& animation, float blendPoint)
480 using LocalType = MessageValue1<Animation, float>;
482 // Reserve some memory inside the message queue
483 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
485 // Construct message in the message queue memory; note that delete should not be called on the return value
486 new(slot) LocalType(&animation, &Animation::SetBlendPoint, blendPoint);
489 inline void PlayAnimationMessage(EventThreadServices& eventThreadServices, const Animation& animation)
491 using LocalType = Message<Animation>;
493 // Reserve some memory inside the message queue
494 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
496 // Construct message in the message queue memory; note that delete should not be called on the return value
497 new(slot) LocalType(&animation, &Animation::Play);
500 inline void PlayAnimationFromMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
502 using LocalType = MessageValue1<Animation, float>;
504 // Reserve some memory inside the message queue
505 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
507 // Construct message in the message queue memory; note that delete should not be called on the return value
508 new(slot) LocalType(&animation, &Animation::PlayFrom, progress);
511 inline void PauseAnimationMessage(EventThreadServices& eventThreadServices, const Animation& animation)
513 using LocalType = Message<Animation>;
515 // Reserve some memory inside the message queue
516 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
518 // Construct message in the message queue memory; note that delete should not be called on the return value
519 new(slot) LocalType(&animation, &Animation::Pause);
522 inline void AddAnimatorMessage(EventThreadServices& eventThreadServices, const Animation& animation, AnimatorBase& animator)
524 using LocalType = MessageValue1<Animation, OwnerPointer<AnimatorBase> >;
526 // Reserve some memory inside the message queue
527 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
529 // Construct message in the message queue memory; note that delete should not be called on the return value
530 OwnerPointer<AnimatorBase> parameter(&animator);
531 new(slot) LocalType(&animation, &Animation::AddAnimator, parameter);
534 inline void PlayAfterMessage(EventThreadServices& eventThreadServices, const Animation& animation, float delaySeconds)
536 using LocalType = MessageValue1<Animation, float>;
538 // Reserve some memory inside the message queue
539 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
541 // Construct message in the message queue memory; note that delete should not be called on the return value
542 new(slot) LocalType(&animation, &Animation::PlayAfter, delaySeconds);
545 inline void SetLoopingModeMessage(EventThreadServices& eventThreadServices, const Animation& animation, bool loopingMode)
547 using LocalType = MessageValue1<Animation, bool>;
549 // Reserve some memory inside the message queue
550 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
552 // Construct message in the message queue memory; note that delete should not be called on the return value
553 new(slot) LocalType(&animation, &Animation::SetLoopingMode, loopingMode);
556 } // namespace SceneGraph
558 } // namespace Internal
562 #endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H