Added funcionality to play animations from an specified initial progress
[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::VECTOR2:
314     {
315       AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
316                                                              target.propertyIndex,
317                                                              target.componentIndex,
318                                                              AnimateByVector2(relativeValue.Get<Vector2>()),
319                                                              alpha,
320                                                              period ) );
321       break;
322     }
323
324     case Property::VECTOR3:
325     {
326       AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
327                                                              target.propertyIndex,
328                                                              target.componentIndex,
329                                                              AnimateByVector3(relativeValue.Get<Vector3>()),
330                                                              alpha,
331                                                              period ) );
332       break;
333     }
334
335     case Property::VECTOR4:
336     {
337       AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
338                                                              target.propertyIndex,
339                                                              target.componentIndex,
340                                                              AnimateByVector4(relativeValue.Get<Vector4>()),
341                                                              alpha,
342                                                              period ) );
343       break;
344     }
345
346     case Property::ROTATION:
347     {
348       AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
349
350       AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
351                                                                 target.propertyIndex,
352                                                                 target.componentIndex,
353                                                                 RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
354                                                                 alpha,
355                                                                 period ) );
356       break;
357     }
358
359     default:
360       DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
361       break;
362   }
363 }
364
365 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
366 {
367   AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
368 }
369
370 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
371 {
372   AnimateTo(target, destinationValue, alpha, mDurationSeconds);
373 }
374
375 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
376 {
377   AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
378 }
379
380 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
381 {
382   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
383
384   AnimateTo( proxy, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
385 }
386
387 void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
388 {
389   Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
390   if(componentIndex != Property::INVALID_COMPONENT_INDEX)
391   {
392     if( type == Property::VECTOR2
393         || type == Property::VECTOR3
394         || type == Property::VECTOR4 )
395     {
396       type = Property::FLOAT;
397     }
398   }
399   DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
400
401   switch (destinationValue.GetType())
402   {
403     case Property::BOOLEAN:
404     {
405       AddAnimatorConnector( AnimatorConnector<bool>::New(targetObject,
406                                                          targetPropertyIndex,
407                                                          componentIndex,
408                                                          AnimateToBoolean(destinationValue.Get<bool>()),
409                                                          alpha,
410                                                          period) );
411       break;
412     }
413
414     case Property::FLOAT:
415     {
416       AddAnimatorConnector( AnimatorConnector<float>::New(targetObject,
417                                                           targetPropertyIndex,
418                                                           componentIndex,
419                                                           AnimateToFloat(destinationValue.Get<float>()),
420                                                           alpha,
421                                                           period) );
422       break;
423     }
424
425     case Property::VECTOR2:
426     {
427       AddAnimatorConnector( AnimatorConnector<Vector2>::New(targetObject,
428                                                             targetPropertyIndex,
429                                                             componentIndex,
430                                                             AnimateToVector2(destinationValue.Get<Vector2>()),
431                                                             alpha,
432                                                             period) );
433       break;
434     }
435
436     case Property::VECTOR3:
437     {
438       if ( Dali::Actor::SIZE == targetPropertyIndex )
439       {
440         // Test whether this is actually an Actor
441         Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
442         if ( maybeActor )
443         {
444           // Notify the actor that its size is being animated
445           maybeActor->OnSizeAnimation( *this, destinationValue.Get<Vector3>() );
446         }
447       }
448
449       AddAnimatorConnector( AnimatorConnector<Vector3>::New(targetObject,
450                                                             targetPropertyIndex,
451                                                             componentIndex,
452                                                             AnimateToVector3(destinationValue.Get<Vector3>()),
453                                                             alpha,
454                                                             period) );
455       break;
456     }
457
458     case Property::VECTOR4:
459     {
460       AddAnimatorConnector( AnimatorConnector<Vector4>::New(targetObject,
461                                                             targetPropertyIndex,
462                                                             componentIndex,
463                                                             AnimateToVector4(destinationValue.Get<Vector4>()),
464                                                             alpha,
465                                                             period) );
466       break;
467     }
468
469     case Property::ROTATION:
470     {
471       AddAnimatorConnector( AnimatorConnector<Quaternion>::New(targetObject,
472                                                                targetPropertyIndex,
473                                                                componentIndex,
474                                                                RotateToQuaternion(destinationValue.Get<Quaternion>()),
475                                                                alpha,
476                                                                period) );
477       break;
478     }
479
480     default:
481       DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
482       break;
483   }
484 }
485
486 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
487 {
488   AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds);
489 }
490
491 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
492 {
493   AnimateBetween(target, keyFrames, mDefaultAlpha, period);
494 }
495
496 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
497 {
498   AnimateBetween(target, keyFrames, alpha, mDurationSeconds);
499 }
500
501 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
502 {
503   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
504
505   switch(keyFrames.GetType())
506   {
507     case Dali::Property::BOOLEAN:
508     {
509       const KeyFrameBoolean* kf;
510       GetSpecialization(keyFrames, kf);
511       KeyFrameBooleanPtr kfCopy = KeyFrameBoolean::Clone(*kf);
512       AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
513                                                           target.propertyIndex,
514                                                           target.componentIndex,
515                                                           KeyFrameBooleanFunctor(kfCopy),
516                                                           alpha,
517                                                           period ) );
518       break;
519     }
520     case Dali::Property::FLOAT:
521     {
522       const KeyFrameNumber* kf;
523       GetSpecialization(keyFrames, kf);
524       KeyFrameNumberPtr kfCopy = KeyFrameNumber::Clone(*kf);
525       AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
526                                                            target.propertyIndex,
527                                                            target.componentIndex,
528                                                            KeyFrameNumberFunctor(kfCopy),
529                                                            alpha,
530                                                            period ) );
531       break;
532     }
533
534     case Dali::Property::VECTOR2:
535     {
536       const KeyFrameVector2* kf;
537       GetSpecialization(keyFrames, kf);
538       KeyFrameVector2Ptr kfCopy = KeyFrameVector2::Clone(*kf);
539       AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
540                                                              target.propertyIndex,
541                                                              target.componentIndex,
542                                                              KeyFrameVector2Functor(kfCopy),
543                                                              alpha,
544                                                              period ) );
545       break;
546     }
547
548     case Dali::Property::VECTOR3:
549     {
550       const KeyFrameVector3* kf;
551       GetSpecialization(keyFrames, kf);
552       KeyFrameVector3Ptr kfCopy = KeyFrameVector3::Clone(*kf);
553       AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
554                                                              target.propertyIndex,
555                                                              target.componentIndex,
556                                                              KeyFrameVector3Functor(kfCopy),
557                                                              alpha,
558                                                              period ) );
559       break;
560     }
561
562     case Dali::Property::VECTOR4:
563     {
564       const KeyFrameVector4* kf;
565       GetSpecialization(keyFrames, kf);
566       KeyFrameVector4Ptr kfCopy = KeyFrameVector4::Clone(*kf);
567       AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
568                                                              target.propertyIndex,
569                                                              target.componentIndex,
570                                                              KeyFrameVector4Functor(kfCopy),
571                                                              alpha,
572                                                              period ) );
573       break;
574     }
575
576     case Dali::Property::ROTATION:
577     {
578       const KeyFrameQuaternion* kf;
579       GetSpecialization(keyFrames, kf);
580       KeyFrameQuaternionPtr kfCopy = KeyFrameQuaternion::Clone(*kf);
581       AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
582                                                                 target.propertyIndex,
583                                                                 target.componentIndex,
584                                                                 KeyFrameQuaternionFunctor(kfCopy),
585                                                                 alpha,
586                                                                 period ) );
587       break;
588     }
589
590     default: // not all property types are animateable
591       break;
592   }
593 }
594
595 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func )
596 {
597   Animate( target, targetType, func, mDefaultAlpha, mDurationSeconds );
598 }
599
600 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, AlphaFunction& alpha )
601 {
602   Animate( target, targetType, func, alpha, mDurationSeconds );
603 }
604
605 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, TimePeriod period )
606 {
607   Animate( target, targetType, func, mDefaultAlpha, period );
608 }
609
610 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, AlphaFunction& alpha, TimePeriod period )
611 {
612   Property::Type type = target.object.GetPropertyType(target.propertyIndex);
613   if(target.componentIndex != Property::INVALID_COMPONENT_INDEX)
614   {
615     if( type == Property::VECTOR2
616         || type == Property::VECTOR3
617         || type == Property::VECTOR4 )
618     {
619       type = Property::FLOAT;
620     }
621   }
622   DALI_ASSERT_ALWAYS( type == targetType && "Animation function must match target property type" );
623
624   ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
625
626   switch ( targetType )
627   {
628     case Property::BOOLEAN:
629     {
630       AddAnimatorConnector( AnimatorConnector<bool>::New(proxy,
631                                                          target.propertyIndex,
632                                                          target.componentIndex,
633                                                          AnyCast< AnimatorFunctionBool >( func ),
634                                                          alpha,
635                                                          period) );
636       break;
637     }
638
639     case Property::FLOAT:
640     {
641       AddAnimatorConnector( AnimatorConnector<float>::New(proxy,
642                                                           target.propertyIndex,
643                                                           target.componentIndex,
644                                                           AnyCast< AnimatorFunctionFloat >( func ),
645                                                           alpha,
646                                                           period) );
647       break;
648     }
649
650     case Property::VECTOR2:
651     {
652       AddAnimatorConnector( AnimatorConnector<Vector2>::New(proxy,
653                                                             target.propertyIndex,
654                                                             target.componentIndex,
655                                                             AnyCast< AnimatorFunctionVector2 >( func ),
656                                                             alpha,
657                                                             period) );
658       break;
659     }
660
661     case Property::VECTOR3:
662     {
663       AddAnimatorConnector( AnimatorConnector<Vector3>::New(proxy,
664                                                             target.propertyIndex,
665                                                             target.componentIndex,
666                                                             AnyCast< AnimatorFunctionVector3 >( func ),
667                                                             alpha,
668                                                             period) );
669       break;
670     }
671
672     case Property::VECTOR4:
673     {
674       AddAnimatorConnector( AnimatorConnector<Vector4>::New(proxy,
675                                                             target.propertyIndex,
676                                                             target.componentIndex,
677                                                             AnyCast< AnimatorFunctionVector4 >( func ),
678                                                             alpha,
679                                                             period) );
680       break;
681     }
682
683     case Property::ROTATION:
684     {
685       AddAnimatorConnector( AnimatorConnector<Quaternion>::New(proxy,
686                                                                target.propertyIndex,
687                                                                target.componentIndex,
688                                                                AnyCast< AnimatorFunctionQuaternion >( func ),
689                                                                alpha,
690                                                                period) );
691       break;
692     }
693
694     default:
695       DALI_ASSERT_ALWAYS(false && "Property type enumeration out of bounds" ); // should never come here
696       break;
697   }
698 }
699
700 bool Animation::HasFinished()
701 {
702   bool hasFinished(false);
703   const int playCount(mAnimation->GetPlayCount());
704
705   // If the play count has been incremented, then another notification is required
706   if (playCount > mNotificationCount)
707   {
708     // Note that only one signal is emitted, if the animation has been played repeatedly
709     mNotificationCount = playCount;
710
711     hasFinished = true;
712   }
713
714   return hasFinished;
715 }
716
717 Dali::Animation::AnimationSignalV2& Animation::FinishedSignal()
718 {
719   return mFinishedSignal;
720 }
721
722 void Animation::EmitSignalFinish()
723 {
724   if ( !mFinishedSignal.Empty() )
725   {
726     Dali::Animation handle( this );
727     mFinishedSignal.Emit( handle );
728   }
729
730   // This callback is used internally, to avoid the overhead of using a signal.
731   if ( mFinishedCallback )
732   {
733     mFinishedCallback( mFinishedCallbackObject );
734   }
735 }
736
737 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
738 {
739   bool connected( true );
740   Animation* animation = dynamic_cast<Animation*>(object);
741
742   if ( Dali::Animation::SIGNAL_FINISHED == signalName )
743   {
744     animation->FinishedSignal().Connect( tracker, functor );
745   }
746   else
747   {
748     // signalName does not match any signal
749     connected = false;
750   }
751
752   return connected;
753 }
754
755 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
756 {
757   mFinishedCallback = callback;
758   mFinishedCallbackObject = object;
759 }
760
761 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
762 {
763   DALI_ASSERT_DEBUG( NULL != connector );
764
765   connector->SetParent(*this);
766
767   mConnectors.PushBack( connector );
768 }
769
770 void Animation::MoveBy(Actor& actor, float x, float y, float z)
771 {
772   MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
773 }
774
775 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
776 {
777   MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
778 }
779
780 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
781 {
782   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
783                                                          Dali::Actor::POSITION,
784                                                          Property::INVALID_COMPONENT_INDEX,
785                                                          AnimateByVector3(displacement),
786                                                          alpha,
787                                                          TimePeriod(delaySeconds, durationSeconds) ) );
788 }
789
790 void Animation::MoveTo(Actor& actor, float x, float y, float z)
791 {
792   MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
793 }
794
795 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
796 {
797   MoveTo(actor, position, alpha, 0.0f, GetDuration());
798 }
799
800 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha,  float delaySeconds, float durationSeconds)
801 {
802   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
803                                                          Dali::Actor::POSITION,
804                                                          Property::INVALID_COMPONENT_INDEX,
805                                                          AnimateToVector3(position),
806                                                          alpha,
807                                                          TimePeriod(delaySeconds, durationSeconds) ) );
808 }
809
810 void Animation::Move(Actor& actor, AnimatorFunctionVector3 func, AlphaFunction alpha,  float delaySeconds, float durationSeconds)
811 {
812   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
813                                                          Dali::Actor::POSITION,
814                                                          Property::INVALID_COMPONENT_INDEX,
815                                                          func,
816                                                          alpha,
817                                                          TimePeriod(delaySeconds, durationSeconds) ) );
818 }
819
820 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
821 {
822   RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
823 }
824
825 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
826 {
827   RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
828 }
829
830 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
831 {
832   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
833                                                             Dali::Actor::ROTATION,
834                                                             Property::INVALID_COMPONENT_INDEX,
835                                                             RotateByAngleAxis(angle, axis),
836                                                             alpha,
837                                                             TimePeriod(delaySeconds, durationSeconds) ) );
838 }
839
840 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
841 {
842   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
843   normalizedAxis.Normalize();
844
845   Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
846
847   RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
848 }
849
850 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
851 {
852   RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
853 }
854
855 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
856 {
857   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
858   normalizedAxis.Normalize();
859
860   Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
861
862   RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
863 }
864
865 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
866 {
867   RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
868 }
869
870 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
871 {
872   Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
873   normalizedAxis.Normalize();
874
875   Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
876
877   RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
878 }
879
880 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
881 {
882   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
883                                                             Dali::Actor::ROTATION,
884                                                             Property::INVALID_COMPONENT_INDEX,
885                                                             RotateToQuaternion(rotation),
886                                                             alpha,
887                                                             TimePeriod(delaySeconds, durationSeconds) ) );
888 }
889
890 void Animation::Rotate(Actor& actor, AnimatorFunctionQuaternion func, AlphaFunction alpha,  float delaySeconds, float durationSeconds)
891 {
892   AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
893                                                             Dali::Actor::ROTATION,
894                                                             Property::INVALID_COMPONENT_INDEX,
895                                                             func,
896                                                             alpha,
897                                                             TimePeriod(delaySeconds, durationSeconds) ) );
898 }
899
900 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
901 {
902   ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
903 }
904
905 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
906 {
907   ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
908 }
909
910 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
911 {
912   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
913                                                          Dali::Actor::SCALE,
914                                                          Property::INVALID_COMPONENT_INDEX,
915                                                          AnimateByVector3(scale),
916                                                          alpha,
917                                                          TimePeriod(delaySeconds, durationSeconds) ) );
918 }
919
920 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
921 {
922   ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
923 }
924
925 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
926 {
927   ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
928 }
929
930 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
931 {
932   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
933                                                          Dali::Actor::SCALE,
934                                                          Property::INVALID_COMPONENT_INDEX,
935                                                          AnimateToVector3(scale),
936                                                          alpha,
937                                                          TimePeriod(delaySeconds, durationSeconds) ) );
938 }
939
940 void Animation::Show(Actor& actor, float delaySeconds)
941 {
942   AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
943                                                       Dali::Actor::VISIBLE,
944                                                       Property::INVALID_COMPONENT_INDEX,
945                                                       AnimateToBoolean(SHOW_VALUE),
946                                                       AlphaFunctions::Default,
947                                                       TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
948 }
949
950 void Animation::Hide(Actor& actor, float delaySeconds)
951 {
952   AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
953                                                       Dali::Actor::VISIBLE,
954                                                       Property::INVALID_COMPONENT_INDEX,
955                                                       AnimateToBoolean(HIDE_VALUE),
956                                                       AlphaFunctions::Default,
957                                                       TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
958 }
959
960 void Animation::OpacityBy(Actor& actor, float opacity)
961 {
962   OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
963 }
964
965 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
966 {
967   OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
968 }
969
970 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
971 {
972   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
973                                                          Dali::Actor::COLOR,
974                                                          Property::INVALID_COMPONENT_INDEX,
975                                                          AnimateByOpacity(opacity),
976                                                          alpha,
977                                                          TimePeriod(delaySeconds, durationSeconds) ) );
978 }
979
980 void Animation::OpacityTo(Actor& actor, float opacity)
981 {
982   OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
983 }
984
985 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
986 {
987   OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
988 }
989
990 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
991 {
992   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
993                                                          Dali::Actor::COLOR,
994                                                          Property::INVALID_COMPONENT_INDEX,
995                                                          AnimateToOpacity(opacity),
996                                                          alpha,
997                                                          TimePeriod(delaySeconds, durationSeconds) ) );
998 }
999
1000 void Animation::ColorBy(Actor& actor, const Vector4& color)
1001 {
1002   ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1003 }
1004
1005 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
1006 {
1007   ColorBy(actor, color, alpha, 0.0f, GetDuration());
1008 }
1009
1010 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1011 {
1012   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1013                                                          Dali::Actor::COLOR,
1014                                                          Property::INVALID_COMPONENT_INDEX,
1015                                                          AnimateByVector4(color),
1016                                                          alpha,
1017                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1018 }
1019
1020 void Animation::ColorTo(Actor& actor, const Vector4& color)
1021 {
1022   ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1023 }
1024
1025 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
1026 {
1027   ColorTo(actor, color, alpha, 0.0f, GetDuration());
1028 }
1029
1030 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1031 {
1032   AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1033                                                          Dali::Actor::COLOR,
1034                                                          Property::INVALID_COMPONENT_INDEX,
1035                                                          AnimateToVector4(color),
1036                                                          alpha,
1037                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1038 }
1039
1040 void Animation::Resize(Actor& actor, float width, float height)
1041 {
1042   Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
1043 }
1044
1045 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
1046 {
1047   Resize(actor, width, height, alpha, 0.0f, GetDuration());
1048 }
1049
1050 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1051 {
1052   Vector3 targetSize( width, height, min(width, height) );
1053
1054   // notify the actor impl that its size is being animated
1055   actor.OnSizeAnimation( *this, targetSize );
1056
1057   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1058                                                          Dali::Actor::SIZE,
1059                                                          Property::INVALID_COMPONENT_INDEX,
1060                                                          AnimateToVector3(targetSize),
1061                                                          alpha,
1062                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1063 }
1064
1065 void Animation::Resize(Actor& actor, const Vector3& size)
1066 {
1067   Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1068 }
1069
1070 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1071 {
1072   Resize(actor, size, alpha, 0.0f, GetDuration());
1073 }
1074
1075 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1076 {
1077   // notify the actor impl that its size is being animated
1078   actor.OnSizeAnimation( *this, size );
1079
1080   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1081                                                          Dali::Actor::SIZE,
1082                                                          Property::INVALID_COMPONENT_INDEX,
1083                                                          AnimateToVector3(size),
1084                                                          alpha,
1085                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1086 }
1087
1088 void Animation::ParentOriginTo(Actor& actor, const Vector3& parentOrigin)
1089 {
1090   ParentOriginTo(actor, parentOrigin, mDefaultAlpha, 0.0f, GetDuration());
1091 }
1092
1093 void Animation::ParentOriginTo(Actor& actor, const Vector3& parentOrigin, AlphaFunction alpha)
1094 {
1095   ParentOriginTo(actor, parentOrigin, alpha, 0.0f, GetDuration());
1096 }
1097
1098 void Animation::ParentOriginTo(Actor& actor, const Vector3& parentOrigin, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1099 {
1100   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1101                                                          Dali::Actor::PARENT_ORIGIN,
1102                                                          Property::INVALID_COMPONENT_INDEX,
1103                                                          AnimateToVector3(parentOrigin),
1104                                                          alpha,
1105                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1106 }
1107
1108 void Animation::AnchorPointTo(Actor& actor, const Vector3& anchorPoint)
1109 {
1110   AnchorPointTo(actor, anchorPoint, mDefaultAlpha, 0.0f, GetDuration());
1111 }
1112
1113 void Animation::AnchorPointTo(Actor& actor, const Vector3& anchorPoint, AlphaFunction alpha)
1114 {
1115   AnchorPointTo(actor, anchorPoint, alpha, 0.0f, GetDuration());
1116 }
1117
1118 void Animation::AnchorPointTo(Actor& actor, const Vector3& anchorPoint, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1119 {
1120   AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1121                                                          Dali::Actor::ANCHOR_POINT,
1122                                                          Property::INVALID_COMPONENT_INDEX,
1123                                                          AnimateToVector3(anchorPoint),
1124                                                          alpha,
1125                                                          TimePeriod(delaySeconds, durationSeconds) ) );
1126 }
1127
1128 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, float value )
1129 {
1130   AnimateProperty( shaderEffect, name, value, GetDefaultAlphaFunction(), 0, GetDuration() );
1131 }
1132
1133 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, float value, AlphaFunction alpha )
1134 {
1135   AnimateProperty( shaderEffect, name, value, alpha, 0, GetDuration() );
1136 }
1137
1138 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, float value, AlphaFunction alpha, float delaySeconds, float durationSeconds )
1139 {
1140   Property::Value propertyValue( value );
1141
1142   // Register the property if it does not exist
1143   Property::Index index = shaderEffect.GetPropertyIndex( name );
1144   if ( Property::INVALID_INDEX == index )
1145   {
1146     index = shaderEffect.RegisterProperty( name, propertyValue );
1147   }
1148
1149   AnimateTo( shaderEffect, index, Property::INVALID_COMPONENT_INDEX, propertyValue, alpha, TimePeriod(delaySeconds, durationSeconds) );
1150 }
1151
1152 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector2 value )
1153 {
1154   AnimateProperty( shaderEffect, name, value, GetDefaultAlphaFunction(), 0, GetDuration());
1155 }
1156
1157 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector2 value, AlphaFunction alpha )
1158 {
1159   AnimateProperty( shaderEffect, name, value, alpha, 0, GetDuration() );
1160 }
1161
1162 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector2 value, AlphaFunction alpha, float delaySeconds, float durationSeconds )
1163 {
1164   Property::Value propertyValue( value );
1165
1166   // Register the property if it does not exist
1167   Property::Index index = shaderEffect.GetPropertyIndex( name );
1168   if ( Property::INVALID_INDEX == index )
1169   {
1170     index = shaderEffect.RegisterProperty( name, propertyValue );
1171   }
1172
1173   AnimateTo( shaderEffect, index, Property::INVALID_COMPONENT_INDEX, propertyValue, alpha, TimePeriod(delaySeconds, durationSeconds) );
1174 }
1175
1176 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector3 value )
1177 {
1178   AnimateProperty( shaderEffect, name, value, GetDefaultAlphaFunction(), 0, GetDuration() );
1179 }
1180
1181 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector3 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, Vector3 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, Vector4 value )
1201 {
1202   AnimateProperty( shaderEffect, name, value, GetDefaultAlphaFunction(), 0, GetDuration() );
1203 }
1204
1205 void Animation::AnimateProperty( Internal::ShaderEffect& shaderEffect, const std::string& name, Vector4 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, Vector4 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 bool Animation::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
1225 {
1226   bool done = false;
1227   Animation* animation = dynamic_cast<Animation*>(object);
1228
1229   if( animation )
1230   {
1231     if(Dali::Animation::ACTION_PLAY == actionName)
1232     {
1233       if(attributes.size() > 0)
1234       {
1235         animation->SetDuration(attributes[0].Get<float>());
1236       }
1237
1238       animation->Play();
1239       done = true;
1240     }
1241     else if(Dali::Animation::ACTION_STOP == actionName)
1242     {
1243       animation->Stop();
1244       done = true;
1245     }
1246     else if(Dali::Animation::ACTION_PAUSE == actionName)
1247     {
1248       animation->Pause();
1249       done = true;
1250     }
1251   }
1252
1253   return done;
1254 }
1255
1256 float Animation::GetCurrentProgress()
1257 {
1258   if( mAnimation )
1259   {
1260     return mAnimation->GetCurrentProgress();
1261   }
1262
1263   return 0.0f;
1264 }
1265
1266 void Animation::SetCurrentProgress(float progress)
1267 {
1268   if( mAnimation && progress >= 0.0f && progress <= 1.0f )
1269   {
1270     // mAnimation is being used in a separate thread; queue a message to set the current progress
1271     SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
1272   }
1273 }
1274
1275 } // namespace Internal
1276
1277 } // namespace Dali