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