[dali_1.0.10] Merge branch 'tizen'
[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 #include <dali/internal/update/animation/scene-graph-animator.h>
24 #include <dali/internal/common/buffer-index.h>
25 #include <dali/internal/common/message.h>
26 #include <dali/internal/common/event-to-update.h>
27
28 namespace Dali
29 {
30
31 namespace Internal
32 {
33
34 namespace SceneGraph
35 {
36
37 class Animation;
38
39 typedef OwnerContainer< Animation* > AnimationContainer;
40
41 typedef AnimationContainer::Iterator AnimationIter;
42 typedef AnimationContainer::ConstIterator AnimationConstIter;
43
44 /**
45  * Animations are used to change the properties of scene graph objects, as part of a scene
46  * managers "update" phase. An animation is a container of Animator objects; the actual setting
47  * of object values is done by the animators.
48  */
49 class Animation
50 {
51 public:
52
53   typedef Dali::Animation::EndAction EndAction;
54
55   enum State
56   {
57     Stopped,
58     Playing,
59     Paused,
60     Destroyed
61   };
62
63   /**
64    * Construct a new Animation.
65    * @param[in] durationSeconds The duration of the animation in seconds.
66    * @param[in] speedFactor Multiplier to the animation velocity.
67    * @param[in] playRange Minimum and maximum progress between which the animation will play.
68    * @param[in] isLooping Whether the animation will loop.
69    * @param[in] endAction The action to perform when the animation ends.
70    * @param[in] destroyAction The action to perform when the animation is destroyed.
71    * @return A new Animation
72    */
73   static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction destroyAction )
74   {
75     return new Animation( durationSeconds, speedFactor, playRange, isLooping, endAction, destroyAction );
76   }
77
78   /**
79    * Virtual destructor
80    */
81   virtual ~Animation();
82
83   /**
84    * Set the duration of an animation.
85    * @pre durationSeconds must be greater than zero.
86    * @param[in] durationSeconds The duration in seconds.
87    */
88   void SetDuration(float durationSeconds);
89
90   /**
91    * Retrieve the duration of the animation.
92    * @return The duration in seconds.
93    */
94   float GetDuration() const
95   {
96     return mDurationSeconds;
97   }
98
99   /*
100    * Retrieve the current progress of the animation.
101    * @return The current progress as a normalized value between [0,1].
102    */
103   float GetCurrentProgress() const
104   {
105     if( mDurationSeconds > 0.0f )
106     {
107       return mElapsedSeconds / mDurationSeconds;
108     }
109
110     return 0.0f;
111   }
112
113   /*
114    * Sets the progress of the animation.
115    * @param[in] The new progress as a normalized value between [0,1]
116    */
117   void SetCurrentProgress( float progress )
118   {
119     mElapsedSeconds = mDurationSeconds * progress;
120   }
121
122   void SetSpeedFactor( float factor )
123   {
124     mSpeedFactor = factor;
125   }
126
127   /**
128    * Set whether the animation will loop.
129    * @param[in] looping True if the animation will loop.
130    */
131   void SetLooping(bool looping);
132
133   /**
134    * Query whether the animation will loop.
135    * @return True if the animation will loop.
136    */
137   bool IsLooping() const
138   {
139     return mLooping;
140   }
141
142   /**
143    * Set the end action of the animation.
144    * @param[in] action The end action.
145    */
146   void SetEndAction(EndAction action);
147
148   /**
149    * Retrieve the action performed when the animation ends.
150    * @return The end action.
151    */
152   EndAction GetEndAction()
153   {
154     return mEndAction;
155   }
156
157   /**
158    * Set the destroy action of the animation.
159    * This action is performed during the next update when
160    * the animation is destroyed.
161    * @param[in] action The destroy action.
162    */
163   void SetDestroyAction(EndAction action);
164
165   /**
166    * Retrieve the action performed when the animation is destroyed.
167    * @return The destroy action.
168    */
169   EndAction GetDestroyAction()
170   {
171     return mDestroyAction;
172   }
173
174   /**
175    * Set the playing range. The animation will only play between the minimum and maximum progress
176    * speficied.
177    *
178    * @param[in] range Two values between [0,1] to specify minimum and maximum progress.
179    */
180   void SetPlayRange( const Vector2& range );
181
182   /**
183    * Play the animation.
184    */
185   void Play();
186
187   /*
188    * Play the animation from a given point
189    * @param[in] progress A value between [0,1] form where the animation should start playing
190    */
191   void PlayFrom( float progress );
192
193   /**
194    * Pause the animation.
195    */
196   void Pause();
197
198   /**
199    * Stop the animation.
200    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
201    * @return True if the animation has finished (otherwise it wasn't playing)
202    */
203   bool Stop(BufferIndex bufferIndex);
204
205   /**
206    * Called shortly before the animation is destroyed.
207    * @param[in] bufferIndex The buffer to update when mDestroyAction == Bake.
208    */
209   void OnDestroy(BufferIndex bufferIndex);
210
211   /**
212    * Query whether the animation is playing, paused or stopped.
213    * Note that even when paused, the Update() method should be called,
214    * since the current progress must be reapplied each frame.
215    */
216   State GetState() const
217   {
218     return mState;
219   }
220
221   /**
222    * Retrive a count of the number of times the animation has been played to completion.
223    * This can be used to emit "Finised" signals from the public-api
224    */
225   int GetPlayCount() const
226   {
227     return mPlayCount;
228   }
229
230   /**
231    * Add a newly created animator.
232    * Animators are automatically removed, when orphaned from an animatable scene object.
233    * @param[in] animator The animator to add.
234    * @param[in] propertyOwner The scene-object that owns the animatable property.
235    * @post The animator is owned by this animation.
236    */
237   void AddAnimator( AnimatorBase* animator, PropertyOwner* propertyOwner );
238
239   /**
240    * Retrieve the animators from an animation.
241    * @return The container of animators.
242    */
243   AnimatorContainer& GetAnimators()
244   {
245     return mAnimators;
246   }
247
248   /**
249    * This causes the animators to change the properties of objects in the scene graph.
250    * @pre The animation is playing or paused.
251    * @param[in] bufferIndex The buffer to update.
252    * @param[in] elapsedSeconds The time elapsed since the previous frame.
253    * @return True if the animation has finished.
254    */
255   bool Update(BufferIndex bufferIndex, float elapsedSeconds);
256
257
258 protected:
259
260   /**
261    * Protected constructor. See New()
262    */
263   Animation( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction destroyAction );
264
265
266 private:
267
268   /**
269    * Helper for Update, also used to bake when the animation is stopped or destroyed.
270    * @param[in] bufferIndex The buffer to update.
271    * @param[in] bake True if the final result should be baked.
272    */
273   void UpdateAnimators(BufferIndex bufferIndex, bool bake);
274
275   /**
276    * Helper function to bake the result of the animation when it is stopped or
277    * destroyed.
278    * @param[in] bufferIndex The buffer to update.
279    * @param[in] action The end action specified.
280    */
281   void Bake(BufferIndex bufferIndex, EndAction action );
282
283   // Undefined
284   Animation(const Animation&);
285
286   // Undefined
287   Animation& operator=(const Animation& rhs);
288
289 protected:
290
291   float mDurationSeconds;
292   float mSpeedFactor;
293   bool mLooping;
294   EndAction mEndAction;
295   EndAction mDestroyAction;
296
297   State mState;
298   float mElapsedSeconds;
299   int mPlayCount;
300
301   Vector2 mPlayRange;
302   AnimatorContainer mAnimators;
303 };
304
305 }; //namespace SceneGraph
306
307 // value types used by messages
308 template <> struct ParameterType< Dali::Animation::EndAction > : public BasicType< Dali::Animation::EndAction > {};
309
310 namespace SceneGraph
311 {
312
313 // Messages for Animation
314
315 inline void SetDurationMessage( EventToUpdate& eventToUpdate, const Animation& animation, float durationSeconds )
316 {
317   typedef MessageValue1< Animation, float > LocalType;
318
319   // Reserve some memory inside the message queue
320   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
321
322   // Construct message in the message queue memory; note that delete should not be called on the return value
323   new (slot) LocalType( &animation, &Animation::SetDuration, durationSeconds );
324 }
325
326 inline void SetLoopingMessage( EventToUpdate& eventToUpdate, const Animation& animation, bool looping )
327 {
328   typedef MessageValue1< Animation, bool > LocalType;
329
330   // Reserve some memory inside the message queue
331   unsigned int* slot = eventToUpdate.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::SetLooping, looping );
335 }
336
337 inline void SetEndActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
338 {
339   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
340
341   // Reserve some memory inside the message queue
342   unsigned int* slot = eventToUpdate.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::SetEndAction, action );
346 }
347
348 inline void SetDestroyActionMessage( EventToUpdate& eventToUpdate, 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 = eventToUpdate.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::SetDestroyAction, action );
357 }
358
359 inline void SetCurrentProgressMessage( EventToUpdate& eventToUpdate, const Animation& animation, float progress )
360 {
361   typedef MessageValue1< Animation, float > LocalType;
362
363   // Reserve some memory inside the message queue
364   unsigned int* slot = eventToUpdate.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::SetCurrentProgress, progress );
368 }
369
370 inline void SetSpeedFactorMessage( EventToUpdate& eventToUpdate, const Animation& animation, float factor )
371 {
372   typedef MessageValue1< Animation, float > LocalType;
373
374   // Reserve some memory inside the message queue
375   unsigned int* slot = eventToUpdate.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::SetSpeedFactor, factor );
379 }
380
381 inline void SetPlayRangeMessage( EventToUpdate& eventToUpdate, const Animation& animation, const Vector2& range )
382 {
383   typedef MessageValue1< Animation, Vector2 > LocalType;
384
385   // Reserve some memory inside the message queue
386   unsigned int* slot = eventToUpdate.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::SetPlayRange, range );
390 }
391
392 inline void PlayAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
393 {
394   typedef Message< Animation > LocalType;
395
396   // Reserve some memory inside the message queue
397   unsigned int* slot = eventToUpdate.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::Play );
401 }
402
403 inline void PlayAnimationFromMessage( EventToUpdate& eventToUpdate, const Animation& animation, float progress )
404 {
405   typedef MessageValue1< Animation,float > LocalType;
406
407   // Reserve some memory inside the message queue
408   unsigned int* slot = eventToUpdate.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::PlayFrom, progress );
412 }
413
414 inline void PauseAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
415 {
416   typedef Message< Animation > LocalType;
417
418   // Reserve some memory inside the message queue
419   unsigned int* slot = eventToUpdate.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::Pause );
423 }
424
425 inline void AddAnimatorMessage( EventToUpdate& eventToUpdate, const Animation& animation, AnimatorBase& animator, const PropertyOwner& owner )
426 {
427   typedef MessageValue2< Animation, OwnerPointer<AnimatorBase>, PropertyOwner* > LocalType;
428
429   // Reserve some memory inside the message queue
430   unsigned int* slot = eventToUpdate.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::AddAnimator, &animator, const_cast<PropertyOwner*>( &owner ) );
434 }
435
436 } // namespace SceneGraph
437
438 } // namespace Internal
439
440 } // namespace Dali
441
442 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__