[dali_1.0.31] 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) 2014 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
209       //Vector3
210       if ( PropertyTypes::Get< Vector3 >() == baseProperty->GetType() )
211       {
212         // Cast to AnimatableProperty of type Vector3
213         const SceneGraph::AnimatableProperty<Vector3>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( baseProperty );
214
215         //Dynamic cast will fail if BaseProperty is not a Vector3 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<Vector3> >::New( *propertyOwner,
223                                                                                                  *animatableProperty,
224                                                                                                  mAnimatorFunction,
225                                                                                                  mAlphaFunction,
226                                                                                                  mTimePeriod );
227             break;
228           }
229           case 1:
230           {
231             mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> >::New( *propertyOwner,
232                                                                                                  *animatableProperty,
233                                                                                                  mAnimatorFunction,
234                                                                                                  mAlphaFunction,
235                                                                                                  mTimePeriod );
236             break;
237           }
238           case 2:
239           {
240             mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> >::New( *propertyOwner,
241                                                                                                  *animatableProperty,
242                                                                                                  mAnimatorFunction,
243                                                                                                  mAlphaFunction,
244                                                                                                  mTimePeriod );
245             break;
246           }
247           default:
248           {
249             break;
250           }
251         }
252       }
253       else if ( PropertyTypes::Get< Vector4 >() == baseProperty->GetType() )
254       {
255         // Animate float component of Vector4 property
256
257         // Cast to AnimatableProperty of type Vector4
258         const SceneGraph::AnimatableProperty<Vector4>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( baseProperty );
259
260         //Dynamic cast will fail if BaseProperty is not a Vector4 AnimatableProperty
261         DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
262
263         switch( mComponentIndex )
264         {
265           case 0:
266           {
267             mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> >::New( *propertyOwner,
268                                                                                                  *animatableProperty,
269                                                                                                  mAnimatorFunction,
270                                                                                                  mAlphaFunction,
271                                                                                                  mTimePeriod );
272             break;
273           }
274           case 1:
275           {
276             mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> >::New( *propertyOwner,
277                                                                                                  *animatableProperty,
278                                                                                                  mAnimatorFunction,
279                                                                                                  mAlphaFunction,
280                                                                                                  mTimePeriod );
281             break;
282           }
283           case 2:
284           {
285             mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> >::New( *propertyOwner,
286                                                                                                  *animatableProperty,
287                                                                                                  mAnimatorFunction,
288                                                                                                  mAlphaFunction,
289                                                                                                  mTimePeriod );
290             break;
291           }
292           case 3:
293           {
294             mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> >::New( *propertyOwner,
295                                                                                                  *animatableProperty,
296                                                                                                  mAnimatorFunction,
297                                                                                                  mAlphaFunction,
298                                                                                                  mTimePeriod );
299             break;
300           }
301
302           default:
303           {
304             break;
305           }
306         }
307       }
308     }
309
310     DALI_ASSERT_DEBUG( mAnimator != NULL );
311
312     //Add the new SceneGraph::Animator to its correspondent SceneGraph::Animation via message to UpdateManager
313     const SceneGraph::Animation* animation = mParent->GetSceneObject();
314     DALI_ASSERT_DEBUG( NULL != animation );
315     AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *mAnimator );
316   }
317
318 protected:
319
320   Object* mObject; ///< Not owned by the animator connector. Valid until ObjectDestroyed() is called.
321   SceneGraph::AnimatorBase* mAnimator;
322
323   Property::Index mPropertyIndex;
324   int mComponentIndex;
325
326   Internal::AnimatorFunctionBase* mAnimatorFunction;  ///< Owned by the animator connector until an Scenegraph::Animator is created
327 };
328
329
330 } // namespace Internal
331
332 } // namespace Dali
333
334 #endif // __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__