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