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