Merge "DALi Version 1.1.26" into devel/master
[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       if( animatableProperty == NULL )
199       {
200         if( baseProperty->IsTransformManagerProperty() )
201         {
202           mAnimator = SceneGraph::AnimatorTransformProperty< PropertyType,TransformManagerPropertyAccessor<PropertyType> >::New( *propertyOwner, *baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
203         }
204         else
205         {
206           DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
207         }
208
209       }
210       else
211       {
212         //Create the animator
213         mAnimator = AnimatorType::New( *propertyOwner, *animatableProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
214       }
215
216     }
217     else
218     {
219       {
220         ///Animating a component of the property
221         if ( PropertyTypes::Get< Vector2 >() == baseProperty->GetType() )
222         {
223           // Animate float component of Vector2 property
224
225           // Cast to AnimatableProperty of type Vector2
226           const SceneGraph::AnimatableProperty<Vector2>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector2>* >( baseProperty );
227           DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
228
229           switch( mComponentIndex )
230           {
231             case 0:
232             {
233               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector2> >::New( *propertyOwner,
234                                                                                                    *animatableProperty,
235                                                                                                    mAnimatorFunction,
236                                                                                                    mAlphaFunction,
237                                                                                                    mTimePeriod );
238               break;
239             }
240             case 1:
241             {
242               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector2> >::New( *propertyOwner,
243                                                                                                    *animatableProperty,
244                                                                                                    mAnimatorFunction,
245                                                                                                    mAlphaFunction,
246                                                                                                    mTimePeriod );
247               break;
248             }
249             default:
250             {
251               break;
252             }
253           }
254         }
255
256         else if ( PropertyTypes::Get< Vector3 >() == baseProperty->GetType() )
257         {
258           // Animate float component of Vector3 property
259           // Cast to AnimatableProperty of type Vector3
260           const SceneGraph::AnimatableProperty<Vector3>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( baseProperty );
261
262           if( animatableProperty == NULL )
263           {
264             if( baseProperty->IsTransformManagerProperty() )
265             {
266               if( mComponentIndex == 0 )
267               {
268                 mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyComponentAccessor<Vector3,0> >::New( *propertyOwner, *baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
269               }
270               else if( mComponentIndex == 1 )
271               {
272                 mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyComponentAccessor<Vector3,1> >::New( *propertyOwner, *baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
273               }
274               else if( mComponentIndex == 2 )
275               {
276                 mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyComponentAccessor<Vector3,2> >::New( *propertyOwner, *baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
277               }
278             }
279             else
280             {
281               DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
282             }
283           }
284           else
285           {
286             //Dynamic cast will fail if BaseProperty is not a Vector3 AnimatableProperty
287             DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
288
289             switch( mComponentIndex )
290             {
291               case 0:
292               {
293                 mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector3> >::New( *propertyOwner,
294                                                                                                      *animatableProperty,
295                                                                                                      mAnimatorFunction,
296                                                                                                      mAlphaFunction,
297                                                                                                      mTimePeriod );
298                 break;
299               }
300               case 1:
301               {
302                 mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> >::New( *propertyOwner,
303                                                                                                      *animatableProperty,
304                                                                                                      mAnimatorFunction,
305                                                                                                      mAlphaFunction,
306                                                                                                      mTimePeriod );
307                 break;
308               }
309               case 2:
310               {
311                 mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> >::New( *propertyOwner,
312                                                                                                      *animatableProperty,
313                                                                                                      mAnimatorFunction,
314                                                                                                      mAlphaFunction,
315                                                                                                      mTimePeriod );
316                 break;
317               }
318               default:
319               {
320                 break;
321               }
322             }
323           }
324         }
325         else if ( PropertyTypes::Get< Vector4 >() == baseProperty->GetType() )
326         {
327           // Animate float component of Vector4 property
328
329           // Cast to AnimatableProperty of type Vector4
330           const SceneGraph::AnimatableProperty<Vector4>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( baseProperty );
331
332           //Dynamic cast will fail if BaseProperty is not a Vector4 AnimatableProperty
333           DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
334
335           switch( mComponentIndex )
336           {
337             case 0:
338             {
339               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> >::New( *propertyOwner,
340                                                                                                    *animatableProperty,
341                                                                                                    mAnimatorFunction,
342                                                                                                    mAlphaFunction,
343                                                                                                    mTimePeriod );
344               break;
345             }
346             case 1:
347             {
348               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> >::New( *propertyOwner,
349                                                                                                    *animatableProperty,
350                                                                                                    mAnimatorFunction,
351                                                                                                    mAlphaFunction,
352                                                                                                    mTimePeriod );
353               break;
354             }
355             case 2:
356             {
357               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> >::New( *propertyOwner,
358                                                                                                    *animatableProperty,
359                                                                                                    mAnimatorFunction,
360                                                                                                    mAlphaFunction,
361                                                                                                    mTimePeriod );
362               break;
363             }
364             case 3:
365             {
366               mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> >::New( *propertyOwner,
367                                                                                                    *animatableProperty,
368                                                                                                    mAnimatorFunction,
369                                                                                                    mAlphaFunction,
370                                                                                                    mTimePeriod );
371               break;
372             }
373
374             default:
375             {
376               break;
377             }
378           }
379         }
380       }
381     }
382
383     DALI_ASSERT_DEBUG( mAnimator != NULL );
384
385     // Add the new SceneGraph::Animator to its correspondent SceneGraph::Animation via message
386     const SceneGraph::Animation* animation = mParent->GetSceneObject();
387     DALI_ASSERT_DEBUG( NULL != animation );
388     AddAnimatorMessage( mParent->GetEventThreadServices(), *animation, *mAnimator );
389   }
390
391 protected:
392
393   Object* mObject; ///< Not owned by the animator connector. Valid until ObjectDestroyed() is called.
394   SceneGraph::AnimatorBase* mAnimator;
395
396   Property::Index mPropertyIndex;
397   int mComponentIndex;
398
399   Internal::AnimatorFunctionBase* mAnimatorFunction;  ///< Owned by the animator connector until an Scenegraph::Animator is created
400 };
401
402
403 } // namespace Internal
404
405 } // namespace Dali
406
407 #endif // __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__