Use memory pools to allocate nodes, renderers, materials and animations
[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] isLooping Whether the animation will loop.
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, bool isLooping, 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 whether the animation will loop.
133    * @param[in] looping True if the animation will loop.
134    */
135   void SetLooping(bool looping);
136
137   /**
138    * Query whether the animation will loop.
139    * @return True if the animation will loop.
140    */
141   bool IsLooping() const
142   {
143     return mLooping;
144   }
145
146   /**
147    * Set the end action of the animation.
148    * @param[in] action The end action.
149    */
150   void SetEndAction(EndAction action);
151
152   /**
153    * Retrieve the action performed when the animation ends.
154    * @return The end action.
155    */
156   EndAction GetEndAction()
157   {
158     return mEndAction;
159   }
160
161   /**
162    * Set the disconnect action of the animation when connected objects are disconnected.
163    * This action is performed during the next update when
164    * the connected object is disconnected.
165    * @param[in] action The disconnect action.
166    */
167   void SetDisconnectAction(EndAction action);
168
169   /**
170    * Retrieve the action performed when the animation is destroyed.
171    * @return The destroy action.
172    */
173   EndAction GetDisconnectAction()
174   {
175     return mDisconnectAction;
176   }
177
178   /**
179    * Set the playing range. The animation will only play between the minimum and maximum progress
180    * speficied.
181    *
182    * @param[in] range Two values between [0,1] to specify minimum and maximum progress.
183    */
184   void SetPlayRange( const Vector2& range );
185
186   /**
187    * Play the animation.
188    */
189   void Play();
190
191   /*
192    * Play the animation from a given point
193    * @param[in] progress A value between [0,1] form where the animation should start playing
194    */
195   void PlayFrom( float progress );
196
197   /**
198    * Pause the animation.
199    */
200   void Pause();
201
202   /**
203    * Stop the animation.
204    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
205    * @return True if the animation has finished (otherwise it wasn't playing)
206    */
207   bool Stop(BufferIndex bufferIndex);
208
209   /**
210    * Called shortly before the animation is destroyed.
211    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
212    */
213   void OnDestroy(BufferIndex bufferIndex);
214
215   /**
216    * Query whether the animation is playing, paused or stopped.
217    * Note that even when paused, the Update() method should be called,
218    * since the current progress must be reapplied each frame.
219    */
220   State GetState() const
221   {
222     return mState;
223   }
224
225   /**
226    * Retrive a count of the number of times the animation has been played to completion.
227    * This can be used to emit "Finised" signals from the public-api
228    */
229   int GetPlayCount() const
230   {
231     return mPlayCount;
232   }
233
234   /**
235    * Add a newly created animator.
236    * Animators are automatically removed, when orphaned from an animatable scene object.
237    * @param[in] animator The animator to add.
238    * @param[in] propertyOwner The scene-object that owns the animatable property.
239    * @post The animator is owned by this animation.
240    */
241   void AddAnimator( AnimatorBase* animator );
242
243   /**
244    * Retrieve the animators from an animation.
245    * @return The container of animators.
246    */
247   AnimatorContainer& GetAnimators()
248   {
249     return mAnimators;
250   }
251
252   /**
253    * This causes the animators to change the properties of objects in the scene graph.
254    * @pre The animation is playing or paused.
255    * @param[in] bufferIndex The buffer to update.
256    * @param[in] elapsedSeconds The time elapsed since the previous frame.
257    * @return True if the animation has finished.
258    */
259   bool Update(BufferIndex bufferIndex, float elapsedSeconds);
260
261
262 protected:
263
264   /**
265    * Protected constructor. See New()
266    */
267   Animation( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction disconnectAction );
268
269
270 private:
271
272   /**
273    * Helper for Update, also used to bake when the animation is stopped or destroyed.
274    * @param[in] bufferIndex The buffer to update.
275    * @param[in] bake True if the final result should be baked.
276    * @param[in] animationFinished True if the animation has finished.
277    */
278   void UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished );
279
280   /**
281    * Helper function to bake the result of the animation when it is stopped or
282    * destroyed.
283    * @param[in] bufferIndex The buffer to update.
284    * @param[in] action The end action specified.
285    */
286   void Bake(BufferIndex bufferIndex, EndAction action );
287
288   /**
289    * Helper function to set active state of animators.
290    * @param[in] active Every animator is set to this state
291    */
292   void SetAnimatorsActive( bool active );
293
294   // Undefined
295   Animation(const Animation&);
296
297   // Undefined
298   Animation& operator=(const Animation& rhs);
299
300 protected:
301
302   float mDurationSeconds;
303   float mSpeedFactor;
304   bool mLooping;
305   EndAction mEndAction;
306   EndAction mDisconnectAction;
307
308   State mState;
309   float mElapsedSeconds;
310   int mPlayCount;
311
312   Vector2 mPlayRange;
313   AnimatorContainer mAnimators;
314 };
315
316 }; //namespace SceneGraph
317
318 // value types used by messages
319 template <> struct ParameterType< Dali::Animation::EndAction > : public BasicType< Dali::Animation::EndAction > {};
320
321 namespace SceneGraph
322 {
323
324 // Messages for Animation
325
326 inline void SetDurationMessage( EventThreadServices& eventThreadServices, const Animation& animation, float durationSeconds )
327 {
328   typedef MessageValue1< Animation, float > LocalType;
329
330   // Reserve some memory inside the message queue
331   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
332
333   // Construct message in the message queue memory; note that delete should not be called on the return value
334   new (slot) LocalType( &animation, &Animation::SetDuration, durationSeconds );
335 }
336
337 inline void SetLoopingMessage( EventThreadServices& eventThreadServices, const Animation& animation, bool looping )
338 {
339   typedef MessageValue1< Animation, bool > LocalType;
340
341   // Reserve some memory inside the message queue
342   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
343
344   // Construct message in the message queue memory; note that delete should not be called on the return value
345   new (slot) LocalType( &animation, &Animation::SetLooping, looping );
346 }
347
348 inline void SetEndActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
349 {
350   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
351
352   // Reserve some memory inside the message queue
353   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
354
355   // Construct message in the message queue memory; note that delete should not be called on the return value
356   new (slot) LocalType( &animation, &Animation::SetEndAction, action );
357 }
358
359 inline void SetDisconnectActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
360 {
361   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
362
363   // Reserve some memory inside the message queue
364   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
365
366   // Construct message in the message queue memory; note that delete should not be called on the return value
367   new (slot) LocalType( &animation, &Animation::SetDisconnectAction, action );
368 }
369
370 inline void SetCurrentProgressMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
371 {
372   typedef MessageValue1< Animation, float > LocalType;
373
374   // Reserve some memory inside the message queue
375   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
376
377   // Construct message in the message queue memory; note that delete should not be called on the return value
378   new (slot) LocalType( &animation, &Animation::SetCurrentProgress, progress );
379 }
380
381 inline void SetSpeedFactorMessage( EventThreadServices& eventThreadServices, const Animation& animation, float factor )
382 {
383   typedef MessageValue1< Animation, float > 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::SetSpeedFactor, factor );
390 }
391
392 inline void SetPlayRangeMessage( EventThreadServices& eventThreadServices, const Animation& animation, const Vector2& range )
393 {
394   typedef MessageValue1< Animation, Vector2 > 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::SetPlayRange, range );
401 }
402
403 inline void PlayAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
404 {
405   typedef Message< Animation > 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::Play );
412 }
413
414 inline void PlayAnimationFromMessage( 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::PlayFrom, progress );
423 }
424
425 inline void PauseAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
426 {
427   typedef Message< Animation > 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::Pause );
434 }
435
436 inline void AddAnimatorMessage( EventThreadServices& eventThreadServices, const Animation& animation, AnimatorBase& animator )
437 {
438   typedef MessageValue1< Animation, OwnerPointer<AnimatorBase> > 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::AddAnimator, &animator );
445 }
446
447
448 } // namespace SceneGraph
449
450 } // namespace Internal
451
452 } // namespace Dali
453
454 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__