1 #ifndef DALI_INTERNAL_ANIMATOR_CONNECTOR_H
2 #define DALI_INTERNAL_ANIMATOR_CONNECTOR_H
5 * Copyright (c) 2021 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/animation-impl.h>
26 #include <dali/internal/event/animation/animator-connector-base.h>
27 #include <dali/internal/update/animation/property-accessor.h>
28 #include <dali/internal/update/animation/property-component-accessor.h>
29 #include <dali/internal/update/common/property-owner.h>
36 * AnimatorConnector is used to connect SceneGraph::Animators.
38 * SceneGraph::Animators weakly reference scene objects, and are automatically deleted when orphaned.
39 * Therefore the AnimatorConnector is NOT responsible for disconnecting animators.
40 * This is the common template for non float properties, there's a specialization for float properties as they can be component properties
42 template<typename PropertyType>
43 class AnimatorConnector : public AnimatorConnectorBase
45 using AnimatorFunction = std::function<PropertyType(float, const PropertyType&)>;
47 AnimatorFunction mAnimatorFunction;
50 using AnimatorType = SceneGraph::Animator<PropertyType, PropertyAccessor<PropertyType> >;
51 using PropertyInterfaceType = SceneGraph::AnimatableProperty<PropertyType>;
54 * Construct a new animator connector.
55 * @param[in] object The object for a scene-graph object to animate.
56 * @param[in] propertyIndex The index of a property provided by the object.
57 * @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)
58 * @param[in] animatorFunction A function used to animate the property.
59 * @param[in] alpha The alpha function to apply.
60 * @param[in] period The time period of the animator.
61 * @return A pointer to a newly allocated animator connector.
63 static AnimatorConnectorBase* New(Object& object,
64 Property::Index propertyIndex,
65 int32_t componentIndex,
66 AnimatorFunction animatorFunction,
68 const TimePeriod& period)
70 return new AnimatorConnector(object,
73 std::move(animatorFunction),
81 ~AnimatorConnector() override = default;
85 * Private constructor; see also AnimatorConnector::New().
87 AnimatorConnector(Object& object,
88 Property::Index propertyIndex,
89 int32_t componentIndex,
90 AnimatorFunction animatorFunction,
92 const TimePeriod& period)
93 : AnimatorConnectorBase(object, propertyIndex, componentIndex, alpha, period),
94 mAnimatorFunction(std::move(animatorFunction))
99 AnimatorConnector() = delete;
100 AnimatorConnector(const AnimatorConnector&) = delete;
101 AnimatorConnector& operator=(const AnimatorConnector& rhs) = delete;
104 * @copydoc AnimatorConnectorBase::DoCreateAnimator()
106 bool DoCreateAnimator(const SceneGraph::PropertyOwner& propertyOwner, const SceneGraph::PropertyBase& baseProperty) final
108 bool resetterRequired = false;
109 // components only supported for float property type
110 DALI_ASSERT_DEBUG(mComponentIndex == Property::INVALID_COMPONENT_INDEX);
111 // Animating the whole property
113 // Cast to AnimatableProperty
114 const PropertyInterfaceType* animatableProperty = dynamic_cast<const PropertyInterfaceType*>(&baseProperty);
116 if(animatableProperty == nullptr)
118 if(baseProperty.IsTransformManagerProperty())
120 mAnimator = SceneGraph::AnimatorTransformProperty<PropertyType, TransformManagerPropertyAccessor<PropertyType> >::New(propertyOwner,
122 std::move(mAnimatorFunction),
125 // Don't reset transform manager properties - TransformManager will do it more efficiently
129 DALI_ASSERT_DEBUG(animatableProperty && "Animating non-animatable property");
134 // Create the animator and resetter
135 mAnimator = AnimatorType::New(propertyOwner,
137 std::move(mAnimatorFunction),
141 resetterRequired = true;
143 return resetterRequired;
148 * Specialization for float as that type supports component properties
151 class AnimatorConnector<float> : public AnimatorConnectorBase
153 using AnimatorFunction = std::function<float(float, const float&)>;
155 AnimatorFunction mAnimatorFunction;
158 using AnimatorType = SceneGraph::Animator<float, PropertyAccessor<float> >;
159 using PropertyInterfaceType = SceneGraph::AnimatableProperty<float>;
162 * Construct a new animator connector.
163 * @param[in] object The object for a scene-graph object to animate.
164 * @param[in] propertyIndex The index of a property provided by the object.
165 * @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)
166 * @param[in] animatorFunction A function used to animate the property.
167 * @param[in] alpha The alpha function to apply.
168 * @param[in] period The time period of the animator.
169 * @return A pointer to a newly allocated animator connector.
171 static AnimatorConnectorBase* New(Object& object,
172 Property::Index propertyIndex,
173 int32_t componentIndex,
174 AnimatorFunction animatorFunction,
176 const TimePeriod& period)
178 return new AnimatorConnector(object,
181 std::move(animatorFunction),
187 * Virtual destructor.
189 ~AnimatorConnector() override = default;
193 * Private constructor; see also AnimatorConnector::New().
195 AnimatorConnector(Object& object,
196 Property::Index propertyIndex,
197 int32_t componentIndex,
198 AnimatorFunction animatorFunction,
200 const TimePeriod& period)
201 : AnimatorConnectorBase(object, propertyIndex, componentIndex, alpha, period),
202 mAnimatorFunction(std::move(animatorFunction))
207 AnimatorConnector() = delete;
208 AnimatorConnector(const AnimatorConnector&) = delete;
209 AnimatorConnector& operator=(const AnimatorConnector& rhs) = delete;
212 * @copydoc AnimatorConnectorBase::DoCreateAnimator()
214 bool DoCreateAnimator(const SceneGraph::PropertyOwner& propertyOwner, const SceneGraph::PropertyBase& baseProperty) final
216 bool resetterRequired = false;
217 if(mComponentIndex == Property::INVALID_COMPONENT_INDEX)
219 // Animating the whole property
221 // Cast to AnimatableProperty
222 const PropertyInterfaceType* animatableProperty = dynamic_cast<const PropertyInterfaceType*>(&baseProperty);
224 if(animatableProperty == nullptr)
226 if(baseProperty.IsTransformManagerProperty())
228 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyAccessor<float> >::New(propertyOwner,
230 std::move(mAnimatorFunction),
233 // Don't reset transform manager properties - TransformManager will do it more efficiently
237 DALI_ASSERT_DEBUG(animatableProperty && "Animating non-animatable property");
242 // Create the animator and resetter
243 mAnimator = AnimatorType::New(propertyOwner,
245 std::move(mAnimatorFunction),
249 resetterRequired = true;
255 // Animating a component of the property
256 if(PropertyTypes::Get<Vector2>() == baseProperty.GetType())
258 // Animate float component of Vector2 property
260 // Cast to AnimatableProperty of type Vector2
261 const SceneGraph::AnimatableProperty<Vector2>* animatableProperty = dynamic_cast<const SceneGraph::AnimatableProperty<Vector2>*>(&baseProperty);
262 DALI_ASSERT_DEBUG(animatableProperty && "Animating non-animatable property");
264 switch(mComponentIndex)
268 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorX<Vector2> >::New(propertyOwner,
270 std::move(mAnimatorFunction),
277 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorY<Vector2> >::New(propertyOwner,
279 std::move(mAnimatorFunction),
290 resetterRequired = (mAnimator != nullptr);
293 else if(PropertyTypes::Get<Vector3>() == baseProperty.GetType())
295 // Animate float component of Vector3 property
296 // Cast to AnimatableProperty of type Vector3
297 const SceneGraph::AnimatableProperty<Vector3>* animatableProperty = dynamic_cast<const SceneGraph::AnimatableProperty<Vector3>*>(&baseProperty);
299 if(animatableProperty == nullptr)
301 if(baseProperty.IsTransformManagerProperty())
303 if(mComponentIndex == 0)
305 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyComponentAccessor<Vector3, 0> >::New(propertyOwner,
307 std::move(mAnimatorFunction),
311 else if(mComponentIndex == 1)
313 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyComponentAccessor<Vector3, 1> >::New(propertyOwner,
315 std::move(mAnimatorFunction),
319 else if(mComponentIndex == 2)
321 mAnimator = SceneGraph::AnimatorTransformProperty<float, TransformManagerPropertyComponentAccessor<Vector3, 2> >::New(propertyOwner,
323 std::move(mAnimatorFunction),
330 DALI_ASSERT_DEBUG(animatableProperty && "Animating non-animatable property");
332 // Don't manually reset transform property - TransformManager will do it more efficiently
336 // Dynamic cast will fail if BaseProperty is not a Vector3 AnimatableProperty
337 DALI_ASSERT_DEBUG(animatableProperty && "Animating non-animatable property");
339 switch(mComponentIndex)
343 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorX<Vector3> >::New(propertyOwner,
345 std::move(mAnimatorFunction),
352 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorY<Vector3> >::New(propertyOwner,
354 std::move(mAnimatorFunction),
361 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorZ<Vector3> >::New(propertyOwner,
363 std::move(mAnimatorFunction),
374 resetterRequired = (mAnimator != nullptr);
377 else if(PropertyTypes::Get<Vector4>() == baseProperty.GetType())
379 // Animate float component of Vector4 property
381 // Cast to AnimatableProperty of type Vector4
382 const SceneGraph::AnimatableProperty<Vector4>* animatableProperty = dynamic_cast<const SceneGraph::AnimatableProperty<Vector4>*>(&baseProperty);
384 //Dynamic cast will fail if BaseProperty is not a Vector4 AnimatableProperty
385 DALI_ASSERT_DEBUG(animatableProperty && "Animating non-animatable property");
387 switch(mComponentIndex)
391 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorX<Vector4> >::New(propertyOwner,
393 std::move(mAnimatorFunction),
400 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorY<Vector4> >::New(propertyOwner,
402 std::move(mAnimatorFunction),
409 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorZ<Vector4> >::New(propertyOwner,
411 std::move(mAnimatorFunction),
418 mAnimator = SceneGraph::Animator<float, PropertyComponentAccessorW<Vector4> >::New(propertyOwner,
420 std::move(mAnimatorFunction),
431 resetterRequired = (mAnimator != nullptr);
435 return resetterRequired;
439 } // namespace Internal
443 #endif // DALI_INTERNAL_ANIMATOR_CONNECTOR_H