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] componentIndex Index to a sub component of a property, for use with Vector2, Vector3 and Vector4 (INVALID_PROPERTY_COMPONENTINDEX to use the whole property)
62 * @param[in] animatorFunction A function used to animate the property.
63 * @param[in] alpha The alpha function to apply.
64 * @param[in] period The time period of the animator.
65 * @return A pointer to a newly allocated animator connector.
67 static AnimatorConnectorBase* New( ProxyObject& proxy,
68 Property::Index propertyIndex,
70 const AnimatorFunction& animatorFunction,
72 const TimePeriod& period )
74 return new AnimatorConnector< PropertyType >( proxy,
85 virtual ~AnimatorConnector()
89 mProxy->RemoveObserver( *this );
92 // Removing animators via Animation is not necessary.
93 // The corresponding scene graph animation will destroy any animators that become disconnected.
97 * From AnimatorConnectorBase.
98 * This is only expected to be called once, when added to an Animation.
100 void SetParent( Animation& parent )
102 DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent" );
107 // Connect an animator, if the proxy has added an object to the scene-graph
108 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
111 ConnectAnimator( *object );
119 * Private constructor; see also AnimatorConnector::New().
121 AnimatorConnector( ProxyObject& proxy,
122 Property::Index propertyIndex,
124 const AnimatorFunction& animatorFunction,
126 const TimePeriod& period )
127 : AnimatorConnectorBase( alpha, period ),
129 mPropertyIndex( propertyIndex ),
130 mComponentIndex( componentIndex ),
131 mAnimatorFunction( animatorFunction ),
134 proxy.AddObserver( *this );
138 AnimatorConnector( const AnimatorConnector& );
141 AnimatorConnector& operator=( const AnimatorConnector& rhs );
144 * From ProxyObject::Observer
146 virtual void SceneObjectAdded( ProxyObject& proxy )
148 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
149 DALI_ASSERT_DEBUG( NULL != object );
151 ConnectAnimator( *object );
155 * From ProxyObject::Observer
157 virtual void SceneObjectRemoved( ProxyObject& proxy )
159 // Removing animators via Animation is not necessary.
160 // The corresponding scene graph animation will destroy any animators that become disconnected.
165 * From ProxyObject::Observer
167 virtual void ProxyDestroyed( ProxyObject& proxy )
174 * Create and connect an animator via update manager
176 void ConnectAnimator( const SceneGraph::PropertyOwner& object )
178 DALI_ASSERT_DEBUG( false == mConnected ); // Guard against double connections
179 DALI_ASSERT_DEBUG( NULL != mParent );
181 const SceneGraph::PropertyBase* base = mProxy->GetSceneObjectAnimatableProperty( mPropertyIndex );
183 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
184 DALI_ASSERT_DEBUG( NULL != sceneProperty && "Animating property with invalid type" );
186 SceneGraph::AnimatorBase* animator = AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
187 DALI_ASSERT_DEBUG( NULL != animator );
189 const SceneGraph::Animation* animation = mParent->GetSceneObject();
190 DALI_ASSERT_DEBUG( NULL != animation );
192 AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *animator, object );
194 mConnected = true; // not really necessary, but useful for asserts
199 ProxyObject* mProxy; ///< Not owned by the animator connector. Valid until ProxyDestroyed() is called.
201 Property::Index mPropertyIndex;
205 AnimatorFunction mAnimatorFunction;
207 bool mConnected; ///< Used to guard against double connections
211 * Variant which allows float components to be animated individually.
214 class AnimatorConnector<float> : public AnimatorConnectorBase, public ProxyObject::Observer
218 typedef boost::function< float (float, const float&) > AnimatorFunction;
219 typedef SceneGraph::Animator< float, PropertyAccessor<float> > AnimatorType;
222 * Construct a new animator connector.
223 * @param[in] proxy The proxy for a scene-graph object to animate.
224 * @param[in] propertyIndex The index of a property provided by the object.
225 * @param[in] componentIndex Index to a sub component of a property, for use with Vector2, Vector3 and Vector4
226 * @param[in] animatorFunction A function used to animate the property.
227 * @param[in] alpha The alpha function to apply.
228 * @param[in] period The time period of the animator.
229 * @return A pointer to a newly allocated animator connector.
231 static AnimatorConnectorBase* New( ProxyObject& proxy,
232 Property::Index propertyIndex,
234 const AnimatorFunction& animatorFunction,
236 const TimePeriod& period )
238 return new AnimatorConnector<float>( proxy,
247 * Virtual destructor.
249 virtual ~AnimatorConnector()
253 mProxy->RemoveObserver( *this );
256 // Removing animators via Animation is not necessary.
257 // The corresponding scene graph animation will destroy any animators that become disconnected.
261 * From AnimatorConnectorBase.
262 * This is only expected to be called once, when added to an Animation.
264 void SetParent( Animation& parent )
266 DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent");
271 // Connect an animator, if the proxy has added an object to the scene-graph
272 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
275 ConnectAnimator( *object );
283 * Private constructor; see also AnimatorConnector::New().
285 AnimatorConnector( ProxyObject& proxy,
286 Property::Index propertyIndex,
288 const AnimatorFunction& animatorFunction,
290 const TimePeriod& period )
291 : AnimatorConnectorBase( alpha, period ),
293 mPropertyIndex( propertyIndex ),
294 mComponentIndex( componentIndex ),
295 mAnimatorFunction( animatorFunction ),
298 proxy.AddObserver( *this );
302 AnimatorConnector( const AnimatorConnector& );
305 AnimatorConnector& operator=( const AnimatorConnector& rhs );
308 * From ProxyObject::Observer
310 virtual void SceneObjectAdded( ProxyObject& proxy )
312 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
313 DALI_ASSERT_DEBUG( NULL != object );
315 ConnectAnimator( *object );
319 * From ProxyObject::Observer
321 virtual void SceneObjectRemoved( ProxyObject& proxy )
323 // Removing animators via Animation is not necessary.
324 // The corresponding scene graph animation will destroy any animators that become disconnected.
329 * From ProxyObject::Observer
331 virtual void ProxyDestroyed( ProxyObject& proxy )
338 * Create and connect an animator via update manager
340 void ConnectAnimator( const SceneGraph::PropertyOwner& object )
342 DALI_ASSERT_DEBUG( false == mConnected ); // Guard against double connections
343 DALI_ASSERT_DEBUG( NULL != mParent );
345 const SceneGraph::PropertyBase* base = mProxy->GetSceneObjectAnimatableProperty( mPropertyIndex );
346 DALI_ASSERT_DEBUG( NULL != base );
348 SceneGraph::AnimatorBase* animator( NULL );
350 const int componentIndex = mProxy->GetPropertyComponentIndex( mPropertyIndex );
351 if( componentIndex != Property::INVALID_COMPONENT_INDEX )
353 mComponentIndex = componentIndex;
356 if ( Property::INVALID_COMPONENT_INDEX == mComponentIndex )
358 // Not a Vector3 or Vector4 component, expecting float type
359 DALI_ASSERT_DEBUG( PropertyTypes::Get< float >() == base->GetType() );
361 typedef SceneGraph::AnimatableProperty< float > PropertyInterfaceType;
363 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
364 DALI_ASSERT_DEBUG( NULL != sceneProperty );
366 animator = AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
370 // Expecting Vector3 or Vector4 type
372 if ( PropertyTypes::Get< Vector3 >() == base->GetType() )
374 // Animate float component of Vector3 property
375 typedef SceneGraph::AnimatableProperty< Vector3 > PropertyInterfaceType;
377 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
378 DALI_ASSERT_DEBUG( NULL != sceneProperty );
380 if ( 0 == mComponentIndex )
382 typedef SceneGraph::Animator< float, PropertyComponentAccessorX<Vector3> > Vector3AnimatorType;
383 animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
385 else if ( 1 == mComponentIndex )
387 typedef SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> > Vector3AnimatorType;
388 animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
390 else if ( 2 == mComponentIndex )
392 typedef SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> > Vector3AnimatorType;
393 animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
396 else if ( PropertyTypes::Get< Vector4 >() == base->GetType() )
398 // Animate float component of Vector4 property
399 typedef SceneGraph::AnimatableProperty< Vector4 > PropertyInterfaceType;
401 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
402 DALI_ASSERT_DEBUG( NULL != sceneProperty );
404 if ( 0 == mComponentIndex )
406 typedef SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> > Vector4AnimatorType;
407 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
409 else if ( 1 == mComponentIndex )
411 typedef SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> > Vector4AnimatorType;
412 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
414 else if ( 2 == mComponentIndex )
416 typedef SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> > Vector4AnimatorType;
417 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
419 else if ( 3 == mComponentIndex )
421 typedef SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> > Vector4AnimatorType;
422 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
427 DALI_ASSERT_DEBUG( NULL != animator && "Animating property with invalid type" );
429 const SceneGraph::Animation* animation = mParent->GetSceneObject();
430 DALI_ASSERT_DEBUG( NULL != animation );
432 AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *animator, object );
434 mConnected = true; // not really necessary, but useful for asserts
439 ProxyObject* mProxy; ///< Not owned by the animator connector. Valid until ProxyDestroyed() is called.
441 Property::Index mPropertyIndex;
445 AnimatorFunction mAnimatorFunction;
447 bool mConnected; ///< Used to guard against double connections
450 } // namespace Internal
454 #endif // __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__