[dali_1.0.1] 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] isLooping Whether the animation will loop.
67    * @param[in] endAction The action to perform when the animation ends.
68    * @param[in] destroyAction The action to perform when the animation is destroyed.
69    * @return A new Animation
70    */
71   static Animation* New( float durationSeconds, bool isLooping, EndAction endAction, EndAction destroyAction )
72   {
73     return new Animation( durationSeconds, isLooping, endAction, destroyAction );
74   }
75
76   /**
77    * Virtual destructor
78    */
79   virtual ~Animation();
80
81   /**
82    * Set the duration of an animation.
83    * @pre durationSeconds must be greater than zero.
84    * @param[in] durationSeconds The duration in seconds.
85    */
86   void SetDuration(float durationSeconds);
87
88   /**
89    * Retrieve the duration of the animation.
90    * @return The duration in seconds.
91    */
92   float GetDuration() const
93   {
94     return mDurationSeconds;
95   }
96
97   /*
98    * Retrieve the current progress of the animation.
99    * @return The current progress as a normalized value between [0,1].
100    */
101   float GetCurrentProgress() const
102   {
103     if( mDurationSeconds > 0.0f )
104     {
105       return mElapsedSeconds / mDurationSeconds;
106     }
107
108     return 0.0f;
109   }
110
111   /*
112    * Sets the progress of the animation.
113    * @param[in] The new progress as a normalized value between [0,1]
114    */
115   void SetCurrentProgress( float progress )
116   {
117     mElapsedSeconds = mDurationSeconds * progress;
118   }
119
120   /**
121    * Set whether the animation will loop.
122    * @param[in] looping True if the animation will loop.
123    */
124   void SetLooping(bool looping);
125
126   /**
127    * Query whether the animation will loop.
128    * @return True if the animation will loop.
129    */
130   bool IsLooping() const
131   {
132     return mLooping;
133   }
134
135   /**
136    * Set the end action of the animation.
137    * @param[in] action The end action.
138    */
139   void SetEndAction(EndAction action);
140
141   /**
142    * Retrieve the action performed when the animation ends.
143    * @return The end action.
144    */
145   EndAction GetEndAction()
146   {
147     return mEndAction;
148   }
149
150   /**
151    * Set the destroy action of the animation.
152    * This action is performed during the next update when
153    * the animation is destroyed.
154    * @param[in] action The destroy action.
155    */
156   void SetDestroyAction(EndAction action);
157
158   /**
159    * Retrieve the action performed when the animation is destroyed.
160    * @return The destroy action.
161    */
162   EndAction GetDestroyAction()
163   {
164     return mDestroyAction;
165   }
166
167   /**
168    * Play the animation.
169    */
170   void Play();
171
172   /*
173    * Play the animation from a given point
174    * @param[in] progress A value between [0,1] form where the animation should start playing
175    */
176   void PlayFrom( float progress );
177
178   /**
179    * Pause the animation.
180    */
181   void Pause();
182
183   /**
184    * Stop the animation.
185    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
186    * @return True if the animation has finished (otherwise it wasn't playing)
187    */
188   bool Stop(BufferIndex bufferIndex);
189
190   /**
191    * Called shortly before the animation is destroyed.
192    * @param[in] bufferIndex The buffer to update when mDestroyAction == Bake.
193    */
194   void OnDestroy(BufferIndex bufferIndex);
195
196   /**
197    * Query whether the animation is playing, paused or stopped.
198    * Note that even when paused, the Update() method should be called,
199    * since the current progress must be reapplied each frame.
200    */
201   State GetState() const
202   {
203     return mState;
204   }
205
206   /**
207    * Retrive a count of the number of times the animation has been played to completion.
208    * This can be used to emit "Finised" signals from the public-api
209    */
210   int GetPlayCount() const
211   {
212     return mPlayCount;
213   }
214
215   /**
216    * Add a newly created animator.
217    * Animators are automatically removed, when orphaned from an animatable scene object.
218    * @param[in] animator The animator to add.
219    * @param[in] propertyOwner The scene-object that owns the animatable property.
220    * @post The animator is owned by this animation.
221    */
222   void AddAnimator( AnimatorBase* animator, PropertyOwner* propertyOwner );
223
224   /**
225    * Retrieve the animators from an animation.
226    * @return The container of animators.
227    */
228   AnimatorContainer& GetAnimators()
229   {
230     return mAnimators;
231   }
232
233   /**
234    * This causes the animators to change the properties of objects in the scene graph.
235    * @pre The animation is playing or paused.
236    * @param[in] bufferIndex The buffer to update.
237    * @param[in] elapsedSeconds The time elapsed since the previous frame.
238    * @return True if the animation has finished.
239    */
240   bool Update(BufferIndex bufferIndex, float elapsedSeconds);
241
242
243 protected:
244
245   /**
246    * Protected constructor. See New()
247    */
248   Animation( float durationSeconds, bool isLooping, EndAction endAction, EndAction destroyAction );
249
250
251 private:
252
253   /**
254    * Helper for Update, also used to bake when the animation is stopped or destroyed.
255    * @param[in] bufferIndex The buffer to update.
256    * @param[in] bake True if the final result should be baked.
257    */
258   void UpdateAnimators(BufferIndex bufferIndex, bool bake);
259
260   // Undefined
261   Animation(const Animation&);
262
263   // Undefined
264   Animation& operator=(const Animation& rhs);
265
266 protected:
267
268   float mDurationSeconds;
269   bool mLooping;
270   EndAction mEndAction;
271   EndAction mDestroyAction;
272
273   State mState;
274   float mElapsedSeconds;
275   int mPlayCount;
276
277   AnimatorContainer mAnimators;
278 };
279
280 }; //namespace SceneGraph
281
282 // value types used by messages
283 template <> struct ParameterType< Dali::Animation::EndAction > : public BasicType< Dali::Animation::EndAction > {};
284
285 namespace SceneGraph
286 {
287
288 // Messages for Animation
289
290 inline void SetDurationMessage( EventToUpdate& eventToUpdate, const Animation& animation, float durationSeconds )
291 {
292   typedef MessageValue1< Animation, float > LocalType;
293
294   // Reserve some memory inside the message queue
295   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
296
297   // Construct message in the message queue memory; note that delete should not be called on the return value
298   new (slot) LocalType( &animation, &Animation::SetDuration, durationSeconds );
299 }
300
301 inline void SetLoopingMessage( EventToUpdate& eventToUpdate, const Animation& animation, bool looping )
302 {
303   typedef MessageValue1< Animation, bool > LocalType;
304
305   // Reserve some memory inside the message queue
306   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
307
308   // Construct message in the message queue memory; note that delete should not be called on the return value
309   new (slot) LocalType( &animation, &Animation::SetLooping, looping );
310 }
311
312 inline void SetEndActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
313 {
314   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
315
316   // Reserve some memory inside the message queue
317   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
318
319   // Construct message in the message queue memory; note that delete should not be called on the return value
320   new (slot) LocalType( &animation, &Animation::SetEndAction, action );
321 }
322
323 inline void SetDestroyActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
324 {
325   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
326
327   // Reserve some memory inside the message queue
328   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
329
330   // Construct message in the message queue memory; note that delete should not be called on the return value
331   new (slot) LocalType( &animation, &Animation::SetDestroyAction, action );
332 }
333
334 inline void SetCurrentProgressMessage( EventToUpdate& eventToUpdate, const Animation& animation, float progress )
335 {
336   typedef MessageValue1< Animation, float > LocalType;
337
338   // Reserve some memory inside the message queue
339   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
340
341   // Construct message in the message queue memory; note that delete should not be called on the return value
342   new (slot) LocalType( &animation, &Animation::SetCurrentProgress, progress );
343 }
344
345 inline void PlayAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
346 {
347   typedef Message< Animation > LocalType;
348
349   // Reserve some memory inside the message queue
350   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
351
352   // Construct message in the message queue memory; note that delete should not be called on the return value
353   new (slot) LocalType( &animation, &Animation::Play );
354 }
355
356 inline void PlayAnimationFromMessage( EventToUpdate& eventToUpdate, const Animation& animation, float progress )
357 {
358   typedef MessageValue1< Animation,float > LocalType;
359
360   // Reserve some memory inside the message queue
361   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
362
363   // Construct message in the message queue memory; note that delete should not be called on the return value
364   new (slot) LocalType( &animation, &Animation::PlayFrom, progress );
365 }
366
367 inline void PauseAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
368 {
369   typedef Message< Animation > LocalType;
370
371   // Reserve some memory inside the message queue
372   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
373
374   // Construct message in the message queue memory; note that delete should not be called on the return value
375   new (slot) LocalType( &animation, &Animation::Pause );
376 }
377
378 inline void AddAnimatorMessage( EventToUpdate& eventToUpdate, const Animation& animation, AnimatorBase& animator, const PropertyOwner& owner )
379 {
380   typedef MessageValue2< Animation, OwnerPointer<AnimatorBase>, PropertyOwner* > LocalType;
381
382   // Reserve some memory inside the message queue
383   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
384
385   // Construct message in the message queue memory; note that delete should not be called on the return value
386   new (slot) LocalType( &animation, &Animation::AddAnimator, &animator, const_cast<PropertyOwner*>( &owner ) );
387 }
388
389 } // namespace SceneGraph
390
391 } // namespace Internal
392
393 } // namespace Dali
394
395 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__