Added Getters for Animator Connectors base class
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / animator-connector.h
1 #ifndef __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__
2 #define __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__
3
4 /*
5  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/event/animation/animator-connector-base.h>
23 #include <dali/internal/event/animation/animation-impl.h>
24 #include <dali/internal/update/common/property-owner.h>
25 #include <dali/internal/update/animation/property-accessor.h>
26 #include <dali/internal/update/animation/property-component-accessor.h>
27 #include <dali/internal/update/manager/update-manager.h>
28
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 /**
36  * AnimatorConnector is used to connect SceneGraph::Animators for newly created scene-graph objects.
37  *
38  * SceneGraph::Animators weakly reference scene objects, and are automatically deleted when orphaned.
39  * Therefore the AnimatorConnector is NOT responsible for disconnecting animators.
40  */
41 template < typename PropertyType >
42 class AnimatorConnector : public AnimatorConnectorBase
43 {
44 public:
45
46   typedef SceneGraph::Animator< PropertyType, PropertyAccessor<PropertyType> > AnimatorType;
47   typedef SceneGraph::AnimatableProperty< PropertyType > PropertyInterfaceType;
48
49   /**
50    * Construct a new animator connector.
51    * @param[in] object The object for a scene-graph object to animate.
52    * @param[in] propertyIndex The index of a property provided by the object.
53    * @param[in] componentIndex Index to a sub component of a property, for use with Vector2, Vector3 and Vector4 (INVALID_PROPERTY_COMPONENTINDEX to use the whole property)
54    * @param[in] animatorFunction A function used to animate the property.
55    * @param[in] alpha The alpha function to apply.
56    * @param[in] period The time period of the animator.
57    * @return A pointer to a newly allocated animator connector.
58    */
59   static AnimatorConnectorBase* New( Object& object,
60                                      Property::Index propertyIndex,
61                                      int componentIndex,
62                                      AnimatorFunctionBase* animatorFunction,
63                                      AlphaFunction alpha,
64                                      const TimePeriod& period )
65   {
66     return new AnimatorConnector< PropertyType >( object,
67                                                   propertyIndex,
68                                                   componentIndex,
69                                                   animatorFunction,
70                                                   alpha,
71                                                   period );
72   }
73
74   /**
75    * Virtual destructor.
76    */
77   virtual ~AnimatorConnector()
78   {
79     if( mObject )
80     {
81       mObject->RemoveObserver( *this );
82     }
83
84     //If there is not a SceneGraph::Animator, the AnimatorConnector is responsible for deleting the mAnimatorFunction
85     //otherwise, the animator function ownership is transferred to the SceneGraph::Animator
86     if( !mAnimator )
87     {
88       delete mAnimatorFunction;
89       mAnimatorFunction = 0;
90     }
91   }
92
93   /**
94    * From AnimatorConnectorBase.
95    * This is only expected to be called once, when added to an Animation.
96    */
97   void SetParent( Animation& parent )
98   {
99     DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent" );
100     mParent = &parent;
101
102     if( mObject && mObject->GetSceneObject() )
103     {
104       CreateAnimator();
105     }
106   }
107
108 private:
109
110   /**
111    * Private constructor; see also AnimatorConnector::New().
112    */
113   AnimatorConnector( Object& object,
114                      Property::Index propertyIndex,
115                      int componentIndex,
116                      Internal::AnimatorFunctionBase* animatorFunction,
117                      AlphaFunction alpha,
118                      const TimePeriod& period )
119   : AnimatorConnectorBase( object, propertyIndex, componentIndex, alpha, period ),
120     mAnimator(0),
121     mAnimatorFunction( animatorFunction )
122   {
123   }
124
125   // Undefined
126   AnimatorConnector( const AnimatorConnector& );
127
128   // Undefined
129   AnimatorConnector& operator=( const AnimatorConnector& rhs );
130
131   /**
132    * From Object::Observer
133    */
134   virtual void SceneObjectAdded( Object& object )
135   {
136     //If the animator has not been created yet, create it now.
137     if( !mAnimator && mObject )
138     {
139       CreateAnimator();
140     }
141   }
142
143    /**
144    * Helper function to create a Scenegraph::Animator and add it to its correspondent SceneGraph::Animation.
145    * @note This function will only be called the first time the object is added to the scene or at creation time if
146    * the object was already in the scene
147    */
148   void CreateAnimator()
149   {
150     DALI_ASSERT_DEBUG( mAnimator == NULL );
151     DALI_ASSERT_DEBUG( mAnimatorFunction != NULL );
152     DALI_ASSERT_DEBUG( mParent != NULL );
153
154     //Get the PropertyOwner the animator is going to animate
155     const SceneGraph::PropertyOwner* propertyOwner = mObject->GetSceneObject();
156
157     //Get SceneGraph::BaseProperty
158     const SceneGraph::PropertyBase* baseProperty = mObject->GetSceneObjectAnimatableProperty( mPropertyIndex );
159
160     //Check if property is a component of another property
161     const int componentIndex = mObject->GetPropertyComponentIndex( mPropertyIndex );
162     if( componentIndex != Property::INVALID_COMPONENT_INDEX )
163     {
164       mComponentIndex = componentIndex;
165     }
166
167     if( mComponentIndex == Property::INVALID_COMPONENT_INDEX )
168     {
169       ///Animating the whole property
170
171       //Cast to AnimatableProperty
172       const PropertyInterfaceType* animatableProperty = dynamic_cast< const PropertyInterfaceType* >( baseProperty );
173
174       if( animatableProperty == NULL )
175       {
176         if( baseProperty->IsTransformManagerProperty() )
177         {
178           mAnimator = SceneGraph::AnimatorTransformProperty< PropertyType,TransformManagerPropertyAccessor<PropertyType> >::New( *propertyOwner, *baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
179         }
180         else
181         {
182           DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
183         }
184
185       }
186       else
187       {
188         //Create the animator
189         mAnimator = AnimatorType::New( *propertyOwner, *animatableProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
190       }
191
192     }
193     else
194     {
195       {
196         ///Animating a component of the property
197         if ( PropertyTypes::Get< Vector2 >() == baseProperty->GetType() )
198         {
199           // Animate float component of Vector2 property
200
201           // Cast to AnimatableProperty of type Vector2
202           const SceneGraph::AnimatableProperty<Vector2>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector2>* >( baseProperty );
203           DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
204
205           switch( mComponentIndex )
206           {
207             case 0:
208             {
209               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector2> >::New( *propertyOwner,
210                                                                                                    *animatableProperty,
211                                                                                                    mAnimatorFunction,
212                                                                                                    mAlphaFunction,
213                                                                                                    mTimePeriod );
214               break;
215             }
216             case 1:
217             {
218               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector2> >::New( *propertyOwner,
219                                                                                                    *animatableProperty,
220                                                                                                    mAnimatorFunction,
221                                                                                                    mAlphaFunction,
222                                                                                                    mTimePeriod );
223               break;
224             }
225             default:
226             {
227               break;
228             }
229           }
230         }
231
232         else if ( PropertyTypes::Get< Vector3 >() == baseProperty->GetType() )
233         {
234           // Animate float component of Vector3 property
235           // Cast to AnimatableProperty of type Vector3
236           const SceneGraph::AnimatableProperty<Vector3>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( baseProperty );
237
238           if( animatableProperty == NULL )
239           {
240             if( baseProperty->IsTransformManagerProperty() )
241             {
242               if( mComponentIndex == 0 )
243               {
244                 mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyComponentAccessor<Vector3,0> >::New( *propertyOwner, *baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
245               }
246               else if( mComponentIndex == 1 )
247               {
248                 mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyComponentAccessor<Vector3,1> >::New( *propertyOwner, *baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
249               }
250               else if( mComponentIndex == 2 )
251               {
252                 mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyComponentAccessor<Vector3,2> >::New( *propertyOwner, *baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
253               }
254             }
255             else
256             {
257               DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
258             }
259           }
260           else
261           {
262             //Dynamic cast will fail if BaseProperty is not a Vector3 AnimatableProperty
263             DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
264
265             switch( mComponentIndex )
266             {
267               case 0:
268               {
269                 mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector3> >::New( *propertyOwner,
270                                                                                                      *animatableProperty,
271                                                                                                      mAnimatorFunction,
272                                                                                                      mAlphaFunction,
273                                                                                                      mTimePeriod );
274                 break;
275               }
276               case 1:
277               {
278                 mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> >::New( *propertyOwner,
279                                                                                                      *animatableProperty,
280                                                                                                      mAnimatorFunction,
281                                                                                                      mAlphaFunction,
282                                                                                                      mTimePeriod );
283                 break;
284               }
285               case 2:
286               {
287                 mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> >::New( *propertyOwner,
288                                                                                                      *animatableProperty,
289                                                                                                      mAnimatorFunction,
290                                                                                                      mAlphaFunction,
291                                                                                                      mTimePeriod );
292                 break;
293               }
294               default:
295               {
296                 break;
297               }
298             }
299           }
300         }
301         else if ( PropertyTypes::Get< Vector4 >() == baseProperty->GetType() )
302         {
303           // Animate float component of Vector4 property
304
305           // Cast to AnimatableProperty of type Vector4
306           const SceneGraph::AnimatableProperty<Vector4>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( baseProperty );
307
308           //Dynamic cast will fail if BaseProperty is not a Vector4 AnimatableProperty
309           DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
310
311           switch( mComponentIndex )
312           {
313             case 0:
314             {
315               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> >::New( *propertyOwner,
316                                                                                                    *animatableProperty,
317                                                                                                    mAnimatorFunction,
318                                                                                                    mAlphaFunction,
319                                                                                                    mTimePeriod );
320               break;
321             }
322             case 1:
323             {
324               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> >::New( *propertyOwner,
325                                                                                                    *animatableProperty,
326                                                                                                    mAnimatorFunction,
327                                                                                                    mAlphaFunction,
328                                                                                                    mTimePeriod );
329               break;
330             }
331             case 2:
332             {
333               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> >::New( *propertyOwner,
334                                                                                                    *animatableProperty,
335                                                                                                    mAnimatorFunction,
336                                                                                                    mAlphaFunction,
337                                                                                                    mTimePeriod );
338               break;
339             }
340             case 3:
341             {
342               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> >::New( *propertyOwner,
343                                                                                                    *animatableProperty,
344                                                                                                    mAnimatorFunction,
345                                                                                                    mAlphaFunction,
346                                                                                                    mTimePeriod );
347               break;
348             }
349
350             default:
351             {
352               break;
353             }
354           }
355         }
356       }
357     }
358
359     DALI_ASSERT_DEBUG( mAnimator != NULL );
360
361     // Add the new SceneGraph::Animator to its correspondent SceneGraph::Animation via message
362     const SceneGraph::Animation* animation = mParent->GetSceneObject();
363     DALI_ASSERT_DEBUG( NULL != animation );
364     AddAnimatorMessage( mParent->GetEventThreadServices(), *animation, *mAnimator );
365   }
366
367 protected:
368
369   SceneGraph::AnimatorBase* mAnimator;
370
371   Internal::AnimatorFunctionBase* mAnimatorFunction;  ///< Owned by the animator connector until an Scenegraph::Animator is created
372 };
373
374
375 } // namespace Internal
376
377 } // namespace Dali
378
379 #endif // __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__