-#ifndef __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__
-#define __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__
+#ifndef DALI_INTERNAL_ANIMATOR_CONNECTOR_H
+#define DALI_INTERNAL_ANIMATOR_CONNECTOR_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
// INTERNAL INCLUDES
-#include <dali/internal/event/common/object-impl.h>
#include <dali/internal/event/animation/animator-connector-base.h>
#include <dali/internal/event/animation/animation-impl.h>
#include <dali/internal/update/common/property-owner.h>
#include <dali/internal/update/animation/property-accessor.h>
#include <dali/internal/update/animation/property-component-accessor.h>
-#include <dali/internal/update/animation/scene-graph-animator.h>
-#include <dali/internal/update/manager/update-manager.h>
namespace Dali
{
{
/**
- * AnimatorConnector is used to connect SceneGraph::Animators for newly created scene-graph objects.
- *
- * The scene-graph objects are created by a Object e.g. Actor is a proxy for SceneGraph::Node.
- * AnimatorConnector observes the proxy object, in order to detect when a scene-graph object is created.
+ * AnimatorConnector is used to connect SceneGraph::Animators.
*
* SceneGraph::Animators weakly reference scene objects, and are automatically deleted when orphaned.
* Therefore the AnimatorConnector is NOT responsible for disconnecting animators.
+ * This is the common template for non float properties, there's a specialization for float properties as they can be component properties
*/
template < typename PropertyType >
-class AnimatorConnector : public AnimatorConnectorBase, public Object::Observer
+class AnimatorConnector : public AnimatorConnectorBase
{
public:
- typedef SceneGraph::Animator< PropertyType, PropertyAccessor<PropertyType> > AnimatorType;
- typedef SceneGraph::AnimatableProperty< PropertyType > PropertyInterfaceType;
+ using AnimatorType = SceneGraph::Animator< PropertyType, PropertyAccessor<PropertyType> >;
+ using PropertyInterfaceType = SceneGraph::AnimatableProperty< PropertyType >;
/**
* Construct a new animator connector.
*/
static AnimatorConnectorBase* New( Object& object,
Property::Index propertyIndex,
- int componentIndex,
+ int32_t componentIndex,
AnimatorFunctionBase* animatorFunction,
AlphaFunction alpha,
const TimePeriod& period )
{
- return new AnimatorConnector< PropertyType >( object,
- propertyIndex,
- componentIndex,
- animatorFunction,
- alpha,
- period );
+ return new AnimatorConnector( object,
+ propertyIndex,
+ componentIndex,
+ animatorFunction,
+ alpha,
+ period );
}
/**
* Virtual destructor.
*/
- virtual ~AnimatorConnector()
+ ~AnimatorConnector() override
{
- if( mObject )
- {
- mObject->RemoveObserver( *this );
- }
-
- //If there is not a SceneGraph::Animator, the AnimatorConnector is responsible for deleting the mAnimatorFunction
- //otherwise, the animator function ownership is transferred to the SceneGraph::Animator
- if( !mAnimator )
- {
- delete mAnimatorFunction;
- mAnimatorFunction = 0;
- }
- }
-
- /**
- * From AnimatorConnectorBase.
- * This is only expected to be called once, when added to an Animation.
- */
- void SetParent( Animation& parent )
- {
- DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent" );
- mParent = &parent;
-
- if( mObject && mObject->GetSceneObject() )
- {
- CreateAnimator();
- }
}
private:
*/
AnimatorConnector( Object& object,
Property::Index propertyIndex,
- int componentIndex,
+ int32_t componentIndex,
Internal::AnimatorFunctionBase* animatorFunction,
AlphaFunction alpha,
const TimePeriod& period )
- : AnimatorConnectorBase( alpha, period ),
- mObject( &object ),
- mAnimator(0),
- mPropertyIndex( propertyIndex ),
- mComponentIndex( componentIndex ),
- mAnimatorFunction( animatorFunction )
+ : AnimatorConnectorBase( object, propertyIndex, componentIndex, animatorFunction, alpha, period )
{
- object.AddObserver( *this );
}
// Undefined
- AnimatorConnector( const AnimatorConnector& );
-
- // Undefined
- AnimatorConnector& operator=( const AnimatorConnector& rhs );
+ AnimatorConnector() = delete;
+ AnimatorConnector( const AnimatorConnector& ) = delete;
+ AnimatorConnector& operator=( const AnimatorConnector& rhs ) = delete;
/**
- * From Object::Observer
+ * @copydoc AnimatorConnectorBase::DoCreateAnimator()
*/
- virtual void SceneObjectAdded( Object& object )
+ bool DoCreateAnimator( const SceneGraph::PropertyOwner& propertyOwner, const SceneGraph::PropertyBase& baseProperty ) final
{
- //If the animator has not been created yet, create it now.
- if( !mAnimator )
+ bool resetterRequired = false;
+ // components only supported for float property type
+ DALI_ASSERT_DEBUG( mComponentIndex == Property::INVALID_COMPONENT_INDEX );
+ // Animating the whole property
+
+ // Cast to AnimatableProperty
+ const PropertyInterfaceType* animatableProperty = dynamic_cast< const PropertyInterfaceType* >( &baseProperty );
+
+ if( animatableProperty == nullptr )
{
- CreateAnimator();
+ if( baseProperty.IsTransformManagerProperty() )
+ {
+ mAnimator = SceneGraph::AnimatorTransformProperty< PropertyType,TransformManagerPropertyAccessor<PropertyType> >::New( propertyOwner, baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
+ // Don't reset transform manager properties - TransformManager will do it more efficiently
+ }
+ else
+ {
+ DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
+ }
+ }
+ else
+ {
+ // Create the animator and resetter
+ mAnimator = AnimatorType::New( propertyOwner, *animatableProperty, mAnimatorFunction,
+ mAlphaFunction, mTimePeriod );
+ resetterRequired = true;
}
+ return resetterRequired;
}
+};
+
+/**
+ * Specialization for float as that type supports component properties
+ */
+template <>
+class AnimatorConnector< float > : public AnimatorConnectorBase
+{
+public:
+
+ using AnimatorType = SceneGraph::Animator< float, PropertyAccessor<float> >;
+ using PropertyInterfaceType = SceneGraph::AnimatableProperty< float >;
/**
- * From Object::Observer
+ * Construct a new animator connector.
+ * @param[in] object The object for a scene-graph object to animate.
+ * @param[in] propertyIndex The index of a property provided by the object.
+ * @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)
+ * @param[in] animatorFunction A function used to animate the property.
+ * @param[in] alpha The alpha function to apply.
+ * @param[in] period The time period of the animator.
+ * @return A pointer to a newly allocated animator connector.
*/
- virtual void SceneObjectRemoved( Object& object )
+ static AnimatorConnectorBase* New( Object& object,
+ Property::Index propertyIndex,
+ int32_t componentIndex,
+ AnimatorFunctionBase* animatorFunction,
+ AlphaFunction alpha,
+ const TimePeriod& period )
{
+ return new AnimatorConnector( object,
+ propertyIndex,
+ componentIndex,
+ animatorFunction,
+ alpha,
+ period );
}
/**
- * From Object::Observer
+ * Virtual destructor.
*/
- virtual void ObjectDestroyed( Object& object )
+ ~AnimatorConnector() override
{
- mObject = NULL;
}
- /**
- * Helper function to create a Scenegraph::Animator and add it to its correspondent SceneGraph::Animation.
- * @note This function will only be called the first time the object is added to the scene or at creation time if
- * the object was already in the scene
+private:
+
+ /**
+ * Private constructor; see also AnimatorConnector::New().
*/
- void CreateAnimator()
+ AnimatorConnector( Object& object,
+ Property::Index propertyIndex,
+ int32_t componentIndex,
+ Internal::AnimatorFunctionBase* animatorFunction,
+ AlphaFunction alpha,
+ const TimePeriod& period )
+ : AnimatorConnectorBase( object, propertyIndex, componentIndex, animatorFunction, alpha, period )
{
- DALI_ASSERT_DEBUG( mAnimator == NULL );
- DALI_ASSERT_DEBUG( mAnimatorFunction != NULL );
- DALI_ASSERT_DEBUG( mParent != NULL );
-
- //Get the PropertyOwner the animator is going to animate
- const SceneGraph::PropertyOwner* propertyOwner = mObject->GetSceneObject();
-
- //Get SceneGraph::BaseProperty
- const SceneGraph::PropertyBase* baseProperty = mObject->GetSceneObjectAnimatableProperty( mPropertyIndex );
+ }
- //Check if property is a component of another property
- const int componentIndex = mObject->GetPropertyComponentIndex( mPropertyIndex );
- if( componentIndex != Property::INVALID_COMPONENT_INDEX )
- {
- mComponentIndex = componentIndex;
- }
+ // Undefined
+ AnimatorConnector() = delete;
+ AnimatorConnector( const AnimatorConnector& ) = delete;
+ AnimatorConnector& operator=( const AnimatorConnector& rhs ) = delete;
+ /**
+ * @copydoc AnimatorConnectorBase::DoCreateAnimator()
+ */
+ bool DoCreateAnimator( const SceneGraph::PropertyOwner& propertyOwner, const SceneGraph::PropertyBase& baseProperty ) final
+ {
+ bool resetterRequired = false;
if( mComponentIndex == Property::INVALID_COMPONENT_INDEX )
{
- ///Animating the whole property
-
- //Cast to AnimatableProperty
- const PropertyInterfaceType* animatableProperty = dynamic_cast< const PropertyInterfaceType* >( baseProperty );
+ // Animating the whole property
- //Dynamic cast will fail if BaseProperty is not an AnimatableProperty
- DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
-
- //Create the animator
- mAnimator = AnimatorType::New( *propertyOwner, *animatableProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
+ // Cast to AnimatableProperty
+ const PropertyInterfaceType* animatableProperty = dynamic_cast< const PropertyInterfaceType* >( &baseProperty );
+ if( animatableProperty == nullptr )
+ {
+ if( baseProperty.IsTransformManagerProperty() )
+ {
+ mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyAccessor<float> >::New( propertyOwner, baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
+ // Don't reset transform manager properties - TransformManager will do it more efficiently
+ }
+ else
+ {
+ DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
+ }
+ }
+ else
+ {
+ // Create the animator and resetter
+ mAnimator = AnimatorType::New( propertyOwner, *animatableProperty, mAnimatorFunction,
+ mAlphaFunction, mTimePeriod );
+ resetterRequired = true;
+ }
}
else
{
- ///Animating a component of the property
-
- //Vector3
- if ( PropertyTypes::Get< Vector3 >() == baseProperty->GetType() )
{
- // Cast to AnimatableProperty of type Vector3
- const SceneGraph::AnimatableProperty<Vector3>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( baseProperty );
+ // Animating a component of the property
+ if ( PropertyTypes::Get< Vector2 >() == baseProperty.GetType() )
+ {
+ // Animate float component of Vector2 property
- //Dynamic cast will fail if BaseProperty is not a Vector3 AnimatableProperty
- DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
+ // Cast to AnimatableProperty of type Vector2
+ const SceneGraph::AnimatableProperty<Vector2>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector2>* >( &baseProperty );
+ DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
- switch( mComponentIndex )
- {
- case 0:
- {
- mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector3> >::New( *propertyOwner,
- *animatableProperty,
- mAnimatorFunction,
- mAlphaFunction,
- mTimePeriod );
- break;
- }
- case 1:
- {
- mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> >::New( *propertyOwner,
- *animatableProperty,
- mAnimatorFunction,
- mAlphaFunction,
- mTimePeriod );
- break;
- }
- case 2:
+ switch( mComponentIndex )
{
- mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> >::New( *propertyOwner,
- *animatableProperty,
- mAnimatorFunction,
- mAlphaFunction,
- mTimePeriod );
- break;
+ case 0:
+ {
+ mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector2> >::New( propertyOwner,
+ *animatableProperty,
+ mAnimatorFunction,
+ mAlphaFunction,
+ mTimePeriod );
+ break;
+ }
+ case 1:
+ {
+ mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector2> >::New( propertyOwner,
+ *animatableProperty,
+ mAnimatorFunction,
+ mAlphaFunction,
+ mTimePeriod );
+ break;
+ }
+ default:
+ {
+ break;
+ }
}
- default:
- {
- break;
- }
- }
- }
- else if ( PropertyTypes::Get< Vector4 >() == baseProperty->GetType() )
- {
- // Animate float component of Vector4 property
-
- // Cast to AnimatableProperty of type Vector4
- const SceneGraph::AnimatableProperty<Vector4>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( baseProperty );
- //Dynamic cast will fail if BaseProperty is not a Vector4 AnimatableProperty
- DALI_ASSERT_DEBUG( animatableProperty != NULL && "Animating non-animatable property" );
+ resetterRequired = ( mAnimator != nullptr );
+ }
- switch( mComponentIndex )
+ else if ( PropertyTypes::Get< Vector3 >() == baseProperty.GetType() )
{
- case 0:
- {
- mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> >::New( *propertyOwner,
- *animatableProperty,
- mAnimatorFunction,
- mAlphaFunction,
- mTimePeriod );
- break;
- }
- case 1:
- {
- mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> >::New( *propertyOwner,
- *animatableProperty,
- mAnimatorFunction,
- mAlphaFunction,
- mTimePeriod );
- break;
- }
- case 2:
+ // Animate float component of Vector3 property
+ // Cast to AnimatableProperty of type Vector3
+ const SceneGraph::AnimatableProperty<Vector3>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( &baseProperty );
+
+ if( animatableProperty == nullptr )
{
- mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> >::New( *propertyOwner,
- *animatableProperty,
- mAnimatorFunction,
- mAlphaFunction,
- mTimePeriod );
- break;
+ if( baseProperty.IsTransformManagerProperty() )
+ {
+ if( mComponentIndex == 0 )
+ {
+ mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyComponentAccessor<Vector3,0> >::New( propertyOwner, baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
+ }
+ else if( mComponentIndex == 1 )
+ {
+ mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyComponentAccessor<Vector3,1> >::New( propertyOwner, baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
+ }
+ else if( mComponentIndex == 2 )
+ {
+ mAnimator = SceneGraph::AnimatorTransformProperty< float,TransformManagerPropertyComponentAccessor<Vector3,2> >::New( propertyOwner, baseProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
+ }
+ }
+ else
+ {
+ DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
+ }
+ // Don't manually reset transform property - TransformManager will do it more efficiently
}
- case 3:
+ else
{
- mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> >::New( *propertyOwner,
- *animatableProperty,
- mAnimatorFunction,
- mAlphaFunction,
- mTimePeriod );
- break;
+ // Dynamic cast will fail if BaseProperty is not a Vector3 AnimatableProperty
+ DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
+
+ switch( mComponentIndex )
+ {
+ case 0:
+ {
+ mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector3> >::New( propertyOwner,
+ *animatableProperty,
+ mAnimatorFunction,
+ mAlphaFunction,
+ mTimePeriod );
+ break;
+ }
+ case 1:
+ {
+ mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> >::New( propertyOwner,
+ *animatableProperty,
+ mAnimatorFunction,
+ mAlphaFunction,
+ mTimePeriod );
+ break;
+ }
+ case 2:
+ {
+ mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> >::New( propertyOwner,
+ *animatableProperty,
+ mAnimatorFunction,
+ mAlphaFunction,
+ mTimePeriod );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ resetterRequired = ( mAnimator != nullptr );
}
+ }
+ else if ( PropertyTypes::Get< Vector4 >() == baseProperty.GetType() )
+ {
+ // Animate float component of Vector4 property
- default:
+ // Cast to AnimatableProperty of type Vector4
+ const SceneGraph::AnimatableProperty<Vector4>* animatableProperty = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( &baseProperty );
+
+ //Dynamic cast will fail if BaseProperty is not a Vector4 AnimatableProperty
+ DALI_ASSERT_DEBUG( animatableProperty && "Animating non-animatable property" );
+
+ switch( mComponentIndex )
{
- break;
+ case 0:
+ {
+ mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> >::New( propertyOwner,
+ *animatableProperty,
+ mAnimatorFunction,
+ mAlphaFunction,
+ mTimePeriod );
+ break;
+ }
+ case 1:
+ {
+ mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> >::New( propertyOwner,
+ *animatableProperty,
+ mAnimatorFunction,
+ mAlphaFunction,
+ mTimePeriod );
+ break;
+ }
+ case 2:
+ {
+ mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> >::New( propertyOwner,
+ *animatableProperty,
+ mAnimatorFunction,
+ mAlphaFunction,
+ mTimePeriod );
+ break;
+ }
+ case 3:
+ {
+ mAnimator = SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> >::New( propertyOwner,
+ *animatableProperty,
+ mAnimatorFunction,
+ mAlphaFunction,
+ mTimePeriod );
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
}
+ resetterRequired = ( mAnimator != nullptr );
}
}
}
-
- DALI_ASSERT_DEBUG( mAnimator != NULL );
-
- //Add the new SceneGraph::Animator to its correspondent SceneGraph::Animation via message to UpdateManager
- const SceneGraph::Animation* animation = mParent->GetSceneObject();
- DALI_ASSERT_DEBUG( NULL != animation );
- AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *mAnimator );
+ return resetterRequired;
}
-
-protected:
-
- Object* mObject; ///< Not owned by the animator connector. Valid until ObjectDestroyed() is called.
- SceneGraph::AnimatorBase* mAnimator;
-
- Property::Index mPropertyIndex;
- int mComponentIndex;
-
- Internal::AnimatorFunctionBase* mAnimatorFunction; ///< Owned by the animator connector until an Scenegraph::Animator is created
};
-
} // namespace Internal
} // namespace Dali
-#endif // __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__
+#endif // DALI_INTERNAL_ANIMATOR_CONNECTOR_H