1 #ifndef __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__
2 #define __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
7 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
21 #include <boost/function.hpp>
24 #include <dali/internal/event/common/proxy-object.h>
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 #include <dali/internal/update/animation/scene-graph-animator.h>
31 #include <dali/internal/update/manager/update-manager.h>
40 * AnimatorConnector is used to connect SceneGraph::Animators for newly created scene-graph objects.
42 * The scene-graph objects are created by a ProxyObject e.g. Actor is a proxy for SceneGraph::Node.
43 * AnimatorConnector observes the proxy object, in order to detect when a scene-graph object is created.
45 * SceneGraph::Animators weakly reference scene objects, and are automatically deleted when orphaned.
46 * Therefore the AnimatorConnector is NOT responsible for disconnecting animators.
48 template < typename PropertyType >
49 class AnimatorConnector : public AnimatorConnectorBase, public ProxyObject::Observer
53 typedef boost::function< PropertyType (float, const PropertyType&) > AnimatorFunction;
54 typedef SceneGraph::Animator< PropertyType, PropertyAccessor<PropertyType> > AnimatorType;
55 typedef SceneGraph::AnimatableProperty< PropertyType > PropertyInterfaceType;
58 * Construct a new animator connector.
59 * @param[in] proxy The proxy for a scene-graph object to animate.
60 * @param[in] propertyIndex The index of a property provided by the object.
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( ProxyObject& proxy,
67 Property::Index propertyIndex,
68 const AnimatorFunction& animatorFunction,
70 const TimePeriod& period )
72 return new AnimatorConnector< PropertyType >( proxy,
82 virtual ~AnimatorConnector()
86 mProxy->RemoveObserver( *this );
89 // Removing animators via Animation is not necessary.
90 // The corresponding scene graph animation will destroy any animators that become disconnected.
94 * From AnimatorConnectorBase.
95 * This is only expected to be called once, when added to an Animation.
97 void SetParent( Animation& parent )
99 DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent" );
104 // Connect an animator, if the proxy has added an object to the scene-graph
105 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
108 ConnectAnimator( *object );
116 * Private constructor; see also AnimatorConnector::New().
118 AnimatorConnector( ProxyObject& proxy,
119 Property::Index propertyIndex,
120 const AnimatorFunction& animatorFunction,
122 const TimePeriod& period )
123 : AnimatorConnectorBase( alpha, period ),
125 mPropertyIndex( propertyIndex ),
126 mAnimatorFunction( animatorFunction ),
129 proxy.AddObserver( *this );
133 AnimatorConnector( const AnimatorConnector& );
136 AnimatorConnector& operator=( const AnimatorConnector& rhs );
139 * From ProxyObject::Observer
141 virtual void SceneObjectAdded( ProxyObject& proxy )
143 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
144 DALI_ASSERT_DEBUG( NULL != object );
146 ConnectAnimator( *object );
150 * From ProxyObject::Observer
152 virtual void SceneObjectRemoved( ProxyObject& proxy )
154 // Removing animators via Animation is not necessary.
155 // The corresponding scene graph animation will destroy any animators that become disconnected.
160 * From ProxyObject::Observer
162 virtual void ProxyDestroyed( ProxyObject& proxy )
169 * Create and connect an animator via update manager
171 void ConnectAnimator( const SceneGraph::PropertyOwner& object )
173 DALI_ASSERT_DEBUG( false == mConnected ); // Guard against double connections
174 DALI_ASSERT_DEBUG( NULL != mParent );
176 const SceneGraph::PropertyBase* base = mProxy->GetSceneObjectAnimatableProperty( mPropertyIndex );
178 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
179 DALI_ASSERT_DEBUG( NULL != sceneProperty && "Animating property with invalid type" );
181 SceneGraph::AnimatorBase* animator = AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
182 DALI_ASSERT_DEBUG( NULL != animator );
184 const SceneGraph::Animation* animation = mParent->GetSceneObject();
185 DALI_ASSERT_DEBUG( NULL != animation );
187 AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *animator, object );
189 mConnected = true; // not really necessary, but useful for asserts
194 ProxyObject* mProxy; ///< Not owned by the animator connector. Valid until ProxyDestroyed() is called.
196 Property::Index mPropertyIndex;
198 AnimatorFunction mAnimatorFunction;
200 bool mConnected; ///< Used to guard against double connections
204 * Variant which allows float components to be animated individually.
207 class AnimatorConnector<float> : public AnimatorConnectorBase, public ProxyObject::Observer
211 typedef boost::function< float (float, const float&) > AnimatorFunction;
212 typedef SceneGraph::Animator< float, PropertyAccessor<float> > AnimatorType;
215 * Construct a new animator connector.
216 * @param[in] proxy The proxy for a scene-graph object to animate.
217 * @param[in] propertyIndex The index of a property provided by the object.
218 * @param[in] animatorFunction A function used to animate the property.
219 * @param[in] alpha The alpha function to apply.
220 * @param[in] period The time period of the animator.
221 * @return A pointer to a newly allocated animator connector.
223 static AnimatorConnectorBase* New( ProxyObject& proxy,
224 Property::Index propertyIndex,
225 const AnimatorFunction& animatorFunction,
227 const TimePeriod& period )
229 return new AnimatorConnector<float>( proxy,
237 * Virtual destructor.
239 virtual ~AnimatorConnector()
243 mProxy->RemoveObserver( *this );
246 // Removing animators via Animation is not necessary.
247 // The corresponding scene graph animation will destroy any animators that become disconnected.
251 * From AnimatorConnectorBase.
252 * This is only expected to be called once, when added to an Animation.
254 void SetParent( Animation& parent )
256 DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent");
261 // Connect an animator, if the proxy has added an object to the scene-graph
262 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
265 ConnectAnimator( *object );
273 * Private constructor; see also AnimatorConnector::New().
275 AnimatorConnector( ProxyObject& proxy,
276 Property::Index propertyIndex,
277 const AnimatorFunction& animatorFunction,
279 const TimePeriod& period )
280 : AnimatorConnectorBase( alpha, period ),
282 mPropertyIndex( propertyIndex ),
283 mAnimatorFunction( animatorFunction ),
286 proxy.AddObserver( *this );
290 AnimatorConnector( const AnimatorConnector& );
293 AnimatorConnector& operator=( const AnimatorConnector& rhs );
296 * From ProxyObject::Observer
298 virtual void SceneObjectAdded( ProxyObject& proxy )
300 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
301 DALI_ASSERT_DEBUG( NULL != object );
303 ConnectAnimator( *object );
307 * From ProxyObject::Observer
309 virtual void SceneObjectRemoved( ProxyObject& proxy )
311 // Removing animators via Animation is not necessary.
312 // The corresponding scene graph animation will destroy any animators that become disconnected.
317 * From ProxyObject::Observer
319 virtual void ProxyDestroyed( ProxyObject& proxy )
326 * Create and connect an animator via update manager
328 void ConnectAnimator( const SceneGraph::PropertyOwner& object )
330 DALI_ASSERT_DEBUG( false == mConnected ); // Guard against double connections
331 DALI_ASSERT_DEBUG( NULL != mParent );
333 const SceneGraph::PropertyBase* base = mProxy->GetSceneObjectAnimatableProperty( mPropertyIndex );
334 DALI_ASSERT_DEBUG( NULL != base );
336 SceneGraph::AnimatorBase* animator( NULL );
338 const int componentIndex = mProxy->GetPropertyComponentIndex( mPropertyIndex );
340 if ( INVALID_PROPERTY_COMPONENT_INDEX == componentIndex )
342 // Not a Vector3 or Vector4 component, expecting float type
343 DALI_ASSERT_DEBUG( PropertyTypes::Get< float >() == base->GetType() );
345 typedef SceneGraph::AnimatableProperty< float > PropertyInterfaceType;
347 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
348 DALI_ASSERT_DEBUG( NULL != sceneProperty );
350 animator = AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
354 // Expecting Vector3 or Vector4 type
356 if ( PropertyTypes::Get< Vector3 >() == base->GetType() )
358 // Animate float component of Vector3 property
359 typedef SceneGraph::AnimatableProperty< Vector3 > PropertyInterfaceType;
361 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
362 DALI_ASSERT_DEBUG( NULL != sceneProperty );
364 if ( 0 == componentIndex )
366 typedef SceneGraph::Animator< float, PropertyComponentAccessorX<Vector3> > Vector3AnimatorType;
367 animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
369 else if ( 1 == componentIndex )
371 typedef SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> > Vector3AnimatorType;
372 animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
374 else if ( 2 == componentIndex )
376 typedef SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> > Vector3AnimatorType;
377 animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
380 else if ( PropertyTypes::Get< Vector4 >() == base->GetType() )
382 // Animate float component of Vector4 property
383 typedef SceneGraph::AnimatableProperty< Vector4 > PropertyInterfaceType;
385 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
386 DALI_ASSERT_DEBUG( NULL != sceneProperty );
388 if ( 0 == componentIndex )
390 typedef SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> > Vector4AnimatorType;
391 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
393 else if ( 1 == componentIndex )
395 typedef SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> > Vector4AnimatorType;
396 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
398 else if ( 2 == componentIndex )
400 typedef SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> > Vector4AnimatorType;
401 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
403 else if ( 3 == componentIndex )
405 typedef SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> > Vector4AnimatorType;
406 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
411 DALI_ASSERT_DEBUG( NULL != animator && "Animating property with invalid type" );
413 const SceneGraph::Animation* animation = mParent->GetSceneObject();
414 DALI_ASSERT_DEBUG( NULL != animation );
416 AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *animator, object );
418 mConnected = true; // not really necessary, but useful for asserts
423 ProxyObject* mProxy; ///< Not owned by the animator connector. Valid until ProxyDestroyed() is called.
425 Property::Index mPropertyIndex;
427 AnimatorFunction mAnimatorFunction;
429 bool mConnected; ///< Used to guard against double connections
432 } // namespace Internal
436 #endif // __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__