Added Animation loop count
[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) 2014 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    * Retrieve the duration of the animation.
96    * @return The duration in seconds.
97    */
98   float GetDuration() const
99   {
100     return mDurationSeconds;
101   }
102
103   /*
104    * Retrieve the current progress of the animation.
105    * @return The current progress as a normalized value between [0,1].
106    */
107   float GetCurrentProgress() const
108   {
109     if( mDurationSeconds > 0.0f )
110     {
111       return mElapsedSeconds / mDurationSeconds;
112     }
113
114     return 0.0f;
115   }
116
117   /*
118    * Sets the progress of the animation.
119    * @param[in] The new progress as a normalized value between [0,1]
120    */
121   void SetCurrentProgress( float progress )
122   {
123     mElapsedSeconds = mDurationSeconds * progress;
124   }
125
126   void SetSpeedFactor( float factor )
127   {
128     mSpeedFactor = factor;
129   }
130
131   /**
132    * Set the animation loop count.
133    * 0 is loop forever, N loop play N times
134    * @param[in] loopCount The loop count
135    */
136   void SetLoopCount(int loopCount);
137
138   /**
139    * Query whether the animation will loop.
140    * @return True if the animation will loop.
141    */
142   bool IsLooping() const
143   {
144     return mLoopCount != 1;
145   }
146
147   /*
148    * Get the loop count
149    * @return the loop count
150    */
151   int GetLoopCount() const
152   {
153     return mLoopCount;
154   }
155
156   /**
157    * Set the end action of the animation.
158    * @param[in] action The end action.
159    */
160   void SetEndAction(EndAction action);
161
162   /**
163    * Retrieve the action performed when the animation ends.
164    * @return The end action.
165    */
166   EndAction GetEndAction()
167   {
168     return mEndAction;
169   }
170
171   /**
172    * Set the disconnect action of the animation when connected objects are disconnected.
173    * This action is performed during the next update when
174    * the connected object is disconnected.
175    * @param[in] action The disconnect action.
176    */
177   void SetDisconnectAction(EndAction action);
178
179   /**
180    * Retrieve the action performed when the animation is destroyed.
181    * @return The destroy action.
182    */
183   EndAction GetDisconnectAction()
184   {
185     return mDisconnectAction;
186   }
187
188   /**
189    * Set the playing range. The animation will only play between the minimum and maximum progress
190    * speficied.
191    *
192    * @param[in] range Two values between [0,1] to specify minimum and maximum progress.
193    */
194   void SetPlayRange( const Vector2& range );
195
196   /**
197    * Play the animation.
198    */
199   void Play();
200
201   /*
202    * Play the animation from a given point
203    * @param[in] progress A value between [0,1] form where the animation should start playing
204    */
205   void PlayFrom( float progress );
206
207   /**
208    * Pause the animation.
209    */
210   void Pause();
211
212   /**
213    * Stop the animation.
214    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
215    * @return True if the animation has finished (otherwise it wasn't playing)
216    */
217   bool Stop(BufferIndex bufferIndex);
218
219   /**
220    * Called shortly before the animation is destroyed.
221    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
222    */
223   void OnDestroy(BufferIndex bufferIndex);
224
225   /**
226    * Query whether the animation is playing, paused or stopped.
227    * Note that even when paused, the Update() method should be called,
228    * since the current progress must be reapplied each frame.
229    */
230   State GetState() const
231   {
232     return mState;
233   }
234
235   /**
236    * Retrive a count of the number of times the animation has been played to completion.
237    * This can be used to emit "Finised" signals from the public-api
238    */
239   int GetPlayedCount() const
240   {
241     return mPlayedCount;
242   }
243
244   /**
245    * Get the current loop count from zero to GetLoopCount().
246    */
247   int GetCurrentLoop() const
248   {
249     return mCurrentLoop;
250   }
251
252   /**
253    * Add a newly created animator.
254    * Animators are automatically removed, when orphaned from an animatable scene object.
255    * @param[in] animator The animator to add.
256    * @param[in] propertyOwner The scene-object that owns the animatable property.
257    * @post The animator is owned by this animation.
258    */
259   void AddAnimator( AnimatorBase* animator );
260
261   /**
262    * Retrieve the animators from an animation.
263    * @return The container of animators.
264    */
265   AnimatorContainer& GetAnimators()
266   {
267     return mAnimators;
268   }
269
270   /**
271    * This causes the animators to change the properties of objects in the scene graph.
272    * @pre The animation is playing or paused.
273    * @param[in] bufferIndex The buffer to update.
274    * @param[in] elapsedSeconds The time elapsed since the previous frame.
275    * @param[out] looped True if the animation looped
276    * @param[out] finished True if the animation has finished.
277    */
278   void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished );
279
280
281 protected:
282
283   /**
284    * Protected constructor. See New()
285    */
286   Animation( float durationSeconds, float speedFactor, const Vector2& playRange, int loopCount, EndAction endAction, EndAction disconnectAction );
287
288
289 private:
290
291   /**
292    * Helper for Update, also used to bake when the animation is stopped or destroyed.
293    * @param[in] bufferIndex The buffer to update.
294    * @param[in] bake True if the final result should be baked.
295    * @param[in] animationFinished True if the animation has finished.
296    */
297   void UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished );
298
299   /**
300    * Helper function to bake the result of the animation when it is stopped or
301    * destroyed.
302    * @param[in] bufferIndex The buffer to update.
303    * @param[in] action The end action specified.
304    */
305   void Bake(BufferIndex bufferIndex, EndAction action );
306
307   /**
308    * Helper function to set active state of animators.
309    * @param[in] active Every animator is set to this state
310    */
311   void SetAnimatorsActive( bool active );
312
313   // Undefined
314   Animation(const Animation&);
315
316   // Undefined
317   Animation& operator=(const Animation& rhs);
318
319 protected:
320
321   float mDurationSeconds;
322   float mSpeedFactor;
323   EndAction mEndAction;
324   EndAction mDisconnectAction;
325
326   State mState;
327   float mElapsedSeconds;
328   int mPlayedCount;              // Incremented at end of animation or completion of all loops
329                                  // Never incremented when looping forever. Event thread tracks to signal end.
330   int mLoopCount;                // N loop setting
331   int mCurrentLoop;              // Current loop number
332
333   Vector2 mPlayRange;
334   AnimatorContainer mAnimators;
335 };
336
337 }; //namespace SceneGraph
338
339 // value types used by messages
340 template <> struct ParameterType< Dali::Animation::EndAction > : public BasicType< Dali::Animation::EndAction > {};
341
342 namespace SceneGraph
343 {
344
345 // Messages for Animation
346
347 inline void SetDurationMessage( EventThreadServices& eventThreadServices, const Animation& animation, float durationSeconds )
348 {
349   typedef MessageValue1< Animation, float > LocalType;
350
351   // Reserve some memory inside the message queue
352   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
353
354   // Construct message in the message queue memory; note that delete should not be called on the return value
355   new (slot) LocalType( &animation, &Animation::SetDuration, durationSeconds );
356 }
357
358 inline void SetLoopingMessage( EventThreadServices& eventThreadServices, const Animation& animation, int loopCount )
359 {
360   typedef MessageValue1< Animation, int > 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::SetLoopCount, loopCount );
367 }
368
369 inline void SetEndActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
370 {
371   typedef MessageValue1< Animation, Dali::Animation::EndAction > 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::SetEndAction, action );
378 }
379
380 inline void SetDisconnectActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
381 {
382   typedef MessageValue1< Animation, Dali::Animation::EndAction > 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::SetDisconnectAction, action );
389 }
390
391 inline void SetCurrentProgressMessage( 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::SetCurrentProgress, progress );
400 }
401
402 inline void SetSpeedFactorMessage( EventThreadServices& eventThreadServices, const Animation& animation, float factor )
403 {
404   typedef MessageValue1< Animation, float > LocalType;
405
406   // Reserve some memory inside the message queue
407   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
408
409   // Construct message in the message queue memory; note that delete should not be called on the return value
410   new (slot) LocalType( &animation, &Animation::SetSpeedFactor, factor );
411 }
412
413 inline void SetPlayRangeMessage( EventThreadServices& eventThreadServices, const Animation& animation, const Vector2& range )
414 {
415   typedef MessageValue1< Animation, Vector2 > LocalType;
416
417   // Reserve some memory inside the message queue
418   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
419
420   // Construct message in the message queue memory; note that delete should not be called on the return value
421   new (slot) LocalType( &animation, &Animation::SetPlayRange, range );
422 }
423
424 inline void PlayAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
425 {
426   typedef Message< Animation > LocalType;
427
428   // Reserve some memory inside the message queue
429   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
430
431   // Construct message in the message queue memory; note that delete should not be called on the return value
432   new (slot) LocalType( &animation, &Animation::Play );
433 }
434
435 inline void PlayAnimationFromMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
436 {
437   typedef MessageValue1< Animation,float > LocalType;
438
439   // Reserve some memory inside the message queue
440   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
441
442   // Construct message in the message queue memory; note that delete should not be called on the return value
443   new (slot) LocalType( &animation, &Animation::PlayFrom, progress );
444 }
445
446 inline void PauseAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
447 {
448   typedef Message< Animation > LocalType;
449
450   // Reserve some memory inside the message queue
451   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
452
453   // Construct message in the message queue memory; note that delete should not be called on the return value
454   new (slot) LocalType( &animation, &Animation::Pause );
455 }
456
457 inline void AddAnimatorMessage( EventThreadServices& eventThreadServices, const Animation& animation, AnimatorBase& animator )
458 {
459   typedef MessageValue1< Animation, OwnerPointer<AnimatorBase> > LocalType;
460
461   // Reserve some memory inside the message queue
462   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
463
464   // Construct message in the message queue memory; note that delete should not be called on the return value
465   new (slot) LocalType( &animation, &Animation::AddAnimator, &animator );
466 }
467
468
469 } // namespace SceneGraph
470
471 } // namespace Internal
472
473 } // namespace Dali
474
475 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__