1 #ifndef DALI_INTERNAL_ANIMATOR_CONNECTOR_H
2 #define DALI_INTERNAL_ANIMATOR_CONNECTOR_H
5 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
38 * AnimatorConnector is used to connect SceneGraph::Animators.
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
44 template < typename PropertyType >
45 class AnimatorConnector : public AnimatorConnectorBase
47 using AnimatorFunction = std::function<PropertyType(float, const PropertyType&)>;
49 AnimatorFunction mAnimatorFunction;
53 using AnimatorType = SceneGraph::Animator< PropertyType, PropertyAccessor<PropertyType> >;
54 using PropertyInterfaceType = SceneGraph::AnimatableProperty< PropertyType >;
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.
66 static AnimatorConnectorBase* New(Object& object,
67 Property::Index propertyIndex,
68 int32_t componentIndex,
69 AnimatorFunction animatorFunction,
71 const TimePeriod& period)
73 return new AnimatorConnector(object,
76 std::move(animatorFunction),
84 ~AnimatorConnector() override = default;
89 * Private constructor; see also AnimatorConnector::New().
91 AnimatorConnector(Object& object,
92 Property::Index propertyIndex,
93 int32_t componentIndex,
94 AnimatorFunction animatorFunction,
96 const TimePeriod& period)
97 : AnimatorConnectorBase(object, propertyIndex, componentIndex, alpha, period),
98 mAnimatorFunction(std::move(animatorFunction))
103 AnimatorConnector() = delete;
104 AnimatorConnector( const AnimatorConnector& ) = delete;
105 AnimatorConnector& operator=( const AnimatorConnector& rhs ) = delete;
108 * @copydoc AnimatorConnectorBase::DoCreateAnimator()
110 bool DoCreateAnimator( const SceneGraph::PropertyOwner& propertyOwner, const SceneGraph::PropertyBase& baseProperty ) final
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
117 // Cast to AnimatableProperty
118 const PropertyInterfaceType* animatableProperty = dynamic_cast< const PropertyInterfaceType* >( &baseProperty );
120 if( animatableProperty == nullptr )
122 if( baseProperty.IsTransformManagerProperty() )
124 mAnimator = SceneGraph::AnimatorTransformProperty<PropertyType, TransformManagerPropertyAccessor<PropertyType> >::New(propertyOwner,
126 std::move(mAnimatorFunction),
129 // Don't reset transform manager properties - TransformManager will do it more efficiently
133 DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
138 // Create the animator and resetter
139 mAnimator = AnimatorType::New(propertyOwner,
141 std::move(mAnimatorFunction),
145 resetterRequired = true;
147 return resetterRequired;
152 * Specialization for float as that type supports component properties
155 class AnimatorConnector< float > : public AnimatorConnectorBase
157 using AnimatorFunction = std::function<float(float, const float&)>;
159 AnimatorFunction mAnimatorFunction;
163 using AnimatorType = SceneGraph::Animator< float, PropertyAccessor<float> >;
164 using PropertyInterfaceType = SceneGraph::AnimatableProperty< float >;
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.
176 static AnimatorConnectorBase* New(Object& object,
177 Property::Index propertyIndex,
178 int32_t componentIndex,
179 AnimatorFunction animatorFunction,
181 const TimePeriod& period)
183 return new AnimatorConnector(object,
186 std::move(animatorFunction),
192 * Virtual destructor.
194 ~AnimatorConnector() override = default;
199 * Private constructor; see also AnimatorConnector::New().
201 AnimatorConnector(Object& object,
202 Property::Index propertyIndex,
203 int32_t componentIndex,
204 AnimatorFunction animatorFunction,
206 const TimePeriod& period)
207 : AnimatorConnectorBase(object, propertyIndex, componentIndex, alpha, period),
208 mAnimatorFunction(std::move(animatorFunction))
213 AnimatorConnector() = delete;
214 AnimatorConnector( const AnimatorConnector& ) = delete;
215 AnimatorConnector& operator=( const AnimatorConnector& rhs ) = delete;
218 * @copydoc AnimatorConnectorBase::DoCreateAnimator()
220 bool DoCreateAnimator( const SceneGraph::PropertyOwner& propertyOwner, const SceneGraph::PropertyBase& baseProperty ) final
222 bool resetterRequired = false;
223 if( mComponentIndex == Property::INVALID_COMPONENT_INDEX )
225 // Animating the whole property
227 // Cast to AnimatableProperty
228 const PropertyInterfaceType* animatableProperty = dynamic_cast< const PropertyInterfaceType* >( &baseProperty );
230 if( animatableProperty == nullptr )
232 if( baseProperty.IsTransformManagerProperty() )
234 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyAccessor<float> >::New(propertyOwner,
236 std::move(mAnimatorFunction),
239 // Don't reset transform manager properties - TransformManager will do it more efficiently
243 DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
248 // Create the animator and resetter
249 mAnimator = AnimatorType::New(propertyOwner,
251 std::move(mAnimatorFunction),
255 resetterRequired = true;
261 // Animating a component of the property
262 if ( PropertyTypes::Get< Vector2 >() == baseProperty.GetType() )
264 // Animate float component of Vector2 property
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" );
270 switch( mComponentIndex )
274 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorX<Vector2> >::New(propertyOwner,
276 std::move(mAnimatorFunction),
283 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorY<Vector2> >::New(propertyOwner,
285 std::move(mAnimatorFunction),
296 resetterRequired = ( mAnimator != nullptr );
299 else if ( PropertyTypes::Get< Vector3 >() == baseProperty.GetType() )
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 );
305 if( animatableProperty == nullptr )
307 if( baseProperty.IsTransformManagerProperty() )
309 if( mComponentIndex == 0 )
311 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyComponentAccessor<Vector3, 0> >::New(propertyOwner,
313 std::move(mAnimatorFunction),
317 else if( mComponentIndex == 1 )
319 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyComponentAccessor<Vector3, 1> >::New(propertyOwner,
321 std::move(mAnimatorFunction),
325 else if( mComponentIndex == 2 )
327 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyComponentAccessor<Vector3, 2> >::New(propertyOwner,
329 std::move(mAnimatorFunction),
336 DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
338 // Don't manually reset transform property - TransformManager will do it more efficiently
342 // Dynamic cast will fail if BaseProperty is not a Vector3 AnimatableProperty
343 DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
345 switch( mComponentIndex )
349 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorX<Vector3> >::New(propertyOwner,
351 std::move(mAnimatorFunction),
358 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorY<Vector3> >::New(propertyOwner,
360 std::move(mAnimatorFunction),
367 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorZ<Vector3> >::New(propertyOwner,
369 std::move(mAnimatorFunction),
380 resetterRequired = ( mAnimator != nullptr );
383 else if ( PropertyTypes::Get< Vector4 >() == baseProperty.GetType() )
385 // Animate float component of Vector4 property
387 // Cast to AnimatableProperty of type Vector4
388 const SceneGraph::AnimatableProperty<Vector4>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( &baseProperty );
390 //Dynamic cast will fail if BaseProperty is not a Vector4 AnimatableProperty
391 DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
393 switch( mComponentIndex )
397 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorX<Vector4> >::New(propertyOwner,
399 std::move(mAnimatorFunction),
406 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorY<Vector4> >::New(propertyOwner,
408 std::move(mAnimatorFunction),
415 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorZ<Vector4> >::New(propertyOwner,
417 std::move(mAnimatorFunction),
424 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorW<Vector4> >::New(propertyOwner,
426 std::move(mAnimatorFunction),
437 resetterRequired = ( mAnimator != nullptr );
441 return resetterRequired;
445 } // namespace Internal
449 #endif // DALI_INTERNAL_ANIMATOR_CONNECTOR_H