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