4f2095eadbd40d5acfa5b18e30f1f9c34266de7c
[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    * Pause the animation.
215    */
216   void Pause();
217
218   /**
219    * Stop the animation.
220    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
221    * @return True if the animation has finished (otherwise it wasn't playing)
222    */
223   bool Stop(BufferIndex bufferIndex);
224
225   /**
226    * Called shortly before the animation is destroyed.
227    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
228    */
229   void OnDestroy(BufferIndex bufferIndex);
230
231   /**
232    * Query whether the animation is playing, paused or stopped.
233    * Note that even when paused, the Update() method should be called,
234    * since the current progress must be reapplied each frame.
235    */
236   State GetState() const
237   {
238     return mState;
239   }
240
241   /**
242    * Retrive a count of the number of times the animation has been played to completion.
243    * This can be used to emit "Finised" signals from the public-api
244    */
245   int GetPlayedCount() const
246   {
247     return mPlayedCount;
248   }
249
250   /**
251    * Get the current loop count from zero to GetLoopCount().
252    */
253   int GetCurrentLoop() const
254   {
255     return mCurrentLoop;
256   }
257
258   /**
259    * Add a newly created animator.
260    * Animators are automatically removed, when orphaned from an animatable scene object.
261    * @param[in] animator The animator to add.
262    * @param[in] propertyOwner The scene-object that owns the animatable property.
263    * @post The animator is owned by this animation.
264    */
265   void AddAnimator( OwnerPointer<AnimatorBase>& animator );
266
267   /**
268    * Retrieve the animators from an animation.
269    * @return The container of animators.
270    */
271   AnimatorContainer& GetAnimators()
272   {
273     return mAnimators;
274   }
275
276   /**
277    * This causes the animators to change the properties of objects in the scene graph.
278    * @pre The animation is playing or paused.
279    * @param[in] bufferIndex The buffer to update.
280    * @param[in] elapsedSeconds The time elapsed since the previous frame.
281    * @param[out] looped True if the animation looped
282    * @param[out] finished True if the animation has finished.
283    * @param[out] progressReached True if progress marker reached
284    */
285   void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached );
286
287
288 protected:
289
290   /**
291    * Protected constructor. See New()
292    */
293   Animation( float durationSeconds, float speedFactor, const Vector2& playRange, int loopCount, EndAction endAction, EndAction disconnectAction );
294
295
296 private:
297
298   /**
299    * Helper for Update, also used to bake when the animation is stopped or destroyed.
300    * @param[in] bufferIndex The buffer to update.
301    * @param[in] bake True if the final result should be baked.
302    * @param[in] animationFinished True if the animation has finished.
303    */
304   void UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished );
305
306   /**
307    * Helper function to bake the result of the animation when it is stopped or
308    * destroyed.
309    * @param[in] bufferIndex The buffer to update.
310    * @param[in] action The end action specified.
311    */
312   void Bake(BufferIndex bufferIndex, EndAction action );
313
314   /**
315    * Helper function to set active state of animators.
316    * @param[in] active Every animator is set to this state
317    */
318   void SetAnimatorsActive( bool active );
319
320   // Undefined
321   Animation(const Animation&);
322
323   // Undefined
324   Animation& operator=(const Animation& rhs);
325
326 protected:
327
328   float mDurationSeconds;
329   float mSpeedFactor;
330   EndAction mEndAction;
331   EndAction mDisconnectAction;
332
333   State mState;
334   float mElapsedSeconds;
335   int mPlayedCount;              // Incremented at end of animation or completion of all loops
336                                  // Never incremented when looping forever. Event thread tracks to signal end.
337   int mLoopCount;                // N loop setting
338   int mCurrentLoop;              // Current loop number
339
340   Vector2 mPlayRange;
341
342   float mProgressMarker;                // Progress marker to trigger a notification
343   bool mProgressReachedSignalRequired;  // Flag to indicate the progress marker was hit
344
345   AnimatorContainer mAnimators;
346 };
347
348 }; //namespace SceneGraph
349
350 // value types used by messages
351 template <> struct ParameterType< Dali::Animation::EndAction > : public BasicType< Dali::Animation::EndAction > {};
352
353 namespace SceneGraph
354 {
355
356 // Messages for Animation
357
358 inline void SetDurationMessage( EventThreadServices& eventThreadServices, const Animation& animation, float durationSeconds )
359 {
360   typedef MessageValue1< Animation, float > LocalType;
361
362   // Reserve some memory inside the message queue
363   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
364
365   // Construct message in the message queue memory; note that delete should not be called on the return value
366   new (slot) LocalType( &animation, &Animation::SetDuration, durationSeconds );
367 }
368
369 inline void SetProgressNotificationMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
370 {
371   typedef MessageValue1< Animation, float > LocalType;
372
373   // Reserve some memory inside the message queue
374   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
375
376   // Construct message in the message queue memory; note that delete should not be called on the return value
377   new (slot) LocalType( &animation, &Animation::SetProgressNotification, progress );
378 }
379
380
381 inline void SetLoopingMessage( EventThreadServices& eventThreadServices, const Animation& animation, int loopCount )
382 {
383   typedef MessageValue1< Animation, int > LocalType;
384
385   // Reserve some memory inside the message queue
386   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
387
388   // Construct message in the message queue memory; note that delete should not be called on the return value
389   new (slot) LocalType( &animation, &Animation::SetLoopCount, loopCount );
390 }
391
392 inline void SetEndActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
393 {
394   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
395
396   // Reserve some memory inside the message queue
397   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
398
399   // Construct message in the message queue memory; note that delete should not be called on the return value
400   new (slot) LocalType( &animation, &Animation::SetEndAction, action );
401 }
402
403 inline void SetDisconnectActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
404 {
405   typedef MessageValue1< Animation, Dali::Animation::EndAction > 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::SetDisconnectAction, action );
412 }
413
414 inline void SetCurrentProgressMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
415 {
416   typedef MessageValue1< Animation, float > 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::SetCurrentProgress, progress );
423 }
424
425 inline void SetSpeedFactorMessage( EventThreadServices& eventThreadServices, const Animation& animation, float factor )
426 {
427   typedef MessageValue1< Animation, float > 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::SetSpeedFactor, factor );
434 }
435
436 inline void SetPlayRangeMessage( EventThreadServices& eventThreadServices, const Animation& animation, const Vector2& range )
437 {
438   typedef MessageValue1< Animation, Vector2 > 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::SetPlayRange, range );
445 }
446
447 inline void PlayAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
448 {
449   typedef Message< Animation > 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::Play );
456 }
457
458 inline void PlayAnimationFromMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
459 {
460   typedef MessageValue1< Animation,float > 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::PlayFrom, progress );
467 }
468
469 inline void PauseAnimationMessage( 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::Pause );
478 }
479
480 inline void AddAnimatorMessage( EventThreadServices& eventThreadServices, const Animation& animation, AnimatorBase& animator )
481 {
482   typedef MessageValue1< Animation, OwnerPointer<AnimatorBase> > 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   OwnerPointer<AnimatorBase> parameter( &animator );
489   new (slot) LocalType( &animation, &Animation::AddAnimator, parameter );
490 }
491
492
493 } // namespace SceneGraph
494
495 } // namespace Internal
496
497 } // namespace Dali
498
499 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__