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