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 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.
22 #include <boost/function.hpp>
25 #include <dali/internal/event/common/proxy-object.h>
26 #include <dali/internal/event/animation/animator-connector-base.h>
27 #include <dali/internal/event/animation/animation-impl.h>
28 #include <dali/internal/update/common/property-owner.h>
29 #include <dali/internal/update/animation/property-accessor.h>
30 #include <dali/internal/update/animation/property-component-accessor.h>
31 #include <dali/internal/update/animation/scene-graph-animator.h>
32 #include <dali/internal/update/manager/update-manager.h>
41 * AnimatorConnector is used to connect SceneGraph::Animators for newly created scene-graph objects.
43 * The scene-graph objects are created by a ProxyObject e.g. Actor is a proxy for SceneGraph::Node.
44 * AnimatorConnector observes the proxy object, in order to detect when a scene-graph object is created.
46 * SceneGraph::Animators weakly reference scene objects, and are automatically deleted when orphaned.
47 * Therefore the AnimatorConnector is NOT responsible for disconnecting animators.
49 template < typename PropertyType >
50 class AnimatorConnector : public AnimatorConnectorBase, public ProxyObject::Observer
54 typedef boost::function< PropertyType (float, const PropertyType&) > AnimatorFunction;
55 typedef SceneGraph::Animator< PropertyType, PropertyAccessor<PropertyType> > AnimatorType;
56 typedef SceneGraph::AnimatableProperty< PropertyType > PropertyInterfaceType;
59 * Construct a new animator connector.
60 * @param[in] proxy The proxy for a scene-graph object to animate.
61 * @param[in] propertyIndex The index of a property provided by the object.
62 * @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)
63 * @param[in] animatorFunction A function used to animate the property.
64 * @param[in] alpha The alpha function to apply.
65 * @param[in] period The time period of the animator.
66 * @return A pointer to a newly allocated animator connector.
68 static AnimatorConnectorBase* New( ProxyObject& proxy,
69 Property::Index propertyIndex,
71 const AnimatorFunction& animatorFunction,
73 const TimePeriod& period )
75 return new AnimatorConnector< PropertyType >( proxy,
86 virtual ~AnimatorConnector()
90 mProxy->RemoveObserver( *this );
93 // Removing animators via Animation is not necessary.
94 // The corresponding scene graph animation will destroy any animators that become disconnected.
98 * From AnimatorConnectorBase.
99 * This is only expected to be called once, when added to an Animation.
101 void SetParent( Animation& parent )
103 DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent" );
108 // Connect an animator, if the proxy has added an object to the scene-graph
109 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
112 ConnectAnimator( *object );
120 * Private constructor; see also AnimatorConnector::New().
122 AnimatorConnector( ProxyObject& proxy,
123 Property::Index propertyIndex,
125 const AnimatorFunction& animatorFunction,
127 const TimePeriod& period )
128 : AnimatorConnectorBase( alpha, period ),
130 mPropertyIndex( propertyIndex ),
131 mComponentIndex( componentIndex ),
132 mAnimatorFunction( animatorFunction ),
135 proxy.AddObserver( *this );
139 AnimatorConnector( const AnimatorConnector& );
142 AnimatorConnector& operator=( const AnimatorConnector& rhs );
145 * From ProxyObject::Observer
147 virtual void SceneObjectAdded( ProxyObject& proxy )
149 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
150 DALI_ASSERT_DEBUG( NULL != object );
152 ConnectAnimator( *object );
156 * From ProxyObject::Observer
158 virtual void SceneObjectRemoved( ProxyObject& proxy )
160 // Removing animators via Animation is not necessary.
161 // The corresponding scene graph animation will destroy any animators that become disconnected.
166 * From ProxyObject::Observer
168 virtual void ProxyDestroyed( ProxyObject& proxy )
175 * Create and connect an animator via update manager
177 void ConnectAnimator( const SceneGraph::PropertyOwner& object )
179 DALI_ASSERT_DEBUG( false == mConnected ); // Guard against double connections
180 DALI_ASSERT_DEBUG( NULL != mParent );
182 const SceneGraph::PropertyBase* base = mProxy->GetSceneObjectAnimatableProperty( mPropertyIndex );
184 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
185 DALI_ASSERT_DEBUG( NULL != sceneProperty && "Animating property with invalid type" );
187 SceneGraph::AnimatorBase* animator = AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
188 DALI_ASSERT_DEBUG( NULL != animator );
190 const SceneGraph::Animation* animation = mParent->GetSceneObject();
191 DALI_ASSERT_DEBUG( NULL != animation );
193 AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *animator, object );
195 mConnected = true; // not really necessary, but useful for asserts
200 ProxyObject* mProxy; ///< Not owned by the animator connector. Valid until ProxyDestroyed() is called.
202 Property::Index mPropertyIndex;
206 AnimatorFunction mAnimatorFunction;
208 bool mConnected; ///< Used to guard against double connections
212 * Variant which allows float components to be animated individually.
215 class AnimatorConnector<float> : public AnimatorConnectorBase, public ProxyObject::Observer
219 typedef boost::function< float (float, const float&) > AnimatorFunction;
220 typedef SceneGraph::Animator< float, PropertyAccessor<float> > AnimatorType;
223 * Construct a new animator connector.
224 * @param[in] proxy The proxy for a scene-graph object to animate.
225 * @param[in] propertyIndex The index of a property provided by the object.
226 * @param[in] componentIndex Index to a sub component of a property, for use with Vector2, Vector3 and Vector4
227 * @param[in] animatorFunction A function used to animate the property.
228 * @param[in] alpha The alpha function to apply.
229 * @param[in] period The time period of the animator.
230 * @return A pointer to a newly allocated animator connector.
232 static AnimatorConnectorBase* New( ProxyObject& proxy,
233 Property::Index propertyIndex,
235 const AnimatorFunction& animatorFunction,
237 const TimePeriod& period )
239 return new AnimatorConnector<float>( proxy,
248 * Virtual destructor.
250 virtual ~AnimatorConnector()
254 mProxy->RemoveObserver( *this );
257 // Removing animators via Animation is not necessary.
258 // The corresponding scene graph animation will destroy any animators that become disconnected.
262 * From AnimatorConnectorBase.
263 * This is only expected to be called once, when added to an Animation.
265 void SetParent( Animation& parent )
267 DALI_ASSERT_ALWAYS( mParent == NULL && "AnimationConnector already has a parent");
272 // Connect an animator, if the proxy has added an object to the scene-graph
273 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
276 ConnectAnimator( *object );
284 * Private constructor; see also AnimatorConnector::New().
286 AnimatorConnector( ProxyObject& proxy,
287 Property::Index propertyIndex,
289 const AnimatorFunction& animatorFunction,
291 const TimePeriod& period )
292 : AnimatorConnectorBase( alpha, period ),
294 mPropertyIndex( propertyIndex ),
295 mComponentIndex( componentIndex ),
296 mAnimatorFunction( animatorFunction ),
299 proxy.AddObserver( *this );
303 AnimatorConnector( const AnimatorConnector& );
306 AnimatorConnector& operator=( const AnimatorConnector& rhs );
309 * From ProxyObject::Observer
311 virtual void SceneObjectAdded( ProxyObject& proxy )
313 const SceneGraph::PropertyOwner* object = mProxy->GetSceneObject();
314 DALI_ASSERT_DEBUG( NULL != object );
316 ConnectAnimator( *object );
320 * From ProxyObject::Observer
322 virtual void SceneObjectRemoved( ProxyObject& proxy )
324 // Removing animators via Animation is not necessary.
325 // The corresponding scene graph animation will destroy any animators that become disconnected.
330 * From ProxyObject::Observer
332 virtual void ProxyDestroyed( ProxyObject& proxy )
339 * Create and connect an animator via update manager
341 void ConnectAnimator( const SceneGraph::PropertyOwner& object )
343 DALI_ASSERT_DEBUG( false == mConnected ); // Guard against double connections
344 DALI_ASSERT_DEBUG( NULL != mParent );
346 const SceneGraph::PropertyBase* base = mProxy->GetSceneObjectAnimatableProperty( mPropertyIndex );
347 DALI_ASSERT_DEBUG( NULL != base );
349 SceneGraph::AnimatorBase* animator( NULL );
351 const int componentIndex = mProxy->GetPropertyComponentIndex( mPropertyIndex );
352 if( componentIndex != Property::INVALID_COMPONENT_INDEX )
354 mComponentIndex = componentIndex;
357 if ( Property::INVALID_COMPONENT_INDEX == mComponentIndex )
359 // Not a Vector3 or Vector4 component, expecting float type
360 DALI_ASSERT_DEBUG( PropertyTypes::Get< float >() == base->GetType() );
362 typedef SceneGraph::AnimatableProperty< float > PropertyInterfaceType;
364 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
365 DALI_ASSERT_DEBUG( NULL != sceneProperty );
367 animator = AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
371 // Expecting Vector3 or Vector4 type
373 if ( PropertyTypes::Get< Vector3 >() == base->GetType() )
375 // Animate float component of Vector3 property
376 typedef SceneGraph::AnimatableProperty< Vector3 > PropertyInterfaceType;
378 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
379 DALI_ASSERT_DEBUG( NULL != sceneProperty );
381 if ( 0 == mComponentIndex )
383 typedef SceneGraph::Animator< float, PropertyComponentAccessorX<Vector3> > Vector3AnimatorType;
384 animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
386 else if ( 1 == mComponentIndex )
388 typedef SceneGraph::Animator< float, PropertyComponentAccessorY<Vector3> > Vector3AnimatorType;
389 animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
391 else if ( 2 == mComponentIndex )
393 typedef SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector3> > Vector3AnimatorType;
394 animator = Vector3AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
397 else if ( PropertyTypes::Get< Vector4 >() == base->GetType() )
399 // Animate float component of Vector4 property
400 typedef SceneGraph::AnimatableProperty< Vector4 > PropertyInterfaceType;
402 const PropertyInterfaceType* sceneProperty = dynamic_cast< const PropertyInterfaceType* >( base );
403 DALI_ASSERT_DEBUG( NULL != sceneProperty );
405 if ( 0 == mComponentIndex )
407 typedef SceneGraph::Animator< float, PropertyComponentAccessorX<Vector4> > Vector4AnimatorType;
408 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
410 else if ( 1 == mComponentIndex )
412 typedef SceneGraph::Animator< float, PropertyComponentAccessorY<Vector4> > Vector4AnimatorType;
413 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
415 else if ( 2 == mComponentIndex )
417 typedef SceneGraph::Animator< float, PropertyComponentAccessorZ<Vector4> > Vector4AnimatorType;
418 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
420 else if ( 3 == mComponentIndex )
422 typedef SceneGraph::Animator< float, PropertyComponentAccessorW<Vector4> > Vector4AnimatorType;
423 animator = Vector4AnimatorType::New( *sceneProperty, mAnimatorFunction, mAlphaFunction, mTimePeriod );
428 DALI_ASSERT_DEBUG( NULL != animator && "Animating property with invalid type" );
430 const SceneGraph::Animation* animation = mParent->GetSceneObject();
431 DALI_ASSERT_DEBUG( NULL != animation );
433 AddAnimatorMessage( mParent->GetUpdateManager().GetEventToUpdate(), *animation, *animator, object );
435 mConnected = true; // not really necessary, but useful for asserts
440 ProxyObject* mProxy; ///< Not owned by the animator connector. Valid until ProxyDestroyed() is called.
442 Property::Index mPropertyIndex;
446 AnimatorFunction mAnimatorFunction;
448 bool mConnected; ///< Used to guard against double connections
451 } // namespace Internal
455 #endif // __DALI_INTERNAL_ANIMATOR_CONNECTOR_H__