Merge "Clean up the code to build successfully on macOS" 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) 2019 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 //EXTERNAL INCLUDES
22 #include <functional>
23
24 // INTERNAL INCLUDES
25 #include <dali/internal/event/animation/animator-connector-base.h>
26 #include <dali/internal/event/animation/animation-impl.h>
27 #include <dali/internal/update/common/property-owner.h>
28 #include <dali/internal/update/animation/property-accessor.h>
29 #include <dali/internal/update/animation/property-component-accessor.h>
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 /**
38  * AnimatorConnector is used to connect SceneGraph::Animators.
39  *
40  * SceneGraph::Animators weakly reference scene objects, and are automatically deleted when orphaned.
41  * Therefore the AnimatorConnector is NOT responsible for disconnecting animators.
42  * This is the common template for non float properties, there's a specialization for float properties as they can be component properties
43  */
44 template < typename PropertyType >
45 class AnimatorConnector : public AnimatorConnectorBase
46 {
47   using AnimatorFunction = std::function<PropertyType(float, const PropertyType&)>;
48
49   AnimatorFunction mAnimatorFunction;
50
51 public:
52
53   using AnimatorType = SceneGraph::Animator< PropertyType, PropertyAccessor<PropertyType> >;
54   using PropertyInterfaceType = SceneGraph::AnimatableProperty< PropertyType >;
55
56   /**
57    * Construct a new animator connector.
58    * @param[in] object The object for a scene-graph object to animate.
59    * @param[in] propertyIndex The index of a property provided by the object.
60    * @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)
61    * @param[in] animatorFunction A function used to animate the property.
62    * @param[in] alpha The alpha function to apply.
63    * @param[in] period The time period of the animator.
64    * @return A pointer to a newly allocated animator connector.
65    */
66   static AnimatorConnectorBase* New(Object&           object,
67                                     Property::Index   propertyIndex,
68                                     int32_t           componentIndex,
69                                     AnimatorFunction  animatorFunction,
70                                     AlphaFunction     alpha,
71                                     const TimePeriod& period)
72   {
73     return new AnimatorConnector(object,
74                                  propertyIndex,
75                                  componentIndex,
76                                  std::move(animatorFunction),
77                                  alpha,
78                                  period);
79   }
80
81   /**
82    * Virtual destructor.
83    */
84   ~AnimatorConnector() override = default;
85
86 private:
87
88   /**
89    * Private constructor; see also AnimatorConnector::New().
90    */
91   AnimatorConnector(Object&           object,
92                     Property::Index   propertyIndex,
93                     int32_t           componentIndex,
94                     AnimatorFunction  animatorFunction,
95                     AlphaFunction     alpha,
96                     const TimePeriod& period)
97   : AnimatorConnectorBase(object, propertyIndex, componentIndex, alpha, period),
98     mAnimatorFunction(std::move(animatorFunction))
99   {
100   }
101
102   // Undefined
103   AnimatorConnector() = delete;
104   AnimatorConnector( const AnimatorConnector& ) = delete;
105   AnimatorConnector& operator=( const AnimatorConnector& rhs ) = delete;
106
107   /**
108    * @copydoc AnimatorConnectorBase::DoCreateAnimator()
109    */
110   bool DoCreateAnimator( const SceneGraph::PropertyOwner& propertyOwner, const SceneGraph::PropertyBase& baseProperty ) final
111   {
112     bool resetterRequired = false;
113     // components only supported for float property type
114     DALI_ASSERT_DEBUG( mComponentIndex == Property::INVALID_COMPONENT_INDEX );
115     // Animating the whole property
116
117     // Cast to AnimatableProperty
118     const PropertyInterfaceType* animatableProperty = dynamic_cast< const PropertyInterfaceType* >( &baseProperty );
119
120     if( animatableProperty == nullptr )
121     {
122       if( baseProperty.IsTransformManagerProperty() )
123       {
124         mAnimator = SceneGraph::AnimatorTransformProperty<PropertyType, TransformManagerPropertyAccessor<PropertyType> >::New(propertyOwner,
125                                                                                                                               baseProperty,
126                                                                                                                               std::move(mAnimatorFunction),
127                                                                                                                               mAlphaFunction,
128                                                                                                                               mTimePeriod);
129         // Don't reset transform manager properties - TransformManager will do it more efficiently
130       }
131       else
132       {
133         DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
134       }
135     }
136     else
137     {
138       // Create the animator and resetter
139       mAnimator = AnimatorType::New(propertyOwner,
140                                     *animatableProperty,
141                                     std::move(mAnimatorFunction),
142                                     mAlphaFunction,
143                                     mTimePeriod);
144
145       resetterRequired = true;
146     }
147     return resetterRequired;
148   }
149 };
150
151 /**
152  * Specialization for float as that type supports component properties
153  */
154 template <>
155 class AnimatorConnector< float > : public AnimatorConnectorBase
156 {
157   using AnimatorFunction = std::function<float(float, const float&)>;
158
159   AnimatorFunction mAnimatorFunction;
160
161 public:
162
163   using AnimatorType = SceneGraph::Animator< float, PropertyAccessor<float> >;
164   using PropertyInterfaceType = SceneGraph::AnimatableProperty< float >;
165
166   /**
167    * Construct a new animator connector.
168    * @param[in] object The object for a scene-graph object to animate.
169    * @param[in] propertyIndex The index of a property provided by the object.
170    * @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)
171    * @param[in] animatorFunction A function used to animate the property.
172    * @param[in] alpha The alpha function to apply.
173    * @param[in] period The time period of the animator.
174    * @return A pointer to a newly allocated animator connector.
175    */
176   static AnimatorConnectorBase* New(Object&           object,
177                                     Property::Index   propertyIndex,
178                                     int32_t           componentIndex,
179                                     AnimatorFunction  animatorFunction,
180                                     AlphaFunction     alpha,
181                                     const TimePeriod& period)
182   {
183     return new AnimatorConnector(object,
184                                  propertyIndex,
185                                  componentIndex,
186                                  std::move(animatorFunction),
187                                  alpha,
188                                  period);
189   }
190
191   /**
192    * Virtual destructor.
193    */
194   ~AnimatorConnector() override = default;
195
196 private:
197
198   /**
199    * Private constructor; see also AnimatorConnector::New().
200    */
201   AnimatorConnector(Object&           object,
202                     Property::Index   propertyIndex,
203                     int32_t           componentIndex,
204                     AnimatorFunction  animatorFunction,
205                     AlphaFunction     alpha,
206                     const TimePeriod& period)
207   : AnimatorConnectorBase(object, propertyIndex, componentIndex, alpha, period),
208     mAnimatorFunction(std::move(animatorFunction))
209   {
210   }
211
212   // Undefined
213   AnimatorConnector() = delete;
214   AnimatorConnector( const AnimatorConnector& ) = delete;
215   AnimatorConnector& operator=( const AnimatorConnector& rhs ) = delete;
216
217   /**
218    * @copydoc AnimatorConnectorBase::DoCreateAnimator()
219    */
220   bool DoCreateAnimator( const SceneGraph::PropertyOwner& propertyOwner, const SceneGraph::PropertyBase& baseProperty ) final
221   {
222     bool resetterRequired = false;
223     if( mComponentIndex == Property::INVALID_COMPONENT_INDEX )
224     {
225       // Animating the whole property
226
227       // Cast to AnimatableProperty
228       const PropertyInterfaceType* animatableProperty = dynamic_cast< const PropertyInterfaceType* >( &baseProperty );
229
230       if( animatableProperty == nullptr )
231       {
232         if( baseProperty.IsTransformManagerProperty() )
233         {
234           mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyAccessor<float> >::New(propertyOwner,
235                                                                                                                   baseProperty,
236                                                                                                                   std::move(mAnimatorFunction),
237                                                                                                                   mAlphaFunction,
238                                                                                                                   mTimePeriod);
239           // Don't reset transform manager properties - TransformManager will do it more efficiently
240         }
241         else
242         {
243           DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
244         }
245       }
246       else
247       {
248         // Create the animator and resetter
249         mAnimator = AnimatorType::New(propertyOwner,
250                                       *animatableProperty,
251                                       std::move(mAnimatorFunction),
252                                       mAlphaFunction,
253                                       mTimePeriod);
254
255         resetterRequired = true;
256       }
257     }
258     else
259     {
260       {
261         // Animating a component of the property
262         if ( PropertyTypes::Get< Vector2 >() == baseProperty.GetType() )
263         {
264           // Animate float component of Vector2 property
265
266           // Cast to AnimatableProperty of type Vector2
267           const SceneGraph::AnimatableProperty<Vector2>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector2>* >( &baseProperty );
268           DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
269
270           switch( mComponentIndex )
271           {
272             case 0:
273             {
274               mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorX<Vector2> >::New(propertyOwner,
275                                                                                                  *animatableProperty,
276                                                                                                  std::move(mAnimatorFunction),
277                                                                                                  mAlphaFunction,
278                                                                                                  mTimePeriod);
279               break;
280             }
281             case 1:
282             {
283               mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorY<Vector2> >::New(propertyOwner,
284                                                                                                  *animatableProperty,
285                                                                                                  std::move(mAnimatorFunction),
286                                                                                                  mAlphaFunction,
287                                                                                                  mTimePeriod);
288               break;
289             }
290             default:
291             {
292               break;
293             }
294           }
295
296           resetterRequired = ( mAnimator != nullptr );
297         }
298
299         else if ( PropertyTypes::Get< Vector3 >() == baseProperty.GetType() )
300         {
301           // Animate float component of Vector3 property
302           // Cast to AnimatableProperty of type Vector3
303           const SceneGraph::AnimatableProperty<Vector3>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( &baseProperty );
304
305           if( animatableProperty == nullptr )
306           {
307             if( baseProperty.IsTransformManagerProperty() )
308             {
309               if( mComponentIndex == 0 )
310               {
311                 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyComponentAccessor<Vector3, 0> >::New(propertyOwner,
312                                                                                                                                       baseProperty,
313                                                                                                                                       std::move(mAnimatorFunction),
314                                                                                                                                       mAlphaFunction,
315                                                                                                                                       mTimePeriod);
316               }
317               else if( mComponentIndex == 1 )
318               {
319                 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyComponentAccessor<Vector3, 1> >::New(propertyOwner,
320                                                                                                                                       baseProperty,
321                                                                                                                                       std::move(mAnimatorFunction),
322                                                                                                                                       mAlphaFunction,
323                                                                                                                                       mTimePeriod);
324               }
325               else if( mComponentIndex == 2 )
326               {
327                 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyComponentAccessor<Vector3, 2> >::New(propertyOwner,
328                                                                                                                                       baseProperty,
329                                                                                                                                       std::move(mAnimatorFunction),
330                                                                                                                                       mAlphaFunction,
331                                                                                                                                       mTimePeriod);
332               }
333             }
334             else
335             {
336               DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
337             }
338             // Don't manually reset transform property - TransformManager will do it more efficiently
339           }
340           else
341           {
342             // Dynamic cast will fail if BaseProperty is not a Vector3 AnimatableProperty
343             DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
344
345             switch( mComponentIndex )
346             {
347               case 0:
348               {
349                 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorX<Vector3> >::New(propertyOwner,
350                                                                                                    *animatableProperty,
351                                                                                                    std::move(mAnimatorFunction),
352                                                                                                    mAlphaFunction,
353                                                                                                    mTimePeriod);
354                 break;
355               }
356               case 1:
357               {
358                 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorY<Vector3> >::New(propertyOwner,
359                                                                                                    *animatableProperty,
360                                                                                                    std::move(mAnimatorFunction),
361                                                                                                    mAlphaFunction,
362                                                                                                    mTimePeriod);
363                 break;
364               }
365               case 2:
366               {
367                 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorZ<Vector3> >::New(propertyOwner,
368                                                                                                    *animatableProperty,
369                                                                                                    std::move(mAnimatorFunction),
370                                                                                                    mAlphaFunction,
371                                                                                                    mTimePeriod);
372                 break;
373               }
374               default:
375               {
376                 break;
377               }
378             }
379
380             resetterRequired = ( mAnimator != nullptr );
381           }
382         }
383         else if ( PropertyTypes::Get< Vector4 >() == baseProperty.GetType() )
384         {
385           // Animate float component of Vector4 property
386
387           // Cast to AnimatableProperty of type Vector4
388           const SceneGraph::AnimatableProperty<Vector4>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( &baseProperty );
389
390           //Dynamic cast will fail if BaseProperty is not a Vector4 AnimatableProperty
391           DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
392
393           switch( mComponentIndex )
394           {
395             case 0:
396             {
397               mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorX<Vector4> >::New(propertyOwner,
398                                                                                                  *animatableProperty,
399                                                                                                  std::move(mAnimatorFunction),
400                                                                                                  mAlphaFunction,
401                                                                                                  mTimePeriod);
402               break;
403             }
404             case 1:
405             {
406               mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorY<Vector4> >::New(propertyOwner,
407                                                                                                  *animatableProperty,
408                                                                                                  std::move(mAnimatorFunction),
409                                                                                                  mAlphaFunction,
410                                                                                                  mTimePeriod);
411               break;
412             }
413             case 2:
414             {
415               mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorZ<Vector4> >::New(propertyOwner,
416                                                                                                  *animatableProperty,
417                                                                                                  std::move(mAnimatorFunction),
418                                                                                                  mAlphaFunction,
419                                                                                                  mTimePeriod);
420               break;
421             }
422             case 3:
423             {
424               mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorW<Vector4> >::New(propertyOwner,
425                                                                                                  *animatableProperty,
426                                                                                                  std::move(mAnimatorFunction),
427                                                                                                  mAlphaFunction,
428                                                                                                  mTimePeriod);
429               break;
430             }
431
432             default:
433             {
434               break;
435             }
436           }
437           resetterRequired = ( mAnimator != nullptr );
438         }
439       }
440     }
441     return resetterRequired;
442   }
443 };
444
445 } // namespace Internal
446
447 } // namespace Dali
448
449 #endif // DALI_INTERNAL_ANIMATOR_CONNECTOR_H