Sync UTC harness
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-animation.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
2 #define DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/animation/animation.h>
23
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/update/animation/scene-graph-animator.h>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33 namespace SceneGraph
34 {
35 /**
36  * Animations are used to change the properties of scene graph objects, as part of a scene
37  * managers "update" phase. An animation is a container of Animator objects; the actual setting
38  * of object values is done by the animators.
39  */
40 class Animation
41 {
42 public:
43   using EndAction = Dali::Animation::EndAction;
44
45   enum State
46   {
47     Stopped,
48     Playing,
49     Paused,
50     Destroyed
51   };
52
53   /**
54    * Construct a new Animation.
55    * @param[in] durationSeconds The duration of the animation in seconds.
56    * @param[in] speedFactor Multiplier to the animation velocity.
57    * @param[in] playRange Minimum and maximum progress between which the animation will play.
58    * @param[in] loopCount The number of times the animation will loop. ( See SetLoopCount() )
59    * @param[in] endAction The action to perform when the animation ends.
60    * @param[in] disconnectAction The action to perform when the property owner of an animator is disconnected.
61    * @return A new Animation
62    */
63   static Animation* New(float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction);
64
65   /**
66    * Virtual destructor
67    */
68   virtual ~Animation();
69
70   /**
71    * Overriden delete operator
72    * Deletes the animation from its global memory pool
73    */
74   void operator delete(void* ptr);
75
76   /**
77    * Set the duration of an animation.
78    * @pre durationSeconds must be greater than zero.
79    * @param[in] durationSeconds The duration in seconds.
80    */
81   void SetDuration(float durationSeconds);
82
83   /**
84    * Set the progress marker to trigger notification
85    * @param[in] progress percent of progress to trigger notification, 0.0f < progress <= 1.0f
86    */
87   void SetProgressNotification(float progress);
88
89   /**
90    * Retrieve the duration of the animation.
91    * @return The duration in seconds.
92    */
93   float GetDuration() const
94   {
95     return mDurationSeconds;
96   }
97
98   /**
99    * Retrieve the current progress of the animation.
100    * @return The current progress as a normalized value between [0,1].
101    */
102   float GetCurrentProgress() const
103   {
104     if(mDurationSeconds > 0.0f)
105     {
106       return mElapsedSeconds / mDurationSeconds;
107     }
108
109     return 0.0f;
110   }
111
112   /**
113    * Sets the progress of the animation.
114    * @param[in] The new progress as a normalized value between [0,1]
115    */
116   void SetCurrentProgress(float progress)
117   {
118     mElapsedSeconds = mDurationSeconds * progress;
119   }
120
121   /**
122    * Specifies a speed factor for the animation.
123    * @param[in] factor A value which will multiply the velocity
124    */
125   void SetSpeedFactor(float factor)
126   {
127     mSpeedFactor = factor;
128   }
129
130   /**
131    * Set the animation loop count.
132    * 0 is loop forever, N loop play N times
133    * @param[in] loopCount The loop count
134    */
135   void SetLoopCount(int32_t loopCount);
136
137   /**
138    * Query whether the animation will loop.
139    * @return True if the animation will loop.
140    */
141   bool IsLooping() const
142   {
143     return mLoopCount != 1;
144   }
145
146   /**
147    * Get the loop count
148    * @return the loop count
149    */
150   int32_t GetLoopCount() const
151   {
152     return mLoopCount;
153   }
154
155   /**
156    * Set the end action of the animation.
157    * @param[in] action The end action.
158    */
159   void SetEndAction(EndAction action);
160
161   /**
162    * Retrieve the action performed when the animation ends.
163    * @return The end action.
164    */
165   EndAction GetEndAction()
166   {
167     return mEndAction;
168   }
169
170   /**
171    * Set the disconnect action of the animation when connected objects are disconnected.
172    * This action is performed during the next update when
173    * the connected object is disconnected.
174    * @param[in] action The disconnect action.
175    */
176   void SetDisconnectAction(EndAction action);
177
178   /**
179    * Retrieve the action performed when the animation is destroyed.
180    * @return The destroy action.
181    */
182   EndAction GetDisconnectAction()
183   {
184     return mDisconnectAction;
185   }
186
187   /**
188    * Set the playing range. The animation will only play between the minimum and maximum progress
189    * speficied.
190    *
191    * @param[in] range Two values between [0,1] to specify minimum and maximum progress.
192    */
193   void SetPlayRange(const Vector2& range);
194
195   /**
196    * Play the animation.
197    */
198   void Play();
199
200   /**
201    * Play the animation from a given point
202    * @param[in] progress A value between [0,1] form where the animation should start playing
203    */
204   void PlayFrom(float progress);
205
206   /**
207    * @brief Play the animation after a given delay time.
208    * @param[in] delaySeconds The delay time
209    */
210   void PlayAfter(float delaySeconds);
211
212   /**
213    * Pause the animation.
214    */
215   void Pause();
216
217   /**
218    * Stop the animation.
219    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
220    * @return True if the animation has finished (otherwise it wasn't playing)
221    */
222   bool Stop(BufferIndex bufferIndex);
223
224   /**
225    * Called shortly before the animation is destroyed.
226    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
227    */
228   void OnDestroy(BufferIndex bufferIndex);
229
230   /**
231    * Query whether the animation is playing, paused or stopped.
232    * Note that even when paused, the Update() method should be called,
233    * since the current progress must be reapplied each frame.
234    */
235   State GetState() const
236   {
237     return mState;
238   }
239
240   /**
241    * Retrive a count of the number of times the animation has been played to completion.
242    * This can be used to emit "Finised" signals from the public-api
243    */
244   int32_t GetPlayedCount() const
245   {
246     return mPlayedCount;
247   }
248
249   /**
250    * Get the current loop count from zero to GetLoopCount().
251    */
252   int32_t GetCurrentLoop() const
253   {
254     return mCurrentLoop;
255   }
256
257   /**
258    * Query whether the animation is currently active (i.e. at least one of the animators has been updated in either frame)
259    * @return True if the animation is currently active
260    */
261   bool IsActive() const
262   {
263     // As we have double buffering, if animator is updated in either frame, it needs to be rendered.
264     return mIsActive[0] || mIsActive[1];
265   }
266
267   /**
268    * @brief Sets the looping mode.
269    *
270    * Animation plays forwards and then restarts from the beginning or runs backwards again.
271    * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
272    */
273   void SetLoopingMode(bool loopingMode);
274
275   /**
276    * Add a newly created animator.
277    * Animators are automatically removed, when orphaned from an animatable scene object.
278    * @param[in] animator The animator to add.
279    * @param[in] propertyOwner The scene-object that owns the animatable property.
280    * @post The animator is owned by this animation.
281    */
282   void AddAnimator(OwnerPointer<AnimatorBase>& animator);
283
284   /**
285    * This causes the animators to change the properties of objects in the scene graph.
286    * @pre The animation is playing or paused.
287    * @param[in] bufferIndex The buffer to update.
288    * @param[in] elapsedSeconds The time elapsed since the previous frame.
289    * @param[out] looped True if the animation looped
290    * @param[out] finished True if the animation has finished.
291    * @param[out] progressReached True if progress marker reached
292    */
293   void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached);
294
295 protected:
296   /**
297    * Protected constructor. See New()
298    */
299   Animation(float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction);
300
301 private:
302   /**
303    * Helper for Update, also used to bake when the animation is stopped or destroyed.
304    * @param[in] bufferIndex The buffer to update.
305    * @param[in] bake True if the final result should be baked.
306    * @param[in] animationFinished True if the animation has finished.
307    */
308   void UpdateAnimators(BufferIndex bufferIndex, bool bake, bool animationFinished);
309
310   /**
311    * Helper function to bake the result of the animation when it is stopped or
312    * destroyed.
313    * @param[in] bufferIndex The buffer to update.
314    * @param[in] action The end action specified.
315    */
316   void Bake(BufferIndex bufferIndex, EndAction action);
317
318   /**
319    * Helper function to set active state of animators.
320    * @param[in] active Every animator is set to this state
321    */
322   void SetAnimatorsActive(bool active);
323
324   // Undefined
325   Animation(const Animation&);
326
327   // Undefined
328   Animation& operator=(const Animation& rhs);
329
330 protected:
331   OwnerContainer<AnimatorBase*> mAnimators;
332
333   Vector2 mPlayRange;
334
335   float mDurationSeconds;
336   float mDelaySeconds;
337   float mElapsedSeconds;
338   float mSpeedFactor;
339   float mProgressMarker; // Progress marker to trigger a notification
340
341   int32_t mPlayedCount; // Incremented at end of animation or completion of all loops
342                         // Never incremented when looping forever. Event thread tracks to signal end.
343   int32_t mLoopCount;   // N loop setting
344   int32_t mCurrentLoop; // Current loop number
345
346   EndAction mEndAction;
347   EndAction mDisconnectAction;
348
349   State mState;
350
351   bool mProgressReachedSignalRequired; // Flag to indicate the progress marker was hit
352   bool mAutoReverseEnabled;            // Flag to identify that the looping mode is auto reverse.
353   bool mIsActive[2];                   // Flag to indicate whether the animation is active in the current frame (which is double buffered)
354 };
355
356 }; //namespace SceneGraph
357
358 // value types used by messages
359 template<>
360 struct ParameterType<Dali::Animation::EndAction> : public BasicType<Dali::Animation::EndAction>
361 {
362 };
363
364 namespace SceneGraph
365 {
366 // Messages for Animation
367
368 inline void SetDurationMessage(EventThreadServices& eventThreadServices, const Animation& animation, float durationSeconds)
369 {
370   using LocalType = MessageValue1<Animation, float>;
371
372   // Reserve some memory inside the message queue
373   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
374
375   // Construct message in the message queue memory; note that delete should not be called on the return value
376   new(slot) LocalType(&animation, &Animation::SetDuration, durationSeconds);
377 }
378
379 inline void SetProgressNotificationMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
380 {
381   using LocalType = MessageValue1<Animation, float>;
382
383   // Reserve some memory inside the message queue
384   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
385
386   // Construct message in the message queue memory; note that delete should not be called on the return value
387   new(slot) LocalType(&animation, &Animation::SetProgressNotification, progress);
388 }
389
390 inline void SetLoopingMessage(EventThreadServices& eventThreadServices, const Animation& animation, int32_t loopCount)
391 {
392   using LocalType = MessageValue1<Animation, int32_t>;
393
394   // Reserve some memory inside the message queue
395   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
396
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::SetLoopCount, loopCount);
399 }
400
401 inline void SetEndActionMessage(EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action)
402 {
403   using LocalType = MessageValue1<Animation, Dali::Animation::EndAction>;
404
405   // Reserve some memory inside the message queue
406   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
407
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::SetEndAction, action);
410 }
411
412 inline void SetDisconnectActionMessage(EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action)
413 {
414   using LocalType = MessageValue1<Animation, Dali::Animation::EndAction>;
415
416   // Reserve some memory inside the message queue
417   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
418
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::SetDisconnectAction, action);
421 }
422
423 inline void SetCurrentProgressMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
424 {
425   using LocalType = MessageValue1<Animation, float>;
426
427   // Reserve some memory inside the message queue
428   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
429
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::SetCurrentProgress, progress);
432 }
433
434 inline void SetSpeedFactorMessage(EventThreadServices& eventThreadServices, const Animation& animation, float factor)
435 {
436   using LocalType = MessageValue1<Animation, float>;
437
438   // Reserve some memory inside the message queue
439   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
440
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::SetSpeedFactor, factor);
443 }
444
445 inline void SetPlayRangeMessage(EventThreadServices& eventThreadServices, const Animation& animation, const Vector2& range)
446 {
447   using LocalType = MessageValue1<Animation, Vector2>;
448
449   // Reserve some memory inside the message queue
450   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
451
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::SetPlayRange, range);
454 }
455
456 inline void PlayAnimationMessage(EventThreadServices& eventThreadServices, const Animation& animation)
457 {
458   using LocalType = Message<Animation>;
459
460   // Reserve some memory inside the message queue
461   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
462
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::Play);
465 }
466
467 inline void PlayAnimationFromMessage(EventThreadServices& eventThreadServices, const Animation& animation, float progress)
468 {
469   using LocalType = MessageValue1<Animation, float>;
470
471   // Reserve some memory inside the message queue
472   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
473
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::PlayFrom, progress);
476 }
477
478 inline void PauseAnimationMessage(EventThreadServices& eventThreadServices, const Animation& animation)
479 {
480   using LocalType = Message<Animation>;
481
482   // Reserve some memory inside the message queue
483   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
484
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::Pause);
487 }
488
489 inline void AddAnimatorMessage(EventThreadServices& eventThreadServices, const Animation& animation, AnimatorBase& animator)
490 {
491   using LocalType = MessageValue1<Animation, OwnerPointer<AnimatorBase> >;
492
493   // Reserve some memory inside the message queue
494   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
495
496   // Construct message in the message queue memory; note that delete should not be called on the return value
497   OwnerPointer<AnimatorBase> parameter(&animator);
498   new(slot) LocalType(&animation, &Animation::AddAnimator, parameter);
499 }
500
501 inline void PlayAfterMessage(EventThreadServices& eventThreadServices, const Animation& animation, float delaySeconds)
502 {
503   using LocalType = MessageValue1<Animation, float>;
504
505   // Reserve some memory inside the message queue
506   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
507
508   // Construct message in the message queue memory; note that delete should not be called on the return value
509   new(slot) LocalType(&animation, &Animation::PlayAfter, delaySeconds);
510 }
511
512 inline void SetLoopingModeMessage(EventThreadServices& eventThreadServices, const Animation& animation, bool loopingMode)
513 {
514   using LocalType = MessageValue1<Animation, bool>;
515
516   // Reserve some memory inside the message queue
517   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
518
519   // Construct message in the message queue memory; note that delete should not be called on the return value
520   new(slot) LocalType(&animation, &Animation::SetLoopingMode, loopingMode);
521 }
522
523 } // namespace SceneGraph
524
525 } // namespace Internal
526
527 } // namespace Dali
528
529 #endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H