License conversion from Flora to Apache 2.0
[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    * Set whether the animation will loop.
99    * @param[in] looping True if the animation will loop.
100    */
101   void SetLooping(bool looping);
102
103   /**
104    * Query whether the animation will loop.
105    * @return True if the animation will loop.
106    */
107   bool IsLooping() const
108   {
109     return mLooping;
110   }
111
112   /**
113    * Set the end action of the animation.
114    * @param[in] action The end action.
115    */
116   void SetEndAction(EndAction action);
117
118   /**
119    * Retrieve the action performed when the animation ends.
120    * @return The end action.
121    */
122   EndAction GetEndAction()
123   {
124     return mEndAction;
125   }
126
127   /**
128    * Set the destroy action of the animation.
129    * This action is performed during the next update when
130    * the animation is destroyed.
131    * @param[in] action The destroy action.
132    */
133   void SetDestroyAction(EndAction action);
134
135   /**
136    * Retrieve the action performed when the animation is destroyed.
137    * @return The destroy action.
138    */
139   EndAction GetDestroyAction()
140   {
141     return mDestroyAction;
142   }
143
144   /**
145    * Play the animation.
146    */
147   void Play();
148
149   /**
150    * Pause the animation.
151    */
152   void Pause();
153
154   /**
155    * Stop the animation.
156    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
157    * @return True if the animation has finished (otherwise it wasn't playing)
158    */
159   bool Stop(BufferIndex bufferIndex);
160
161   /**
162    * Called shortly before the animation is destroyed.
163    * @param[in] bufferIndex The buffer to update when mDestroyAction == Bake.
164    */
165   void OnDestroy(BufferIndex bufferIndex);
166
167   /**
168    * Query whether the animation is playing, paused or stopped.
169    * Note that even when paused, the Update() method should be called,
170    * since the current progress must be reapplied each frame.
171    */
172   State GetState() const
173   {
174     return mState;
175   }
176
177   /**
178    * Retrive a count of the number of times the animation has been played to completion.
179    * This can be used to emit "Finised" signals from the public-api
180    */
181   int GetPlayCount() const
182   {
183     return mPlayCount;
184   }
185
186   /**
187    * Add a newly created animator.
188    * Animators are automatically removed, when orphaned from an animatable scene object.
189    * @param[in] animator The animator to add.
190    * @param[in] propertyOwner The scene-object that owns the animatable property.
191    * @post The animator is owned by this animation.
192    */
193   void AddAnimator( AnimatorBase* animator, PropertyOwner* propertyOwner );
194
195   /**
196    * Retrieve the animators from an animation.
197    * @return The container of animators.
198    */
199   AnimatorContainer& GetAnimators()
200   {
201     return mAnimators;
202   }
203
204   /**
205    * This causes the animators to change the properties of objects in the scene graph.
206    * @pre The animation is playing or paused.
207    * @param[in] bufferIndex The buffer to update.
208    * @param[in] elapsedSeconds The time elapsed since the previous frame.
209    * @return True if the animation has finished.
210    */
211   bool Update(BufferIndex bufferIndex, float elapsedSeconds);
212
213
214 protected:
215
216   /**
217    * Protected constructor. See New()
218    */
219   Animation( float durationSeconds, bool isLooping, EndAction endAction, EndAction destroyAction );
220
221
222 private:
223
224   /**
225    * Helper for Update, also used to bake when the animation is stopped or destroyed.
226    * @param[in] bufferIndex The buffer to update.
227    * @param[in] bake True if the final result should be baked.
228    */
229   void UpdateAnimators(BufferIndex bufferIndex, bool bake);
230
231   // Undefined
232   Animation(const Animation&);
233
234   // Undefined
235   Animation& operator=(const Animation& rhs);
236
237 protected:
238
239   float mDurationSeconds;
240   bool mLooping;
241   EndAction mEndAction;
242   EndAction mDestroyAction;
243
244   State mState;
245   float mElapsedSeconds;
246   int mPlayCount;
247
248   AnimatorContainer mAnimators;
249 };
250
251 }; //namespace SceneGraph
252
253 // value types used by messages
254 template <> struct ParameterType< Dali::Animation::EndAction > : public BasicType< Dali::Animation::EndAction > {};
255
256 namespace SceneGraph
257 {
258
259 // Messages for Animation
260
261 inline void SetDurationMessage( EventToUpdate& eventToUpdate, const Animation& animation, float durationSeconds )
262 {
263   typedef MessageValue1< Animation, float > LocalType;
264
265   // Reserve some memory inside the message queue
266   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
267
268   // Construct message in the message queue memory; note that delete should not be called on the return value
269   new (slot) LocalType( &animation, &Animation::SetDuration, durationSeconds );
270 }
271
272 inline void SetLoopingMessage( EventToUpdate& eventToUpdate, const Animation& animation, bool looping )
273 {
274   typedef MessageValue1< Animation, bool > LocalType;
275
276   // Reserve some memory inside the message queue
277   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
278
279   // Construct message in the message queue memory; note that delete should not be called on the return value
280   new (slot) LocalType( &animation, &Animation::SetLooping, looping );
281 }
282
283 inline void SetEndActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
284 {
285   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
286
287   // Reserve some memory inside the message queue
288   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
289
290   // Construct message in the message queue memory; note that delete should not be called on the return value
291   new (slot) LocalType( &animation, &Animation::SetEndAction, action );
292 }
293
294 inline void SetDestroyActionMessage( EventToUpdate& eventToUpdate, const Animation& animation, Dali::Animation::EndAction action )
295 {
296   typedef MessageValue1< Animation, Dali::Animation::EndAction > LocalType;
297
298   // Reserve some memory inside the message queue
299   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
300
301   // Construct message in the message queue memory; note that delete should not be called on the return value
302   new (slot) LocalType( &animation, &Animation::SetDestroyAction, action );
303 }
304
305 inline void PlayAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
306 {
307   typedef Message< Animation > LocalType;
308
309   // Reserve some memory inside the message queue
310   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
311
312   // Construct message in the message queue memory; note that delete should not be called on the return value
313   new (slot) LocalType( &animation, &Animation::Play );
314 }
315
316 inline void PauseAnimationMessage( EventToUpdate& eventToUpdate, const Animation& animation )
317 {
318   typedef Message< Animation > LocalType;
319
320   // Reserve some memory inside the message queue
321   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
322
323   // Construct message in the message queue memory; note that delete should not be called on the return value
324   new (slot) LocalType( &animation, &Animation::Pause );
325 }
326
327 inline void AddAnimatorMessage( EventToUpdate& eventToUpdate, const Animation& animation, AnimatorBase& animator, const PropertyOwner& owner )
328 {
329   typedef MessageValue2< Animation, OwnerPointer<AnimatorBase>, PropertyOwner* > LocalType;
330
331   // Reserve some memory inside the message queue
332   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
333
334   // Construct message in the message queue memory; note that delete should not be called on the return value
335   new (slot) LocalType( &animation, &Animation::AddAnimator, &animator, const_cast<PropertyOwner*>( &owner ) );
336 }
337
338 } // namespace SceneGraph
339
340 } // namespace Internal
341
342 } // namespace Dali
343
344 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H__