1 #ifndef __DALI_CONSTRAINT_H__
2 #define __DALI_CONSTRAINT_H__
5 * Copyright (c) 2015 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 <dali/public-api/animation/constraint-source.h>
23 #include <dali/public-api/common/dali-vector.h>
24 #include <dali/public-api/object/base-handle.h>
25 #include <dali/public-api/object/property.h>
26 #include <dali/public-api/object/property-input.h>
27 #include <dali/public-api/signals/callback.h>
32 * @addtogroup dali-core-animation
38 namespace Internal DALI_INTERNAL
43 typedef Vector< PropertyInput* > PropertyInputContainer;
46 * @brief An abstract base class for Constraints.
48 * This can be used to constrain a property of an object, after animations have been applied.
49 * Constraints are applied in the following order:
50 * - Constraints are applied to on-stage actors in a depth-first traversal.
51 * - For each actor, the constraints are applied in the same order as the calls to Apply().
52 * - Constraints are not applied to off-stage actors.
54 * Create a constraint using one of the New methods depending on the type of callback function used.
55 * Try to use a C function unless some data needs to be stored, otherwise functors and class methods
58 * A constraint can be applied to an object in the following manner:
61 * Handle handle = CreateMyObject();
62 * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, &MyFunction );
63 * constraint.AddSource( LocalSource( INPUT_PROPERTY_INDEX ) );
67 class DALI_IMPORT_API Constraint : public BaseHandle
72 * @brief Template for the Function that is called by the Constraint system.
76 * - Static member methods of an object
77 * - Member functions of a particular class
78 * - Functors of a particular class
79 * - If a functor or method is provided, then a copy of the object is made.
81 * The expected signature of the callback should be:
83 * void Function( P&, const PropertyInputContainer& );
86 * The P& parameter is an in,out parameter which stores the current value of the property. The callback
87 * should change this value to the desired one. The PropertyInputContainer is a const reference to the property inputs
88 * added to the Constraint in the order they were added via AddSource().
90 * @tparam P The property type to constrain.
92 template< typename P >
93 class DALI_INTERNAL Function : public CallbackBase
98 * @brief Constructor which connects to the provided C function (or a static member function).
100 * The expected signature of the function is:
102 * void MyFunction( P&, const PropertyInputContainer& );
105 * @param[in] function The function to call.
107 Function( void( *function )( P&, const PropertyInputContainer& ) )
108 : CallbackBase( reinterpret_cast< CallbackBase::Function >( function ) ),
109 mCopyConstructorDispatcher( NULL )
114 * @brief Constructor which copies a function object and connects to the functor of that object.
116 * The function object should have a functor with the following signature:
118 * void operator()( P&, const PropertyInputContainer& );
121 * @param[in] object The object to copy.
123 * @tparam T The type of the object.
126 Function( const T& object )
127 : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
128 NULL, // uses operator() instead of member function
129 reinterpret_cast< CallbackBase::Dispatcher >( &FunctorDispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
130 reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
131 mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
136 * @brief Constructor which copies a function object and allows a connection to a member method.
138 * The object should have a method with the signature:
140 * void MyObject::MyMethod( P&, const PropertyInputContainer& );
143 * @param[in] object The object to copy.
144 * @param[in] memberFunction The member function to call. This has to be a member of the same class.
146 * @tparam T The type of the object.
149 Function( const T& object, void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
150 : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
151 reinterpret_cast< CallbackBase::MemberFunction >( memberFunction ),
152 reinterpret_cast< CallbackBase::Dispatcher >( &Dispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
153 reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
154 mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
159 * @brief Clones the Function object.
161 * The object, if held by this object, is also copied.
163 * @return A pointer to a newly-allocation Function.
165 CallbackBase* Clone()
167 CallbackBase* callback = NULL;
168 if ( mImpl && mImpl->mObjectPointer && mCopyConstructorDispatcher )
170 callback = new Function( mCopyConstructorDispatcher( reinterpret_cast< UndefinedClass* >( mImpl->mObjectPointer ) ) /* Copy the object */,
172 mImpl->mMemberFunctionDispatcher,
173 mImpl->mDestructorDispatcher,
174 mCopyConstructorDispatcher );
178 callback = new Function( mFunction );
186 * @brief Must not be declared.
188 * This is used so that no optimisations are done by the compiler when using void*.
190 class UndefinedClass;
193 * @brief Used to call the function to copy the stored object
195 typedef UndefinedClass* (*CopyConstructorDispatcher) ( UndefinedClass* object );
198 * @brief Copies the actual object in Constraint::Function.
200 * @tparam T The type of the object.
203 struct ObjectCopyConstructorDispatcher
206 * @brief Copy the object stored in Constraint::Function.
208 * @param[in] object The object to copy.
210 * @return Newly allocated clone of the object.
212 static UndefinedClass* Copy( const UndefinedClass* object )
214 T* copy = new T( *( reinterpret_cast< const T* >( object ) ) );
215 return reinterpret_cast< UndefinedClass* >( copy );
220 * @brief Undefined copy constructor
222 Function( const Function& );
225 * @brief Undefined assignment operator
227 Function& operator=( const Function& );
230 * @brief Constructor used when copying the stored object.
232 * @param[in] object A newly copied object
233 * @param[in] memberFunction The member function of the object.
234 * @param[in] dispatcher Used to call the actual object.
235 * @param[in] destructor Used to delete the owned object.
236 * @param[in] copyConstructorDispatcher Used to create a copy of the owned object.
238 Function( void* object,
239 CallbackBase::MemberFunction memberFunction,
240 CallbackBase::Dispatcher dispatcher,
241 CallbackBase::Destructor destructor,
242 CopyConstructorDispatcher copyConstructorDispatcher )
243 : CallbackBase( object, memberFunction, dispatcher, destructor ),
244 mCopyConstructorDispatcher( copyConstructorDispatcher )
249 * @brief Constructor used when copying a simple stored function.
251 * @param[in] function The function to call.
253 Function( CallbackBase::Function function )
254 : CallbackBase( function ),
255 mCopyConstructorDispatcher( NULL )
261 CopyConstructorDispatcher mCopyConstructorDispatcher; ///< Function to call to copy the stored object
265 * @brief The action that will happen when the constraint is removed.
267 * The final value may be "baked" i.e. saved permanently.
268 * Alternatively the constrained value may be discarded when the constraint is removed.
272 Bake, ///< When the constraint is fully-applied, the constrained value is saved.
273 Discard ///< When the constraint is removed, the constrained value is discarded.
276 static const RemoveAction DEFAULT_REMOVE_ACTION; ///< Bake
279 * @brief Create an uninitialized Constraint; this can be initialized with Constraint::New().
281 * Calling member functions with an uninitialized Dali::Object is not allowed.
286 * @brief Create a constraint which targets a property using a function or a static class member.
288 * The expected signature, for a Vector3 type for example, of the function is:
290 * void MyFunction( Vector3&, const PropertyInputContainer& );
293 * Create the constraint with this function as follows:
295 * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, &MyFunction );
298 * @param[in] handle The handle to the property-owning object.
299 * @param[in] targetIndex The index of the property to constrain.
300 * @param[in] function The function to call to set the constrained property value.
301 * @return The new constraint.
303 * @tparam P The type of the property to constrain.
306 static Constraint New( Handle handle, Property::Index targetIndex, void( *function )( P&, const PropertyInputContainer& ) )
308 CallbackBase* callback = new Constraint::Function< P >( function );
309 return New( handle, targetIndex, PropertyTypes::Get< P >(), callback );
313 * @brief Create a constraint which targets a property using a functor object.
315 * The expected structure, for a Vector3 type for example, of the functor object is:
319 * void operator() ( Vector3&, const PropertyInputContainer& );
323 * Create the constraint with this object as follows:
325 * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, MyObject() );
328 * @param[in] handle The handle to the property-owning object.
329 * @param[in] targetIndex The index of the property to constrain.
330 * @param[in] object The functor object whose functor is called to set the constrained property value.
331 * @return The new constraint.
333 * @tparam P The type of the property to constrain.
334 * @tparam T The type of the object.
336 template< class P, class T >
337 static Constraint New( Handle handle, Property::Index targetIndex, const T& object )
339 CallbackBase* function = new Constraint::Function< P >( object );
340 return New( handle, targetIndex, PropertyTypes::Get< P >(), function );
344 * @brief Create a constraint which targets a property using an object method.
346 * The expected structure, for a Vector3 type for example, of the object is:
350 * void MyMethod( Vector3&, const PropertyInputContainer& );
354 * Create the constraint with this object as follows:
356 * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, MyObject(), &MyObject::MyMethod );
359 * @param[in] handle The handle to the property-owning object.
360 * @param[in] targetIndex The index of the property to constrain.
361 * @param[in] object The object whose member function is called to set the constrained property value.
362 * @param[in] memberFunction The member function to call to set the constrained property value.
363 * @return The new constraint.
365 * @tparam P The type of the property to constrain.
366 * @tparam T The type of the object.
368 template< class P, class T >
369 static Constraint New( Handle handle, Property::Index targetIndex, const T& object, void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
371 CallbackBase* function = new Constraint::Function< P >( object, memberFunction );
372 return New( handle, targetIndex, PropertyTypes::Get< P >(), function );
376 * @brief Creates a clones of this constraint for another object.
378 * @param[in] handle The handle to the property-owning object this constraint is to be cloned for.
380 * @return The new constraint.
382 Constraint Clone( Handle handle );
387 * This is non-virtual since derived Handle types must not contain data or virtual methods.
392 * @brief This copy constructor is required for (smart) pointer semantics.
394 * @param [in] constraint A reference to the copied handle
396 Constraint( const Constraint& constraint );
399 * @brief This assignment operator is required for (smart) pointer semantics.
401 * @param [in] rhs A reference to the copied handle
402 * @return A reference to this
404 Constraint& operator=( const Constraint& rhs );
407 * @brief Downcast an Object handle to Constraint handle.
409 * If handle points to a Constraint object the
410 * downcast produces valid handle. If not the returned handle is left uninitialized.
411 * @param[in] baseHandle to An object
412 * @return handle to a Constraint object or an uninitialized handle
414 static Constraint DownCast( BaseHandle baseHandle );
417 * @brief Adds a constraint source to the constraint
419 * @param[in] source The constraint source input to add
421 void AddSource( ConstraintSource source );
424 * @brief Applies this constraint.
426 * @pre The constraint must be initialized
427 * @pre The target object must still be alive
428 * @pre The source inputs should not have been destroyed
433 * @brief Removes this constraint.
438 * @brief Retrieve the object which this constraint is targeting.
440 * @return The target object.
442 Handle GetTargetObject();
445 * @brief Retrieve the property which this constraint is targeting.
447 * @return The target property.
449 Dali::Property::Index GetTargetProperty();
452 * @brief Set whether the constraint will "bake" a value when fully-applied.
454 * Otherwise the constrained value will be discarded, when the constraint is removed.
455 * The default value is Constraint::Bake.
456 * @param[in] action The remove-action.
458 void SetRemoveAction( RemoveAction action );
461 * @brief Query whether the constraint will "bake" a value when fully-applied.
463 * Otherwise the constrained value will be discarded, when the constraint is removed.
464 * @return The apply-action.
466 RemoveAction GetRemoveAction() const;
469 * @brief Set a tag for the constraint so it can be identified later
471 * @param[in] tag An integer to identify the constraint
473 void SetTag( const unsigned int tag );
480 unsigned int GetTag() const;
482 public: // Not intended for use by Application developers
485 * @brief This constructor is used by Dali New() methods
486 * @param [in] constraint A pointer to a newly allocated Dali resource
488 explicit DALI_INTERNAL Constraint( Internal::ConstraintBase* constraint );
490 private: // Not intended for use by Application developers
493 * @brief Construct a new constraint which targets a property.
495 * @param[in] handle The handle to the property-owning object.
496 * @param[in] targetIndex The index of the property to constrain.
497 * @param[in] targetType Type The type of the constrained property.
498 * @param[in] function The constraint function.
499 * @return The new constraint.
501 static Constraint New( Handle handle, Property::Index targetIndex, Property::Type targetType, CallbackBase* function );
509 #endif // __DALI_CONSTRAINT_H__