Merge "(Animation) Ensure animator has been activated before performing the disconnec...
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-animator.h
1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_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 // EXTERNAL INCLUDES
22 #include <boost/function.hpp>
23
24 // INTERNAL INCLUDES
25 #include <dali/internal/common/owner-container.h>
26 #include <dali/internal/event/animation/key-frames-impl.h>
27 #include <dali/internal/update/nodes/node.h>
28 #include <dali/internal/update/common/property-base.h>
29 #include <dali/internal/common/observer-pointer.h>
30 #include <dali/public-api/animation/alpha-functions.h>
31 #include <dali/public-api/animation/animation.h>
32 #include <dali/public-api/animation/time-period.h>
33 #include <dali/public-api/common/dali-common.h>
34 #include <dali/public-api/math/quaternion.h>
35 #include <dali/public-api/math/radian.h>
36
37 namespace Dali
38 {
39
40 namespace Internal
41 {
42
43 namespace SceneGraph
44 {
45
46 class AnimatorBase;
47
48 typedef OwnerContainer< AnimatorBase* > AnimatorContainer;
49
50 typedef AnimatorContainer::Iterator AnimatorIter;
51 typedef AnimatorContainer::ConstIterator AnimatorConstIter;
52
53 /**
54  * An abstract base class for Animators, which can be added to scene graph animations.
55  * Each animator changes a single property of an object in the scene graph.
56  */
57 class AnimatorBase
58 {
59 public:
60
61   typedef float (*AlphaFunc)(float progress); ///< Definition of an alpha function
62
63   /**
64    * Constructor.
65    */
66   AnimatorBase()
67   : mDurationSeconds(1.0f),
68     mInitialDelaySeconds(0.0f),
69     mAlphaFunc(AlphaFunctions::Linear),
70     mDisconnectAction(Dali::Animation::BakeFinal),
71     mActive(false)
72   {
73   }
74
75   /**
76    * Virtual destructor.
77    */
78   virtual ~AnimatorBase()
79   {
80   }
81
82   /**
83    * Set the duration of the animator.
84    * @pre durationSeconds must be zero or greater; zero is useful when animating boolean values.
85    * @param [in] seconds Duration in seconds.
86    */
87   void SetDuration(float seconds)
88   {
89     DALI_ASSERT_DEBUG(seconds >= 0.0f);
90
91     mDurationSeconds = seconds;
92   }
93
94   /**
95    * Retrieve the duration of the animator.
96    * @return The duration in seconds.
97    */
98   float GetDuration()
99   {
100     return mDurationSeconds;
101   }
102
103   /**
104    * Set the delay before the animator should take effect.
105    * The default is zero i.e. no delay.
106    * @param [in] seconds The delay in seconds.
107    */
108   void SetInitialDelay(float seconds)
109   {
110     mInitialDelaySeconds = seconds;
111   }
112
113   /**
114    * Retrieve the initial delay of the animator.
115    * @return The delay in seconds.
116    */
117   float GetInitialDelay()
118   {
119     return mInitialDelaySeconds;
120   }
121
122   /**
123    * Set the alpha function for an animator.
124    * @param [in] alphaFunc The alpha function to apply to the animation progress.
125    */
126   void SetAlphaFunc(AlphaFunc alphaFunc)
127   {
128     mAlphaFunc = alphaFunc;
129   }
130
131   /**
132    * Retrieve the alpha function of an animator.
133    * @return The function.
134    */
135   AlphaFunc GetAlphaFunc() const
136   {
137     return mAlphaFunc;
138   }
139
140   /**
141    * Whether to bake the animation if attached property owner is disconnected.
142    * Property is only baked if the animator is active.
143    * @param [in] action The disconnect action.
144    */
145   void SetDisconnectAction( Dali::Animation::EndAction action )
146   {
147     mDisconnectAction = action;
148   }
149
150   /**
151    * Retrieve the disconnect action of an animator.
152    * @return The disconnect action.
153    */
154   Dali::Animation::EndAction GetDisconnectAction() const
155   {
156     return mDisconnectAction;
157   }
158
159   /**
160    * Whether the animator is active or not.
161    * @param [in] action The disconnect action.
162    * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected.
163    * @note When the property owner is disconnected, the active state is set to false.
164    */
165   void SetActive( bool active )
166   {
167     mActive = active;
168   }
169
170   /**
171    * Retrieve whether the animator has been set to active or not.
172    * @return The active state.
173    */
174   bool GetActive() const
175   {
176     return mActive;
177   }
178
179   /**
180    * This must be called when the animator is attached to the scene-graph.
181    * @pre The animatable scene object must also be attached to the scene-graph.
182    * @param[in] propertyOwner The scene-object that owns the animatable property.
183    */
184   virtual void Attach( PropertyOwner* propertyOwner ) = 0;
185
186   /**
187    * Update the scene object attached to the animator.
188    * @param[in] bufferIndex The buffer to animate.
189    * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point.
190    * @param[in] bake Bake.
191    * @return True if the update was applied, false if the animator has been orphaned.
192    */
193   virtual bool Update(BufferIndex bufferIndex, float progress, bool bake) = 0;
194
195   /**
196    * Query whether the animator is still attached to a scene object.
197    * The attachment will be automatically severed, when the object is destroyed.
198    * @return True if the animator is attached.
199    */
200   virtual bool IsAttached() const = 0;
201
202 protected:
203
204   float mDurationSeconds;
205   float mInitialDelaySeconds;
206
207   AlphaFunc mAlphaFunc;
208
209   Dali::Animation::EndAction mDisconnectAction;
210   bool mActive:1;
211 };
212
213 /**
214  * An animator for a specific property type PropertyType.
215  */
216 template < typename PropertyType, typename PropertyAccessorType >
217 class Animator : public AnimatorBase, public PropertyOwner::Observer
218 {
219 public:
220
221   typedef boost::function< PropertyType (float, const PropertyType&) > AnimatorFunction;
222
223   /**
224    * Construct a new property animator.
225    * @param[in] property The animatable property; only valid while the Animator is attached.
226    * @param[in] animatorFunction The function used to animate the property.
227    * @param[in] alphaFunction The alpha function to apply.
228    * @param[in] timePeriod The time period of this animation.
229    * @return A newly allocated animator.
230    */
231   static AnimatorBase* New( const PropertyBase& property,
232                             AnimatorFunction animatorFunction,
233                             AlphaFunction alphaFunction,
234                             const TimePeriod& timePeriod )
235   {
236     typedef Animator< PropertyType, PropertyAccessorType > AnimatorType;
237
238     // The property was const in the actor-thread, but animators are used in the scene-graph thread.
239     AnimatorType* animator = new AnimatorType( const_cast<PropertyBase*>( &property ),
240                                                animatorFunction );
241
242     animator->SetAlphaFunc( alphaFunction );
243     animator->SetInitialDelay( timePeriod.delaySeconds );
244     animator->SetDuration( timePeriod.durationSeconds );
245
246     return animator;
247   }
248
249   /**
250    * Virtual destructor.
251    */
252   virtual ~Animator()
253   {
254     if (mPropertyOwner)
255     {
256       mPropertyOwner->RemoveObserver(*this);
257     }
258   }
259
260   /**
261    * From AnimatorBase.
262    * @param[in] propertyOwner The scene-object that owns the animatable property.
263    */
264   virtual void Attach( PropertyOwner* propertyOwner )
265   {
266     mPropertyOwner = propertyOwner;
267
268     if (mPropertyOwner)
269     {
270       mPropertyOwner->AddObserver(*this);
271     }
272   }
273
274   /**
275    * From AnimatorBase.
276    */
277   virtual bool Update( BufferIndex bufferIndex, float progress, bool bake )
278   {
279     // If the object dies, the animator has no effect
280     if ( mPropertyOwner )
281     {
282       float alpha = mAlphaFunc( progress );
283
284       const PropertyType& current = mPropertyAccessor.Get( bufferIndex );
285
286       const PropertyType result = mAnimatorFunction( alpha, current );
287
288       if ( bake )
289       {
290         mPropertyAccessor.Bake( bufferIndex, result );
291       }
292       else
293       {
294         mPropertyAccessor.Set( bufferIndex, result );
295       }
296
297       mCurrentProgress = progress;
298     }
299
300     return IsAttached(); // return false if orphaned
301   }
302
303   /**
304    * From AnimatorBase.
305    */
306   virtual bool IsAttached() const
307   {
308     return NULL != mPropertyOwner;
309   }
310
311   /**
312    * Called when mPropertyOwner is disconnected from the scene graph.
313    */
314   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
315   {
316     // If we are active, then bake the value if required
317     if ( mActive && mDisconnectAction != Dali::Animation::Discard )
318     {
319       // Bake to target-value if BakeFinal, otherwise bake current value
320       Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true );
321     }
322
323     mActive = false;
324     mPropertyOwner = NULL;
325     mPropertyAccessor.Reset();
326   }
327
328   /**
329    * Called shortly before mPropertyOwner is destroyed, along with its property.
330    */
331   virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
332   {
333     mPropertyOwner = NULL;
334     mPropertyAccessor.Reset();
335   }
336
337 private:
338
339   /**
340    * Private constructor; see also Animator::New().
341    */
342   Animator( PropertyBase* property,
343             AnimatorFunction animatorFunction )
344   : mPropertyOwner( NULL ),
345     mPropertyAccessor( property ),
346     mAnimatorFunction( animatorFunction ),
347     mCurrentProgress( 0.0f )
348   {
349   }
350
351   // Undefined
352   Animator( const Animator& );
353
354   // Undefined
355   Animator& operator=( const Animator& );
356
357 protected:
358
359   PropertyOwner* mPropertyOwner;
360   PropertyAccessorType mPropertyAccessor;
361
362   AnimatorFunction mAnimatorFunction;
363   float mCurrentProgress;
364 };
365
366 } // namespace SceneGraph
367
368
369 // Common Update functions
370
371 struct AnimateByFloat
372 {
373   AnimateByFloat(const float& relativeValue)
374   : mRelative(relativeValue)
375   {
376   }
377
378   float operator()(float alpha, const float& property)
379   {
380     return float(property + mRelative * alpha);
381   }
382
383   float mRelative;
384 };
385
386 struct AnimateToFloat
387 {
388   AnimateToFloat(const float& targetValue)
389   : mTarget(targetValue)
390   {
391   }
392
393   float operator()(float alpha, const float& property)
394   {
395     return float(property + ((mTarget - property) * alpha));
396   }
397
398   float mTarget;
399 };
400
401 struct AnimateByInteger
402 {
403   AnimateByInteger(const int& relativeValue)
404   : mRelative(relativeValue)
405   {
406   }
407
408   float operator()(float alpha, const int& property)
409   {
410     return int(property + mRelative * alpha + 0.5f );
411   }
412
413   int mRelative;
414 };
415
416 struct AnimateToInteger
417 {
418   AnimateToInteger(const int& targetValue)
419   : mTarget(targetValue)
420   {
421   }
422
423   float operator()(float alpha, const int& property)
424   {
425     return int(property + ((mTarget - property) * alpha) + 0.5f);
426   }
427
428   int mTarget;
429 };
430
431 struct AnimateByVector2
432 {
433   AnimateByVector2(const Vector2& relativeValue)
434   : mRelative(relativeValue)
435   {
436   }
437
438   Vector2 operator()(float alpha, const Vector2& property)
439   {
440     return Vector2(property + mRelative * alpha);
441   }
442
443   Vector2 mRelative;
444 };
445
446 struct AnimateToVector2
447 {
448   AnimateToVector2(const Vector2& targetValue)
449   : mTarget(targetValue)
450   {
451   }
452
453   Vector2 operator()(float alpha, const Vector2& property)
454   {
455     return Vector2(property + ((mTarget - property) * alpha));
456   }
457
458   Vector2 mTarget;
459 };
460
461 struct AnimateByVector3
462 {
463   AnimateByVector3(const Vector3& relativeValue)
464   : mRelative(relativeValue)
465   {
466   }
467
468   Vector3 operator()(float alpha, const Vector3& property)
469   {
470     return Vector3(property + mRelative * alpha);
471   }
472
473   Vector3 mRelative;
474 };
475
476 struct AnimateToVector3
477 {
478   AnimateToVector3(const Vector3& targetValue)
479   : mTarget(targetValue)
480   {
481   }
482
483   Vector3 operator()(float alpha, const Vector3& property)
484   {
485     return Vector3(property + ((mTarget - property) * alpha));
486   }
487
488   Vector3 mTarget;
489 };
490
491 struct AnimateByVector4
492 {
493   AnimateByVector4(const Vector4& relativeValue)
494   : mRelative(relativeValue)
495   {
496   }
497
498   Vector4 operator()(float alpha, const Vector4& property)
499   {
500     return Vector4(property + mRelative * alpha);
501   }
502
503   Vector4 mRelative;
504 };
505
506 struct AnimateToVector4
507 {
508   AnimateToVector4(const Vector4& targetValue)
509   : mTarget(targetValue)
510   {
511   }
512
513   Vector4 operator()(float alpha, const Vector4& property)
514   {
515     return Vector4(property + ((mTarget - property) * alpha));
516   }
517
518   Vector4 mTarget;
519 };
520
521 struct AnimateByOpacity
522 {
523   AnimateByOpacity(const float& relativeValue)
524   : mRelative(relativeValue)
525   {
526   }
527
528   Vector4 operator()(float alpha, const Vector4& property)
529   {
530     Vector4 result(property);
531     result.a += mRelative * alpha;
532
533     return result;
534   }
535
536   float mRelative;
537 };
538
539 struct AnimateToOpacity
540 {
541   AnimateToOpacity(const float& targetValue)
542   : mTarget(targetValue)
543   {
544   }
545
546   Vector4 operator()(float alpha, const Vector4& property)
547   {
548     Vector4 result(property);
549     result.a = property.a + ((mTarget - property.a) * alpha);
550
551     return result;
552   }
553
554   float mTarget;
555 };
556
557 struct AnimateByBoolean
558 {
559   AnimateByBoolean(bool relativeValue)
560   : mRelative(relativeValue)
561   {
562   }
563
564   bool operator()(float alpha, const bool& property)
565   {
566     // Alpha is not useful here, just keeping to the same template as other update functors
567     return bool(alpha >= 1.0f ? (property || mRelative) : property);
568   }
569
570   bool mRelative;
571 };
572
573 struct AnimateToBoolean
574 {
575   AnimateToBoolean(bool targetValue)
576   : mTarget(targetValue)
577   {
578   }
579
580   bool operator()(float alpha, const bool& property)
581   {
582     // Alpha is not useful here, just keeping to the same template as other update functors
583     return bool(alpha >= 1.0f ? mTarget : property);
584   }
585
586   bool mTarget;
587 };
588
589 struct RotateByAngleAxis
590 {
591   RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
592   : mAngleRadians(angleRadians),
593     mAxis(axis.x, axis.y, axis.z, 0.0f)
594   {
595   }
596
597   Quaternion operator()(float alpha, const Quaternion& rotation)
598   {
599     if (alpha > 0.0f)
600     {
601       return rotation * Quaternion(mAngleRadians * alpha, mAxis);
602     }
603
604     return rotation;
605   }
606
607   float mAngleRadians;
608   Vector4 mAxis;
609 };
610
611 struct RotateToQuaternion
612 {
613   RotateToQuaternion(const Quaternion& targetValue)
614   : mTarget(targetValue)
615   {
616   }
617
618   Quaternion operator()(float alpha, const Quaternion& rotation)
619   {
620     return Quaternion::Slerp(rotation, mTarget, alpha);
621   }
622
623   Quaternion mTarget;
624 };
625
626
627 struct KeyFrameBooleanFunctor
628 {
629   KeyFrameBooleanFunctor(KeyFrameBooleanPtr keyFrames)
630   : mKeyFrames(keyFrames)
631   {
632   }
633
634   bool operator()(float progress, const bool& property)
635   {
636     if(mKeyFrames->IsActive(progress))
637     {
638       return mKeyFrames->GetValue(progress);
639     }
640     return property;
641   }
642
643   KeyFrameBooleanPtr mKeyFrames;
644 };
645
646 struct KeyFrameNumberFunctor
647 {
648   KeyFrameNumberFunctor(KeyFrameNumberPtr keyFrames)
649   : mKeyFrames(keyFrames)
650   {
651   }
652
653   float operator()(float progress, const float& property)
654   {
655     if(mKeyFrames->IsActive(progress))
656     {
657       return mKeyFrames->GetValue(progress);
658     }
659     return property;
660   }
661
662   KeyFrameNumberPtr mKeyFrames;
663 };
664
665 struct KeyFrameIntegerFunctor
666 {
667   KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames)
668   : mKeyFrames(keyFrames)
669   {
670   }
671
672   float operator()(float progress, const int& property)
673   {
674     if(mKeyFrames->IsActive(progress))
675     {
676       return mKeyFrames->GetValue(progress);
677     }
678     return property;
679   }
680
681   KeyFrameIntegerPtr mKeyFrames;
682 };
683
684 struct KeyFrameVector2Functor
685 {
686   KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames)
687   : mKeyFrames(keyFrames)
688   {
689   }
690
691   Vector2 operator()(float progress, const Vector2& property)
692   {
693     if(mKeyFrames->IsActive(progress))
694     {
695       return mKeyFrames->GetValue(progress);
696     }
697     return property;
698   }
699
700   KeyFrameVector2Ptr mKeyFrames;
701 };
702
703
704 struct KeyFrameVector3Functor
705 {
706   KeyFrameVector3Functor(KeyFrameVector3Ptr keyFrames)
707   : mKeyFrames(keyFrames)
708   {
709   }
710
711   Vector3 operator()(float progress, const Vector3& property)
712   {
713     if(mKeyFrames->IsActive(progress))
714     {
715       return mKeyFrames->GetValue(progress);
716     }
717     return property;
718   }
719
720   KeyFrameVector3Ptr mKeyFrames;
721 };
722
723 struct KeyFrameVector4Functor
724 {
725   KeyFrameVector4Functor(KeyFrameVector4Ptr keyFrames)
726   : mKeyFrames(keyFrames)
727   {
728   }
729
730   Vector4 operator()(float progress, const Vector4& property)
731   {
732     if(mKeyFrames->IsActive(progress))
733     {
734       return mKeyFrames->GetValue(progress);
735     }
736     return property;
737   }
738
739   KeyFrameVector4Ptr mKeyFrames;
740 };
741
742 struct KeyFrameQuaternionFunctor
743 {
744   KeyFrameQuaternionFunctor(KeyFrameQuaternionPtr keyFrames)
745   : mKeyFrames(keyFrames)
746   {
747   }
748
749   Quaternion operator()(float progress, const Quaternion& property)
750   {
751     if(mKeyFrames->IsActive(progress))
752     {
753       return mKeyFrames->GetValue(progress);
754     }
755     return property;
756   }
757
758   KeyFrameQuaternionPtr mKeyFrames;
759 };
760
761
762
763
764 } // namespace Internal
765
766 } // namespace Dali
767
768 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__