Merge "Clean up the code to build successfully on macOS" into devel/master
[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) 2020 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 /**
39  * Animations are used to change the properties of scene graph objects, as part of a scene
40  * managers "update" phase. An animation is a container of Animator objects; the actual setting
41  * of object values is done by the animators.
42  */
43 class Animation
44 {
45 public:
46
47   using EndAction = Dali::Animation::EndAction;
48
49   enum State
50   {
51     Stopped,
52     Playing,
53     Paused,
54     Destroyed
55   };
56
57   /**
58    * Construct a new Animation.
59    * @param[in] durationSeconds The duration of the animation in seconds.
60    * @param[in] speedFactor Multiplier to the animation velocity.
61    * @param[in] playRange Minimum and maximum progress between which the animation will play.
62    * @param[in] loopCount The number of times the animation will loop. ( See SetLoopCount() )
63    * @param[in] endAction The action to perform when the animation ends.
64    * @param[in] disconnectAction The action to perform when the property owner of an animator is disconnected.
65    * @return A new Animation
66    */
67   static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction );
68
69   /**
70    * Virtual destructor
71    */
72   virtual ~Animation();
73
74   /**
75    * Overriden delete operator
76    * Deletes the animation from its global memory pool
77    */
78   void operator delete( void* ptr );
79
80   /**
81    * Set the duration of an animation.
82    * @pre durationSeconds must be greater than zero.
83    * @param[in] durationSeconds The duration in seconds.
84    */
85   void SetDuration(float durationSeconds);
86
87   /**
88    * Set the progress marker to trigger notification
89    * @param[in] progress percent of progress to trigger notification, 0.0f < progress <= 1.0f
90    */
91   void SetProgressNotification( float progress );
92
93   /**
94    * Retrieve the duration of the animation.
95    * @return The duration in seconds.
96    */
97   float GetDuration() const
98   {
99     return mDurationSeconds;
100   }
101
102   /**
103    * Retrieve the current progress of the animation.
104    * @return The current progress as a normalized value between [0,1].
105    */
106   float GetCurrentProgress() const
107   {
108     if( mDurationSeconds > 0.0f )
109     {
110       return mElapsedSeconds / mDurationSeconds;
111     }
112
113     return 0.0f;
114   }
115
116   /**
117    * Sets the progress of the animation.
118    * @param[in] The new progress as a normalized value between [0,1]
119    */
120   void SetCurrentProgress( float progress )
121   {
122     mElapsedSeconds = mDurationSeconds * progress;
123   }
124
125   /**
126    * Specifies a speed factor for the animation.
127    * @param[in] factor A value which will multiply the velocity
128    */
129   void SetSpeedFactor( float factor )
130   {
131     mSpeedFactor = factor;
132   }
133
134   /**
135    * Set the animation loop count.
136    * 0 is loop forever, N loop play N times
137    * @param[in] loopCount The loop count
138    */
139   void SetLoopCount(int32_t loopCount);
140
141   /**
142    * Query whether the animation will loop.
143    * @return True if the animation will loop.
144    */
145   bool IsLooping() const
146   {
147     return mLoopCount != 1;
148   }
149
150   /**
151    * Get the loop count
152    * @return the loop count
153    */
154   int32_t GetLoopCount() const
155   {
156     return mLoopCount;
157   }
158
159   /**
160    * Set the end action of the animation.
161    * @param[in] action The end action.
162    */
163   void SetEndAction(EndAction action);
164
165   /**
166    * Retrieve the action performed when the animation ends.
167    * @return The end action.
168    */
169   EndAction GetEndAction()
170   {
171     return mEndAction;
172   }
173
174   /**
175    * Set the disconnect action of the animation when connected objects are disconnected.
176    * This action is performed during the next update when
177    * the connected object is disconnected.
178    * @param[in] action The disconnect action.
179    */
180   void SetDisconnectAction(EndAction action);
181
182   /**
183    * Retrieve the action performed when the animation is destroyed.
184    * @return The destroy action.
185    */
186   EndAction GetDisconnectAction()
187   {
188     return mDisconnectAction;
189   }
190
191   /**
192    * Set the playing range. The animation will only play between the minimum and maximum progress
193    * speficied.
194    *
195    * @param[in] range Two values between [0,1] to specify minimum and maximum progress.
196    */
197   void SetPlayRange( const Vector2& range );
198
199   /**
200    * Play the animation.
201    */
202   void Play();
203
204   /**
205    * Play the animation from a given point
206    * @param[in] progress A value between [0,1] form where the animation should start playing
207    */
208   void PlayFrom( float progress );
209
210   /**
211    * @brief Play the animation after a given delay time.
212    * @param[in] delaySeconds The delay time
213    */
214   void PlayAfter( float delaySeconds );
215
216   /**
217    * Pause the animation.
218    */
219   void Pause();
220
221   /**
222    * Stop the animation.
223    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
224    * @return True if the animation has finished (otherwise it wasn't playing)
225    */
226   bool Stop(BufferIndex bufferIndex);
227
228   /**
229    * Called shortly before the animation is destroyed.
230    * @param[in] bufferIndex The buffer to update when mEndAction == Bake.
231    */
232   void OnDestroy(BufferIndex bufferIndex);
233
234   /**
235    * Query whether the animation is playing, paused or stopped.
236    * Note that even when paused, the Update() method should be called,
237    * since the current progress must be reapplied each frame.
238    */
239   State GetState() const
240   {
241     return mState;
242   }
243
244   /**
245    * Retrive a count of the number of times the animation has been played to completion.
246    * This can be used to emit "Finised" signals from the public-api
247    */
248   int32_t GetPlayedCount() const
249   {
250     return mPlayedCount;
251   }
252
253   /**
254    * Get the current loop count from zero to GetLoopCount().
255    */
256   int32_t GetCurrentLoop() const
257   {
258     return mCurrentLoop;
259   }
260
261   /**
262    * Query whether the animation is currently active (i.e. at least one of the animators has been updated in either frame)
263    * @return True if the animation is currently active
264    */
265   bool IsActive() const
266   {
267     // As we have double buffering, if animator is updated in either frame, it needs to be rendered.
268     return mIsActive[0] || mIsActive[1];
269   }
270
271   /**
272    * @brief Sets the looping mode.
273    *
274    * Animation plays forwards and then restarts from the beginning or runs backwards again.
275    * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
276    */
277   void SetLoopingMode( bool loopingMode );
278
279   /**
280    * Add a newly created animator.
281    * Animators are automatically removed, when orphaned from an animatable scene object.
282    * @param[in] animator The animator to add.
283    * @param[in] propertyOwner The scene-object that owns the animatable property.
284    * @post The animator is owned by this animation.
285    */
286   void AddAnimator( OwnerPointer<AnimatorBase>& animator );
287
288   /**
289    * This causes the animators to change the properties of objects in the scene graph.
290    * @pre The animation is playing or paused.
291    * @param[in] bufferIndex The buffer to update.
292    * @param[in] elapsedSeconds The time elapsed since the previous frame.
293    * @param[out] looped True if the animation looped
294    * @param[out] finished True if the animation has finished.
295    * @param[out] progressReached True if progress marker reached
296    */
297   void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached );
298
299
300 protected:
301
302   /**
303    * Protected constructor. See New()
304    */
305   Animation( float durationSeconds, float speedFactor, const Vector2& playRange, int32_t loopCount, EndAction endAction, EndAction disconnectAction );
306
307
308 private:
309
310   /**
311    * Helper for Update, also used to bake when the animation is stopped or destroyed.
312    * @param[in] bufferIndex The buffer to update.
313    * @param[in] bake True if the final result should be baked.
314    * @param[in] animationFinished True if the animation has finished.
315    */
316   void UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished );
317
318   /**
319    * Helper function to bake the result of the animation when it is stopped or
320    * destroyed.
321    * @param[in] bufferIndex The buffer to update.
322    * @param[in] action The end action specified.
323    */
324   void Bake(BufferIndex bufferIndex, EndAction action );
325
326   /**
327    * Helper function to set active state of animators.
328    * @param[in] active Every animator is set to this state
329    */
330   void SetAnimatorsActive( bool active );
331
332   // Undefined
333   Animation(const Animation&);
334
335   // Undefined
336   Animation& operator=(const Animation& rhs);
337
338 protected:
339
340   OwnerContainer< AnimatorBase* > mAnimators;
341
342   Vector2 mPlayRange;
343
344   float mDurationSeconds;
345   float mDelaySeconds;
346   float mElapsedSeconds;
347   float mSpeedFactor;
348   float mProgressMarker;         // Progress marker to trigger a notification
349
350   int32_t mPlayedCount;              // Incremented at end of animation or completion of all loops
351                                  // Never incremented when looping forever. Event thread tracks to signal end.
352   int32_t mLoopCount;                // N loop setting
353   int32_t mCurrentLoop;              // Current loop number
354
355   EndAction mEndAction;
356   EndAction mDisconnectAction;
357
358   State mState;
359
360   bool mProgressReachedSignalRequired;  // Flag to indicate the progress marker was hit
361   bool mAutoReverseEnabled;             // Flag to identify that the looping mode is auto reverse.
362   bool mIsActive[2];                    // Flag to indicate whether the animation is active in the current frame (which is double buffered)
363 };
364
365 }; //namespace SceneGraph
366
367 // value types used by messages
368 template <> struct ParameterType< Dali::Animation::EndAction > : public BasicType< Dali::Animation::EndAction > {};
369
370 namespace SceneGraph
371 {
372
373 // Messages for Animation
374
375 inline void SetDurationMessage( EventThreadServices& eventThreadServices, const Animation& animation, float durationSeconds )
376 {
377   using LocalType = MessageValue1< Animation, float >;
378
379   // Reserve some memory inside the message queue
380   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
381
382   // Construct message in the message queue memory; note that delete should not be called on the return value
383   new (slot) LocalType( &animation, &Animation::SetDuration, durationSeconds );
384 }
385
386 inline void SetProgressNotificationMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
387 {
388   using LocalType = MessageValue1< Animation, float >;
389
390   // Reserve some memory inside the message queue
391   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
392
393   // Construct message in the message queue memory; note that delete should not be called on the return value
394   new (slot) LocalType( &animation, &Animation::SetProgressNotification, progress );
395 }
396
397
398 inline void SetLoopingMessage( EventThreadServices& eventThreadServices, const Animation& animation, int32_t loopCount )
399 {
400   using LocalType = MessageValue1< Animation, int32_t >;
401
402   // Reserve some memory inside the message queue
403   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
404
405   // Construct message in the message queue memory; note that delete should not be called on the return value
406   new (slot) LocalType( &animation, &Animation::SetLoopCount, loopCount );
407 }
408
409 inline void SetEndActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
410 {
411   using LocalType = MessageValue1< Animation, Dali::Animation::EndAction >;
412
413   // Reserve some memory inside the message queue
414   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
415
416   // Construct message in the message queue memory; note that delete should not be called on the return value
417   new (slot) LocalType( &animation, &Animation::SetEndAction, action );
418 }
419
420 inline void SetDisconnectActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
421 {
422   using LocalType = MessageValue1< Animation, Dali::Animation::EndAction >;
423
424   // Reserve some memory inside the message queue
425   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
426
427   // Construct message in the message queue memory; note that delete should not be called on the return value
428   new (slot) LocalType( &animation, &Animation::SetDisconnectAction, action );
429 }
430
431 inline void SetCurrentProgressMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
432 {
433   using LocalType = MessageValue1< Animation, float >;
434
435   // Reserve some memory inside the message queue
436   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
437
438   // Construct message in the message queue memory; note that delete should not be called on the return value
439   new (slot) LocalType( &animation, &Animation::SetCurrentProgress, progress );
440 }
441
442 inline void SetSpeedFactorMessage( EventThreadServices& eventThreadServices, const Animation& animation, float factor )
443 {
444   using LocalType = MessageValue1< Animation, float >;
445
446   // Reserve some memory inside the message queue
447   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
448
449   // Construct message in the message queue memory; note that delete should not be called on the return value
450   new (slot) LocalType( &animation, &Animation::SetSpeedFactor, factor );
451 }
452
453 inline void SetPlayRangeMessage( EventThreadServices& eventThreadServices, const Animation& animation, const Vector2& range )
454 {
455   using LocalType = MessageValue1< Animation, Vector2 >;
456
457   // Reserve some memory inside the message queue
458   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
459
460   // Construct message in the message queue memory; note that delete should not be called on the return value
461   new (slot) LocalType( &animation, &Animation::SetPlayRange, range );
462 }
463
464 inline void PlayAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
465 {
466   using LocalType = Message< Animation >;
467
468   // Reserve some memory inside the message queue
469   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
470
471   // Construct message in the message queue memory; note that delete should not be called on the return value
472   new (slot) LocalType( &animation, &Animation::Play );
473 }
474
475 inline void PlayAnimationFromMessage( EventThreadServices& eventThreadServices, const Animation& animation, float progress )
476 {
477   using LocalType = MessageValue1< Animation, float >;
478
479   // Reserve some memory inside the message queue
480   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
481
482   // Construct message in the message queue memory; note that delete should not be called on the return value
483   new (slot) LocalType( &animation, &Animation::PlayFrom, progress );
484 }
485
486 inline void PauseAnimationMessage( EventThreadServices& eventThreadServices, const Animation& animation )
487 {
488   using LocalType = Message< Animation >;
489
490   // Reserve some memory inside the message queue
491   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
492
493   // Construct message in the message queue memory; note that delete should not be called on the return value
494   new (slot) LocalType( &animation, &Animation::Pause );
495 }
496
497 inline void AddAnimatorMessage( EventThreadServices& eventThreadServices, const Animation& animation, AnimatorBase& animator )
498 {
499   using LocalType = MessageValue1< Animation, OwnerPointer<AnimatorBase> >;
500
501   // Reserve some memory inside the message queue
502   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
503
504   // Construct message in the message queue memory; note that delete should not be called on the return value
505   OwnerPointer<AnimatorBase> parameter( &animator );
506   new (slot) LocalType( &animation, &Animation::AddAnimator, parameter );
507 }
508
509 inline void PlayAfterMessage( EventThreadServices& eventThreadServices, const Animation& animation, float delaySeconds )
510 {
511   using LocalType = MessageValue1< Animation, float >;
512
513   // Reserve some memory inside the message queue
514   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
515
516   // Construct message in the message queue memory; note that delete should not be called on the return value
517   new (slot) LocalType( &animation, &Animation::PlayAfter, delaySeconds );
518 }
519
520 inline void SetLoopingModeMessage( EventThreadServices& eventThreadServices, const Animation& animation, bool loopingMode )
521 {
522   using LocalType = MessageValue1< Animation, bool >;
523
524   // Reserve some memory inside the message queue
525   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
526
527   // Construct message in the message queue memory; note that delete should not be called on the return value
528   new (slot) LocalType( &animation, &Animation::SetLoopingMode, loopingMode );
529 }
530
531 } // namespace SceneGraph
532
533 } // namespace Internal
534
535 } // namespace Dali
536
537 #endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H