Merge "Internal animation changes" into 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] disconnectAction The action to perform when the property owner of an animator is disconnected.
71    * @return A new Animation
72    */
73   static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction disconnectAction )
74   {
75     return new Animation( durationSeconds, speedFactor, playRange, isLooping, endAction, disconnectAction );
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 disconnect action of the animation when connected objects are disconnected.
159    * This action is performed during the next update when
160    * the connected object is disconnected.
161    * @param[in] action The disconnect action.
162    */
163   void SetDisconnectAction(EndAction action);
164
165   /**
166    * Retrieve the action performed when the animation is destroyed.
167    * @return The destroy action.
168    */
169   EndAction GetDisconnectAction()
170   {
171     return mDisconnectAction;
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 mEndAction == 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 );
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 disconnectAction );
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    * @param[in] animationFinished True if the animation has finished.
273    */
274   void UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished );
275
276   /**
277    * Helper function to bake the result of the animation when it is stopped or
278    * destroyed.
279    * @param[in] bufferIndex The buffer to update.
280    * @param[in] action The end action specified.
281    */
282   void Bake(BufferIndex bufferIndex, EndAction action );
283
284   /**
285    * Helper function to set active state of animators.
286    * @param[in] active Every animator is set to this state
287    */
288   void SetAnimatorsActive( bool active );
289
290   // Undefined
291   Animation(const Animation&);
292
293   // Undefined
294   Animation& operator=(const Animation& rhs);
295
296 protected:
297
298   float mDurationSeconds;
299   float mSpeedFactor;
300   bool mLooping;
301   EndAction mEndAction;
302   EndAction mDisconnectAction;
303
304   State mState;
305   float mElapsedSeconds;
306   int mPlayCount;
307
308   Vector2 mPlayRange;
309   AnimatorContainer mAnimators;
310 };
311
312 }; //namespace SceneGraph
313
314 // value types used by messages
315 template <> struct ParameterType< Dali::Animation::EndAction > : public BasicType< Dali::Animation::EndAction > {};
316
317 namespace SceneGraph
318 {
319
320 // Messages for Animation
321
322 inline void SetDurationMessage( EventToUpdate& eventToUpdate, const Animation& animation, float durationSeconds )
323 {
324   typedef MessageValue1< Animation, float > LocalType;
325
326   // Reserve some memory inside the message queue
327   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
328
329   // Construct message in the message queue memory; note that delete should not be called on the return value
330   new (slot) LocalType( &animation, &Animation::SetDuration, durationSeconds );
331 }
332
333 inline void SetLoopingMessage( EventToUpdate& eventToUpdate, const Animation& animation, bool looping )
334 {
335   typedef MessageValue1< Animation, bool > LocalType;
336
337   // Reserve some memory inside the message queue
338   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
339
340   // Construct message in the message queue memory; note that delete should not be called on the return value
341   new (slot) LocalType( &animation, &Animation::SetLooping, looping );
342 }
343
344 inline void SetEndActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
345 {
346   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
347
348   // Reserve some memory inside the message queue
349   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
350
351   // Construct message in the message queue memory; note that delete should not be called on the return value
352   new (slot) LocalType( &animation, &Animation::SetEndAction, action );
353 }
354
355 inline void SetDisconnectActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
356 {
357   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
358
359   // Reserve some memory inside the message queue
360   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
361
362   // Construct message in the message queue memory; note that delete should not be called on the return value
363   new (slot) LocalType( &animation, &Animation::SetDisconnectAction, action );
364 }
365
366 inline void SetCurrentProgressMessage( EventToUpdate& eventToUpdate, const Animation& animation, float progress )
367 {
368   typedef MessageValue1< Animation, float > LocalType;
369
370   // Reserve some memory inside the message queue
371   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
372
373   // Construct message in the message queue memory; note that delete should not be called on the return value
374   new (slot) LocalType( &animation, &Animation::SetCurrentProgress, progress );
375 }
376
377 inline void SetSpeedFactorMessage( EventToUpdate& eventToUpdate, const Animation& animation, float factor )
378 {
379   typedef MessageValue1< Animation, float > LocalType;
380
381   // Reserve some memory inside the message queue
382   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
383
384   // Construct message in the message queue memory; note that delete should not be called on the return value
385   new (slot) LocalType( &animation, &Animation::SetSpeedFactor, factor );
386 }
387
388 inline void SetPlayRangeMessage( EventToUpdate& eventToUpdate, const Animation& animation, const Vector2& range )
389 {
390   typedef MessageValue1< Animation, Vector2 > LocalType;
391
392   // Reserve some memory inside the message queue
393   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
394
395   // Construct message in the message queue memory; note that delete should not be called on the return value
396   new (slot) LocalType( &animation, &Animation::SetPlayRange, range );
397 }
398
399 inline void PlayAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
400 {
401   typedef Message< Animation > LocalType;
402
403   // Reserve some memory inside the message queue
404   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
405
406   // Construct message in the message queue memory; note that delete should not be called on the return value
407   new (slot) LocalType( &animation, &Animation::Play );
408 }
409
410 inline void PlayAnimationFromMessage( EventToUpdate& eventToUpdate, const Animation& animation, float progress )
411 {
412   typedef MessageValue1< Animation,float > LocalType;
413
414   // Reserve some memory inside the message queue
415   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
416
417   // Construct message in the message queue memory; note that delete should not be called on the return value
418   new (slot) LocalType( &animation, &Animation::PlayFrom, progress );
419 }
420
421 inline void PauseAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
422 {
423   typedef Message< Animation > LocalType;
424
425   // Reserve some memory inside the message queue
426   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
427
428   // Construct message in the message queue memory; note that delete should not be called on the return value
429   new (slot) LocalType( &animation, &Animation::Pause );
430 }
431
432 inline void AddAnimatorMessage( EventToUpdate& eventToUpdate, const Animation& animation, AnimatorBase& animator )
433 {
434   typedef MessageValue1< Animation, OwnerPointer<AnimatorBase> > LocalType;
435
436   // Reserve some memory inside the message queue
437   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
438
439   // Construct message in the message queue memory; note that delete should not be called on the return value
440   new (slot) LocalType( &animation, &Animation::AddAnimator, &animator );
441 }
442
443
444 } // namespace SceneGraph
445
446 } // namespace Internal
447
448 } // namespace Dali
449
450 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__