Boost::any replacement in Dali Core functions
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / animation-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://floralicense.org/license/
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 // CLASS HEADER
18 #include <dali/internal/event/animation/animation-impl.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/public-api/animation/alpha-functions.h>
22 #include <dali/public-api/animation/time-period.h>
23 #include <dali/public-api/common/dali-common.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/public-api/math/vector2.h>
26 #include <dali/public-api/math/radian.h>
27 #include <dali/internal/event/actors/actor-impl.h>
28 #include <dali/internal/event/common/stage-impl.h>
29 #include <dali/internal/event/animation/animator-connector.h>
30 #include <dali/internal/event/animation/animation-playlist.h>
31 #include <dali/internal/event/common/notification-manager.h>
32 #include <dali/internal/update/manager/update-manager.h>
33 #include <dali/internal/event/effects/shader-effect-impl.h>
34 #include <dali/internal/event/common/thread-local-storage.h>
35
36 using namespace std;
37
38 using Dali::Internal::SceneGraph::UpdateManager;
39 using Dali::Internal::SceneGraph::AnimatorBase;
40 using Dali::Internal::SceneGraph::Shader;
41
42 namespace Dali
43 {
44
45 namespace Internal
46 {
47
48 static bool SHOW_VALUE = true;
49 static bool HIDE_VALUE = false;
50
51 namespace
52 {
53
54 BaseHandle Create()
55 {
56   return Dali::Animation::New(0.f);
57 }
58
59 TypeRegistration mType( typeid(Dali::Animation), typeid(Dali::BaseHandle), Create );
60
61 SignalConnectorType signalConnector1( mType, Dali::Animation::SIGNAL_FINISHED, &Animation::DoConnectSignal );
62
63 TypeAction action1( mType, Dali::Animation::ACTION_PLAY, &Animation::DoAction );
64 TypeAction action2( mType, Dali::Animation::ACTION_STOP, &Animation::DoAction );
65 TypeAction action3( mType, Dali::Animation::ACTION_PAUSE, &Animation::DoAction );
66
67 } // anon namespace
68
69
70 AnimationPtr Animation::New(float durationSeconds)
71 {
72   return New(durationSeconds, Dali::Animation::Bake, Dali::Animation::Bake, Dali::AlphaFunctions::Linear);
73 }
74
75 AnimationPtr Animation::New(float durationSeconds, EndAction endAction, EndAction destroyAction)
76 {
77   return New(durationSeconds, endAction, destroyAction, Dali::AlphaFunctions::Linear);
78 }
79
80 AnimationPtr Animation::New(float durationSeconds, EndAction endAction, EndAction destroyAction, AlphaFunction alpha)
81 {
82   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
83   UpdateManager& updateManager = tls.GetUpdateManager();
84
85   AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
86
87   AnimationPtr progress = new Animation( updateManager, playlist, durationSeconds, endAction, destroyAction, alpha );
88
89   // Second-phase construction
90   progress->Initialize();
91
92   return progress;
93 }
94
95 Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction destroyAction, AlphaFunction defaultAlpha )
96 : mUpdateManager( updateManager ),
97   mPlaylist( playlist ),
98   mAnimation( NULL ),
99   mNotificationCount( 0 ),
100   mFinishedCallback( NULL ),
101   mFinishedCallbackObject( NULL ),
102   mDurationSeconds( durationSeconds ),
103   mIsLooping( false ),
104   mEndAction( endAction ),
105   mDestroyAction( destroyAction ),
106   mDefaultAlpha( defaultAlpha )
107 {
108 }
109
110 void Animation::Initialize()
111 {
112   // Connect to the animation playlist
113   mPlaylist.AnimationCreated( *this );
114
115   CreateSceneObject();
116
117   RegisterObject();
118 }
119
120 Animation::~Animation()
121 {
122   // Guard to allow handle destruction after Core has been destroyed
123   if ( Stage::IsInstalled() )
124   {
125     // Disconnect from the animation playlist
126     mPlaylist.AnimationDestroyed( *this );
127
128     DestroySceneObject();
129
130     UnregisterObject();
131   }
132 }
133
134 void Animation::CreateSceneObject()
135 {
136   DALI_ASSERT_DEBUG( mAnimation == NULL );
137
138   // Create a new animation, temporarily owned
139   SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mIsLooping, mEndAction, mDestroyAction );
140
141   // Keep a const pointer to the animation.
142   mAnimation = animation;
143
144   // Transfer animation ownership to the update manager through a message
145   AddAnimationMessage( mUpdateManager, animation );
146 }
147
148 void Animation::DestroySceneObject()
149 {
150   if ( mAnimation != NULL )
151   {
152     // Remove animation using a message to the update manager
153     RemoveAnimationMessage( mUpdateManager, *mAnimation );
154     mAnimation = NULL;
155   }
156 }
157
158 void Animation::SetDuration(float seconds)
159 {
160   // Cache for public getters
161   mDurationSeconds = seconds;
162
163   // mAnimation is being used in a separate thread; queue a message to set the value
164   SetDurationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, seconds );
165 }
166
167 float Animation::GetDuration() const
168 {
169   // This is not animatable; the cached value is up-to-date.
170   return mDurationSeconds;
171 }
172
173 void Animation::SetLooping(bool looping)
174 {
175   // Cache for public getters
176   mIsLooping = looping;
177
178   // mAnimation is being used in a separate thread; queue a message to set the value
179   SetLoopingMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, looping );
180 }
181
182 bool Animation::IsLooping() const
183 {
184   // This is not animatable; the cached value is up-to-date.
185   return mIsLooping;
186 }
187
188 void Animation::SetEndAction(EndAction action)
189 {
190   // Cache for public getters
191   mEndAction = action;
192
193   // mAnimation is being used in a separate thread; queue a message to set the value
194   SetEndActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
195 }
196
197 Dali::Animation::EndAction Animation::GetEndAction() const
198 {
199   // This is not animatable; the cached value is up-to-date.
200   return mEndAction;
201 }
202
203 void Animation::SetDestroyAction(EndAction action)
204 {
205   // Cache for public getters
206   mDestroyAction = action;
207
208   // mAnimation is being used in a separate thread; queue a message to set the value
209   SetDestroyActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
210 }
211
212 Dali::Animation::EndAction Animation::GetDestroyAction() const
213 {
214   // This is not animatable; the cached value is up-to-date.
215   return mDestroyAction;
216 }
217
218 void Animation::Play()
219 {
220   // Update the current playlist
221   mPlaylist.OnPlay( *this );
222
223   // mAnimation is being used in a separate thread; queue a Play message
224   PlayAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
225 }
226
227 void Animation::Pause()
228 {
229   // mAnimation is being used in a separate thread; queue a Pause message
230   PauseAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
231 }
232
233 void Animation::Stop()
234 {
235   // mAnimation is being used in a separate thread; queue a Stop message
236   StopAnimationMessage( mUpdateManager, *mAnimation );
237 }
238
239 void Animation::Clear()
240 {
241   DALI_ASSERT_DEBUG(mAnimation);
242
243   // Remove all the connectors
244   mConnectors.Clear();
245
246   // Replace the old scene-object with a new one
247   DestroySceneObject();
248   CreateSceneObject();
249
250   // Reset the notification count, since the new scene-object has never been played
251   mNotificationCount = 0;
252
253   // Update the current playlist
254   mPlaylist.OnClear( *this );
255 }
256
257 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
258 {
259   AnimateBy(target, relativeValue, AlphaFunctions::Default, mDurationSeconds);
260 }
261
262 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
263 {
264   AnimateBy(target, relativeValue, alpha, mDurationSeconds);
265 }
266
267 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
268 {
269   AnimateBy(target, relativeValue, AlphaFunctions::Default, period);
270 }
271
272 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
273 {
274   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
275
276   switch ( relativeValue.GetType() )
277   {
278     case Property::BOOLEAN:
279     {
280       AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
281                                                           target.propertyIndex,
282                                                           target.componentIndex,
283                                                           AnimateByBoolean(relativeValue.Get<bool>()),
284                                                           alpha,
285                                                           period ) );
286       break;
287     }
288
289     case Property::FLOAT:
290     {
291       AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
292                                                            target.propertyIndex,
293                                                            target.componentIndex,
294                                                            AnimateByFloat(relativeValue.Get<float>()),
295                                                            alpha,
296                                                            period ) );
297       break;
298     }
299
300     case Property::VECTOR2:
301     {
302       AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
303                                                              target.propertyIndex,
304                                                              target.componentIndex,
305                                                              AnimateByVector2(relativeValue.Get<Vector2>()),
306                                                              alpha,
307                                                              period ) );
308       break;
309     }
310
311     case Property::VECTOR3:
312     {
313       AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
314                                                              target.propertyIndex,
315                                                              target.componentIndex,
316                                                              AnimateByVector3(relativeValue.Get<Vector3>()),
317                                                              alpha,
318                                                              period ) );
319       break;
320     }
321
322     case Property::VECTOR4:
323     {
324       AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
325                                                              target.propertyIndex,
326                                                              target.componentIndex,
327                                                              AnimateByVector4(relativeValue.Get<Vector4>()),
328                                                              alpha,
329                                                              period ) );
330       break;
331     }
332
333     case Property::ROTATION:
334     {
335       AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
336
337       AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
338                                                                 target.propertyIndex,
339                                                                 target.componentIndex,
340                                                                 RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
341                                                                 alpha,
342                                                                 period ) );
343       break;
344     }
345
346     default:
347       DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
348       break;
349   }
350 }
351
352 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
353 {
354   AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
355 }
356
357 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
358 {
359   AnimateTo(target, destinationValue, alpha, mDurationSeconds);
360 }
361
362 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
363 {
364   AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
365 }
366
367 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
368 {
369   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
370
371   AnimateTo( proxy, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
372 }
373
374 void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
375 {
376   Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
377   if(componentIndex != Property::INVALID_COMPONENT_INDEX)
378   {
379     if( type == Property::VECTOR2
380         || type == Property::VECTOR3
381         || type == Property::VECTOR4 )
382     {
383       type = Property::FLOAT;
384     }
385   }
386   DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
387
388   switch (destinationValue.GetType())
389   {
390     case Property::BOOLEAN:
391     {
392       AddAnimatorConnector( AnimatorConnector<bool>::New(targetObject,
393                                                          targetPropertyIndex,
394                                                          componentIndex,
395                                                          AnimateToBoolean(destinationValue.Get<bool>()),
396                                                          alpha,
397                                                          period) );
398       break;
399     }
400
401     case Property::FLOAT:
402     {
403       AddAnimatorConnector( AnimatorConnector<float>::New(targetObject,
404                                                           targetPropertyIndex,
405                                                           componentIndex,
406                                                           AnimateToFloat(destinationValue.Get<float>()),
407                                                           alpha,
408                                                           period) );
409       break;
410     }
411
412     case Property::VECTOR2:
413     {
414       AddAnimatorConnector( AnimatorConnector<Vector2>::New(targetObject,
415                                                             targetPropertyIndex,
416                                                             componentIndex,
417                                                             AnimateToVector2(destinationValue.Get<Vector2>()),
418                                                             alpha,
419                                                             period) );
420       break;
421     }
422
423     case Property::VECTOR3:
424     {
425       if ( Dali::Actor::SIZE == targetPropertyIndex )
426       {
427         // Test whether this is actually an Actor
428         Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
429         if ( maybeActor )
430         {
431           // Notify the actor that its size is being animated
432           maybeActor->OnSizeAnimation( *this, destinationValue.Get<Vector3>() );
433         }
434       }
435
436       AddAnimatorConnector( AnimatorConnector<Vector3>::New(targetObject,
437                                                             targetPropertyIndex,
438                                                             componentIndex,
439                                                             AnimateToVector3(destinationValue.Get<Vector3>()),
440                                                             alpha,
441                                                             period) );
442       break;
443     }
444
445     case Property::VECTOR4:
446     {
447       AddAnimatorConnector( AnimatorConnector<Vector4>::New(targetObject,
448                                                             targetPropertyIndex,
449                                                             componentIndex,
450                                                             AnimateToVector4(destinationValue.Get<Vector4>()),
451                                                             alpha,
452                                                             period) );
453       break;
454     }
455
456     case Property::ROTATION:
457     {
458       AddAnimatorConnector( AnimatorConnector<Quaternion>::New(targetObject,
459                                                                targetPropertyIndex,
460                                                                componentIndex,
461                                                                RotateToQuaternion(destinationValue.Get<Quaternion>()),
462                                                                alpha,
463                                                                period) );
464       break;
465     }
466
467     default:
468       DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
469       break;
470   }
471 }
472
473 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
474 {
475   AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds);
476 }
477
478 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
479 {
480   AnimateBetween(target, keyFrames, mDefaultAlpha, period);
481 }
482
483 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
484 {
485   AnimateBetween(target, keyFrames, alpha, mDurationSeconds);
486 }
487
488 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
489 {
490   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
491
492   switch(keyFrames.GetType())
493   {
494     case Dali::Property::BOOLEAN:
495     {
496       const KeyFrameBoolean* kf;
497       GetSpecialization(keyFrames, kf);
498       KeyFrameBooleanPtr kfCopy = KeyFrameBoolean::Clone(*kf);
499       AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
500                                                           target.propertyIndex,
501                                                           target.componentIndex,
502                                                           KeyFrameBooleanFunctor(kfCopy),
503                                                           alpha,
504                                                           period ) );
505       break;
506     }
507     case Dali::Property::FLOAT:
508     {
509       const KeyFrameNumber* kf;
510       GetSpecialization(keyFrames, kf);
511       KeyFrameNumberPtr kfCopy = KeyFrameNumber::Clone(*kf);
512       AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
513                                                            target.propertyIndex,
514                                                            target.componentIndex,
515                                                            KeyFrameNumberFunctor(kfCopy),
516                                                            alpha,
517                                                            period ) );
518       break;
519     }
520
521     case Dali::Property::VECTOR2:
522     {
523       const KeyFrameVector2* kf;
524       GetSpecialization(keyFrames, kf);
525       KeyFrameVector2Ptr kfCopy = KeyFrameVector2::Clone(*kf);
526       AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
527                                                              target.propertyIndex,
528                                                              target.componentIndex,
529                                                              KeyFrameVector2Functor(kfCopy),
530                                                              alpha,
531                                                              period ) );
532       break;
533     }
534
535     case Dali::Property::VECTOR3:
536     {
537       const KeyFrameVector3* kf;
538       GetSpecialization(keyFrames, kf);
539       KeyFrameVector3Ptr kfCopy = KeyFrameVector3::Clone(*kf);
540       AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
541                                                              target.propertyIndex,
542                                                              target.componentIndex,
543                                                              KeyFrameVector3Functor(kfCopy),
544                                                              alpha,
545                                                              period ) );
546       break;
547     }
548
549     case Dali::Property::VECTOR4:
550     {
551       const KeyFrameVector4* kf;
552       GetSpecialization(keyFrames, kf);
553       KeyFrameVector4Ptr kfCopy = KeyFrameVector4::Clone(*kf);
554       AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
555                                                              target.propertyIndex,
556                                                              target.componentIndex,
557                                                              KeyFrameVector4Functor(kfCopy),
558                                                              alpha,
559                                                              period ) );
560       break;
561     }
562
563     case Dali::Property::ROTATION:
564     {
565       const KeyFrameQuaternion* kf;
566       GetSpecialization(keyFrames, kf);
567       KeyFrameQuaternionPtr kfCopy = KeyFrameQuaternion::Clone(*kf);
568       AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
569                                                                 target.propertyIndex,
570                                                                 target.componentIndex,
571                                                                 KeyFrameQuaternionFunctor(kfCopy),
572                                                                 alpha,
573                                                                 period ) );
574       break;
575     }
576
577     default: // not all property types are animateable
578       break;
579   }
580 }
581
582 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func )
583 {
584   Animate( target, targetType, func, mDefaultAlpha, mDurationSeconds );
585 }
586
587 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, AlphaFunction& alpha )
588 {
589   Animate( target, targetType, func, alpha, mDurationSeconds );
590 }
591
592 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, TimePeriod period )
593 {
594   Animate( target, targetType, func, mDefaultAlpha, period );
595 }
596
597 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, AlphaFunction& alpha, TimePeriod period )
598 {
599   Property::Type type = target.object.GetPropertyType(target.propertyIndex);
600   if(target.componentIndex != Property::INVALID_COMPONENT_INDEX)
601   {
602     if( type == Property::VECTOR2
603         || type == Property::VECTOR3
604         || type == Property::VECTOR4 )
605     {
606       type = Property::FLOAT;
607     }
608   }
609   DALI_ASSERT_ALWAYS( type == targetType && "Animation function must match target property type" );
610
611   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
612
613   switch ( targetType )
614   {
615     case Property::BOOLEAN:
616     {
617       AddAnimatorConnector( AnimatorConnector<bool>::New(proxy,
618                                                          target.propertyIndex,
619                                                          target.componentIndex,
620                                                          AnyCast< AnimatorFunctionBool >( func ),
621                                                          alpha,
622                                                          period) );
623       break;
624     }
625
626     case Property::FLOAT:
627     {
628       AddAnimatorConnector( AnimatorConnector<float>::New(proxy,
629                                                           target.propertyIndex,
630                                                           target.componentIndex,
631                                                           AnyCast< AnimatorFunctionFloat >( func ),
632                                                           alpha,
633                                                           period) );
634       break;
635     }
636
637     case Property::VECTOR2:
638     {
639       AddAnimatorConnector( AnimatorConnector<Vector2>::New(proxy,
640                                                             target.propertyIndex,
641                                                             target.componentIndex,
642                                                             AnyCast< AnimatorFunctionVector2 >( func ),
643                                                             alpha,
644                                                             period) );
645       break;
646     }
647
648     case Property::VECTOR3:
649     {
650       AddAnimatorConnector( AnimatorConnector<Vector3>::New(proxy,
651                                                             target.propertyIndex,
652                                                             target.componentIndex,
653                                                             AnyCast< AnimatorFunctionVector3 >( func ),
654                                                             alpha,
655                                                             period) );
656       break;
657     }
658
659     case Property::VECTOR4:
660     {
661       AddAnimatorConnector( AnimatorConnector<Vector4>::New(proxy,
662                                                             target.propertyIndex,
663                                                             target.componentIndex,
664                                                             AnyCast< AnimatorFunctionVector4 >( func ),
665                                                             alpha,
666                                                             period) );
667       break;
668     }
669
670     case Property::ROTATION:
671     {
672       AddAnimatorConnector( AnimatorConnector<Quaternion>::New(proxy,
673                                                                target.propertyIndex,
674                                                                target.componentIndex,
675                                                                AnyCast< AnimatorFunctionQuaternion >( func ),
676                                                                alpha,
677                                                                period) );
678       break;
679     }
680
681     default:
682       DALI_ASSERT_ALWAYS(false && "Property type enumeration out of bounds" ); // should never come here
683       break;
684   }
685 }
686
687 bool Animation::HasFinished()
688 {
689   bool hasFinished(false);
690   const int playCount(mAnimation->GetPlayCount());
691
692   // If the play count has been incremented, then another notification is required
693   if (playCount > mNotificationCount)
694   {
695     // Note that only one signal is emitted, if the animation has been played repeatedly
696     mNotificationCount = playCount;
697
698     hasFinished = true;
699   }
700
701   return hasFinished;
702 }
703
704 Dali::Animation::AnimationSignalV2& Animation::FinishedSignal()
705 {
706   return mFinishedSignal;
707 }
708
709 void Animation::EmitSignalFinish()
710 {
711   if ( !mFinishedSignal.Empty() )
712   {
713     Dali::Animation handle( this );
714     mFinishedSignal.Emit( handle );
715   }
716
717   // This callback is used internally, to avoid the overhead of using a signal.
718   if ( mFinishedCallback )
719   {
720     mFinishedCallback( mFinishedCallbackObject );
721   }
722 }
723
724 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
725 {
726   bool connected( true );
727   Animation* animation = dynamic_cast<Animation*>(object);
728
729   if ( Dali::Animation::SIGNAL_FINISHED == signalName )
730   {
731     animation->FinishedSignal().Connect( tracker, functor );
732   }
733   else
734   {
735     // signalName does not match any signal
736     connected = false;
737   }
738
739   return connected;
740 }
741
742 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
743 {
744   mFinishedCallback = callback;
745   mFinishedCallbackObject = object;
746 }
747
748 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
749 {
750   DALI_ASSERT_DEBUG( NULL != connector );
751
752   connector->SetParent(*this);
753
754   mConnectors.PushBack( connector );
755 }
756
757 void Animation::MoveBy(Actor& actor, float x, float y, float z)
758 {
759   MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
760 }
761
762 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
763 {
764   MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
765 }
766
767 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
768 {
769   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
770                                                          Dali::Actor::POSITION,
771                                                          Property::INVALID_COMPONENT_INDEX,
772                                                          AnimateByVector3(displacement),
773                                                          alpha,
774                                                          TimePeriod(delaySeconds, durationSeconds) ) );
775 }
776
777 void Animation::MoveTo(Actor& actor, float x, float y, float z)
778 {
779   MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
780 }
781
782 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
783 {
784   MoveTo(actor, position, alpha, 0.0f, GetDuration());
785 }
786
787 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha,  float delaySeconds, float durationSeconds)
788 {
789   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
790                                                          Dali::Actor::POSITION,
791                                                          Property::INVALID_COMPONENT_INDEX,
792                                                          AnimateToVector3(position),
793                                                          alpha,
794                                                          TimePeriod(delaySeconds, durationSeconds) ) );
795 }
796
797 void Animation::Move(Actor& actor, AnimatorFunctionVector3 func, AlphaFunction alpha,  float delaySeconds, float durationSeconds)
798 {
799   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
800                                                          Dali::Actor::POSITION,
801                                                          Property::INVALID_COMPONENT_INDEX,
802                                                          func,
803                                                          alpha,
804                                                          TimePeriod(delaySeconds, durationSeconds) ) );
805 }
806
807 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
808 {
809   RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
810 }
811
812 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
813 {
814   RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
815 }
816
817 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
818 {
819   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
820                                                             Dali::Actor::ROTATION,
821                                                             Property::INVALID_COMPONENT_INDEX,
822                                                             RotateByAngleAxis(angle, axis),
823                                                             alpha,
824                                                             TimePeriod(delaySeconds, durationSeconds) ) );
825 }
826
827 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
828 {
829   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
830   normalizedAxis.Normalize();
831
832   Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
833
834   RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
835 }
836
837 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
838 {
839   RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
840 }
841
842 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
843 {
844   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
845   normalizedAxis.Normalize();
846
847   Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
848
849   RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
850 }
851
852 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
853 {
854   RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
855 }
856
857 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
858 {
859   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
860   normalizedAxis.Normalize();
861
862   Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
863
864   RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
865 }
866
867 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
868 {
869   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
870                                                             Dali::Actor::ROTATION,
871                                                             Property::INVALID_COMPONENT_INDEX,
872                                                             RotateToQuaternion(rotation),
873                                                             alpha,
874                                                             TimePeriod(delaySeconds, durationSeconds) ) );
875 }
876
877 void Animation::Rotate(Actor& actor, AnimatorFunctionQuaternion func, AlphaFunction alpha,  float delaySeconds, float durationSeconds)
878 {
879   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
880                                                             Dali::Actor::ROTATION,
881                                                             Property::INVALID_COMPONENT_INDEX,
882                                                             func,
883                                                             alpha,
884                                                             TimePeriod(delaySeconds, durationSeconds) ) );
885 }
886
887 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
888 {
889   ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
890 }
891
892 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
893 {
894   ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
895 }
896
897 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
898 {
899   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
900                                                          Dali::Actor::SCALE,
901                                                          Property::INVALID_COMPONENT_INDEX,
902                                                          AnimateByVector3(scale),
903                                                          alpha,
904                                                          TimePeriod(delaySeconds, durationSeconds) ) );
905 }
906
907 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
908 {
909   ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
910 }
911
912 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
913 {
914   ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
915 }
916
917 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
918 {
919   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
920                                                          Dali::Actor::SCALE,
921                                                          Property::INVALID_COMPONENT_INDEX,
922                                                          AnimateToVector3(scale),
923                                                          alpha,
924                                                          TimePeriod(delaySeconds, durationSeconds) ) );
925 }
926
927 void Animation::Show(Actor& actor, float delaySeconds)
928 {
929   AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
930                                                       Dali::Actor::VISIBLE,
931                                                       Property::INVALID_COMPONENT_INDEX,
932                                                       AnimateToBoolean(SHOW_VALUE),
933                                                       AlphaFunctions::Default,
934                                                       TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
935 }
936
937 void Animation::Hide(Actor& actor, float delaySeconds)
938 {
939   AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
940                                                       Dali::Actor::VISIBLE,
941                                                       Property::INVALID_COMPONENT_INDEX,
942                                                       AnimateToBoolean(HIDE_VALUE),
943                                                       AlphaFunctions::Default,
944                                                       TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
945 }
946
947 void Animation::OpacityBy(Actor& actor, float opacity)
948 {
949   OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
950 }
951
952 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
953 {
954   OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
955 }
956
957 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
958 {
959   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
960                                                          Dali::Actor::COLOR,
961                                                          Property::INVALID_COMPONENT_INDEX,
962                                                          AnimateByOpacity(opacity),
963                                                          alpha,
964                                                          TimePeriod(delaySeconds, durationSeconds) ) );
965 }
966
967 void Animation::OpacityTo(Actor& actor, float opacity)
968 {
969   OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
970 }
971
972 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
973 {
974   OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
975 }
976
977 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
978 {
979   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
980                                                          Dali::Actor::COLOR,
981                                                          Property::INVALID_COMPONENT_INDEX,
982                                                          AnimateToOpacity(opacity),
983                                                          alpha,
984                                                          TimePeriod(delaySeconds, durationSeconds) ) );
985 }
986
987 void Animation::ColorBy(Actor& actor, const Vector4& color)
988 {
989   ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
990 }
991
992 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
993 {
994   ColorBy(actor, color, alpha, 0.0f, GetDuration());
995 }
996
997 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
998 {
999   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1000                                                          Dali::Actor::COLOR,
1001                                                          Property::INVALID_COMPONENT_INDEX,
1002                                                          AnimateByVector4(color),
1003                                                          alpha,
1004                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1005 }
1006
1007 void Animation::ColorTo(Actor& actor, const Vector4& color)
1008 {
1009   ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1010 }
1011
1012 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
1013 {
1014   ColorTo(actor, color, alpha, 0.0f, GetDuration());
1015 }
1016
1017 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1018 {
1019   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1020                                                          Dali::Actor::COLOR,
1021                                                          Property::INVALID_COMPONENT_INDEX,
1022                                                          AnimateToVector4(color),
1023                                                          alpha,
1024                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1025 }
1026
1027 void Animation::Resize(Actor& actor, float width, float height)
1028 {
1029   Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
1030 }
1031
1032 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
1033 {
1034   Resize(actor, width, height, alpha, 0.0f, GetDuration());
1035 }
1036
1037 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1038 {
1039   Vector3 targetSize( width, height, min(width, height) );
1040
1041   // notify the actor impl that its size is being animated
1042   actor.OnSizeAnimation( *this, targetSize );
1043
1044   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1045                                                          Dali::Actor::SIZE,
1046                                                          Property::INVALID_COMPONENT_INDEX,
1047                                                          AnimateToVector3(targetSize),
1048                                                          alpha,
1049                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1050 }
1051
1052 void Animation::Resize(Actor& actor, const Vector3& size)
1053 {
1054   Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1055 }
1056
1057 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1058 {
1059   Resize(actor, size, alpha, 0.0f, GetDuration());
1060 }
1061
1062 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1063 {
1064   // notify the actor impl that its size is being animated
1065   actor.OnSizeAnimation( *this, size );
1066
1067   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1068                                                          Dali::Actor::SIZE,
1069                                                          Property::INVALID_COMPONENT_INDEX,
1070                                                          AnimateToVector3(size),
1071                                                          alpha,
1072                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1073 }
1074
1075 void Animation::ParentOriginTo(Actor& actor, const Vector3& parentOrigin)
1076 {
1077   ParentOriginTo(actor, parentOrigin, mDefaultAlpha, 0.0f, GetDuration());
1078 }
1079
1080 void Animation::ParentOriginTo(Actor& actor, const Vector3& parentOrigin, AlphaFunction alpha)
1081 {
1082   ParentOriginTo(actor, parentOrigin, alpha, 0.0f, GetDuration());
1083 }
1084
1085 void Animation::ParentOriginTo(Actor& actor, const Vector3& parentOrigin, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1086 {
1087   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1088                                                          Dali::Actor::PARENT_ORIGIN,
1089                                                          Property::INVALID_COMPONENT_INDEX,
1090                                                          AnimateToVector3(parentOrigin),
1091                                                          alpha,
1092                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1093 }
1094
1095 void Animation::AnchorPointTo(Actor& actor, const Vector3& anchorPoint)
1096 {
1097   AnchorPointTo(actor, anchorPoint, mDefaultAlpha, 0.0f, GetDuration());
1098 }
1099
1100 void Animation::AnchorPointTo(Actor& actor, const Vector3& anchorPoint, AlphaFunction alpha)
1101 {
1102   AnchorPointTo(actor, anchorPoint, alpha, 0.0f, GetDuration());
1103 }
1104
1105 void Animation::AnchorPointTo(Actor& actor, const Vector3& anchorPoint, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1106 {
1107   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1108                                                          Dali::Actor::ANCHOR_POINT,
1109                                                          Property::INVALID_COMPONENT_INDEX,
1110                                                          AnimateToVector3(anchorPoint),
1111                                                          alpha,
1112                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1113 }
1114
1115 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, float value )
1116 {
1117   AnimateProperty( shaderEffect, name, value, GetDefaultAlphaFunction(), 0, GetDuration() );
1118 }
1119
1120 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, float value, AlphaFunction alpha )
1121 {
1122   AnimateProperty( shaderEffect, name, value, alpha, 0, GetDuration() );
1123 }
1124
1125 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, float value, AlphaFunction alpha, float delaySeconds, float durationSeconds )
1126 {
1127   Property::Value propertyValue( value );
1128
1129   // Register the property if it does not exist
1130   Property::Index index = shaderEffect.GetPropertyIndex( name );
1131   if ( Property::INVALID_INDEX == index )
1132   {
1133     index = shaderEffect.RegisterProperty( name, propertyValue );
1134   }
1135
1136   AnimateTo( shaderEffect, index, Property::INVALID_COMPONENT_INDEX, propertyValue, alpha, TimePeriod(delaySeconds, durationSeconds) );
1137 }
1138
1139 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector2 value )
1140 {
1141   AnimateProperty( shaderEffect, name, value, GetDefaultAlphaFunction(), 0, GetDuration());
1142 }
1143
1144 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector2 value, AlphaFunction alpha )
1145 {
1146   AnimateProperty( shaderEffect, name, value, alpha, 0, GetDuration() );
1147 }
1148
1149 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector2 value, AlphaFunction alpha, float delaySeconds, float durationSeconds )
1150 {
1151   Property::Value propertyValue( value );
1152
1153   // Register the property if it does not exist
1154   Property::Index index = shaderEffect.GetPropertyIndex( name );
1155   if ( Property::INVALID_INDEX == index )
1156   {
1157     index = shaderEffect.RegisterProperty( name, propertyValue );
1158   }
1159
1160   AnimateTo( shaderEffect, index, Property::INVALID_COMPONENT_INDEX, propertyValue, alpha, TimePeriod(delaySeconds, durationSeconds) );
1161 }
1162
1163 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector3 value )
1164 {
1165   AnimateProperty( shaderEffect, name, value, GetDefaultAlphaFunction(), 0, GetDuration() );
1166 }
1167
1168 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector3 value, AlphaFunction alpha )
1169 {
1170   AnimateProperty( shaderEffect, name, value, alpha, 0, GetDuration() );
1171 }
1172
1173 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector3 value, AlphaFunction alpha, float delaySeconds, float durationSeconds )
1174 {
1175   Property::Value propertyValue( value );
1176
1177   // Register the property if it does not exist
1178   Property::Index index = shaderEffect.GetPropertyIndex( name );
1179   if ( Property::INVALID_INDEX == index )
1180   {
1181     index = shaderEffect.RegisterProperty( name, propertyValue );
1182   }
1183
1184   AnimateTo( shaderEffect, index, Property::INVALID_COMPONENT_INDEX, propertyValue, alpha, TimePeriod(delaySeconds, durationSeconds) );
1185 }
1186
1187 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector4 value )
1188 {
1189   AnimateProperty( shaderEffect, name, value, GetDefaultAlphaFunction(), 0, GetDuration() );
1190 }
1191
1192 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector4 value, AlphaFunction alpha )
1193 {
1194   AnimateProperty( shaderEffect, name, value, alpha, 0, GetDuration() );
1195 }
1196
1197 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector4 value, AlphaFunction alpha, float delaySeconds, float durationSeconds )
1198 {
1199   Property::Value propertyValue( value );
1200
1201   // Register the property if it does not exist
1202   Property::Index index = shaderEffect.GetPropertyIndex( name );
1203   if ( Property::INVALID_INDEX == index )
1204   {
1205     index = shaderEffect.RegisterProperty( name, propertyValue );
1206   }
1207
1208   AnimateTo( shaderEffect, index, Property::INVALID_COMPONENT_INDEX, propertyValue, alpha, TimePeriod(delaySeconds, durationSeconds) );
1209 }
1210
1211 bool Animation::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
1212 {
1213   bool done = false;
1214   Animation* animation = dynamic_cast<Animation*>(object);
1215
1216   if( animation )
1217   {
1218     if(Dali::Animation::ACTION_PLAY == actionName)
1219     {
1220       if(attributes.size() > 0)
1221       {
1222         animation->SetDuration(attributes[0].Get<float>());
1223       }
1224
1225       animation->Play();
1226       done = true;
1227     }
1228     else if(Dali::Animation::ACTION_STOP == actionName)
1229     {
1230       animation->Stop();
1231       done = true;
1232     }
1233     else if(Dali::Animation::ACTION_PAUSE == actionName)
1234     {
1235       animation->Pause();
1236       done = true;
1237     }
1238   }
1239
1240   return done;
1241 }
1242
1243 } // namespace Internal
1244
1245 } // namespace Dali