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