1 #ifndef DALI_CONSTRAINT_H
2 #define DALI_CONSTRAINT_H
5 * Copyright (c) 2020 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 <cstdint> // uint32_t
25 #include <dali/public-api/animation/constraint-source.h>
26 #include <dali/public-api/common/dali-vector.h>
27 #include <dali/public-api/object/base-handle.h>
28 #include <dali/public-api/object/property.h>
29 #include <dali/public-api/object/property-input.h>
30 #include <dali/public-api/signals/callback.h>
35 * @addtogroup dali_core_animation
41 namespace Internal DALI_INTERNAL
46 typedef Vector< PropertyInput* > PropertyInputContainer;
49 * @brief An abstract base class for Constraints.
51 * This can be used to constrain a property of an object, after animations have been applied.
52 * Constraints are applied in the following order:
53 * - Constraints are applied to on-stage actors in a depth-first traversal.
54 * - For each actor, the constraints are applied in the same order as the calls to Apply().
55 * - Constraints are not applied to off-stage actors.
57 * Create a constraint using one of the New methods depending on the type of callback function used.
58 * Try to use a C function unless some data needs to be stored, otherwise functors and class methods
61 * A constraint can be applied to an object in the following manner:
64 * Handle handle = CreateMyObject();
65 * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, &MyFunction );
66 * constraint.AddSource( LocalSource( INPUT_PROPERTY_INDEX ) );
71 class DALI_CORE_API Constraint : public BaseHandle
76 * @brief Template for the Function that is called by the Constraint system.
80 * - Static member methods of an object
81 * - Member functions of a particular class
82 * - Functors of a particular class
83 * - If a functor or method is provided, then a copy of the object is made.
85 * The expected signature of the callback should be:
87 * void Function( P&, const PropertyInputContainer& );
90 * The P& parameter is an in,out parameter which stores the current value of the property. The callback
91 * should change this value to the desired one. The PropertyInputContainer is a const reference to the property inputs
92 * added to the Constraint in the order they were added via AddSource().
95 * @tparam P The property type to constrain
97 template< typename P >
98 class DALI_INTERNAL Function : public CallbackBase
103 * @brief Constructor which connects to the provided C function (or a static member function).
105 * The expected signature of the function is:
107 * void MyFunction( P&, const PropertyInputContainer& );
111 * @param[in] function The function to call
113 Function( void( *function )( P&, const PropertyInputContainer& ) )
114 : CallbackBase( reinterpret_cast< CallbackBase::Function >( function ) ),
115 mCopyConstructorDispatcher( NULL )
120 * @brief Constructor which copies a function object and connects to the functor of that object.
122 * The function object should have a functor with the following signature:
124 * void operator()( P&, const PropertyInputContainer& );
128 * @param[in] object The object to copy
129 * @tparam T The type of the object
132 Function( const T& object )
133 : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
134 NULL, // uses operator() instead of member function
135 reinterpret_cast< CallbackBase::Dispatcher >( &FunctorDispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
136 reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
137 mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
142 * @brief Constructor which copies a function object and allows a connection to a member method.
144 * The object should have a method with the signature:
146 * void MyObject::MyMethod( P&, const PropertyInputContainer& );
150 * @param[in] object The object to copy
151 * @param[in] memberFunction The member function to call. This has to be a member of the same class
152 * @tparam T The type of the object
155 Function( const T& object, void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
156 : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
157 reinterpret_cast< CallbackBase::MemberFunction >( memberFunction ),
158 reinterpret_cast< CallbackBase::Dispatcher >( &Dispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
159 reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
160 mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
165 * @brief Clones the Function object.
167 * The object, if held by this object, is also copied.
170 * @return A pointer to a newly-allocated Function
172 CallbackBase* Clone()
174 CallbackBase* callback = NULL;
175 if ( mImpl && mImpl->mObjectPointer && mCopyConstructorDispatcher )
177 callback = new Function( mCopyConstructorDispatcher( reinterpret_cast< UndefinedClass* >( mImpl->mObjectPointer ) ) /* Copy the object */,
179 mImpl->mMemberFunctionDispatcher,
180 mImpl->mDestructorDispatcher,
181 mCopyConstructorDispatcher );
185 callback = new Function( mFunction );
193 * @brief Must not be declared.
195 * This is used so that no optimisations are done by the compiler when using void*.
197 class UndefinedClass;
200 * @brief Used to call the function to copy the stored object.
203 typedef UndefinedClass* (*CopyConstructorDispatcher) ( UndefinedClass* object );
206 * @brief Copies the actual object in Constraint::Function.
209 * @tparam T The type of the object
212 struct ObjectCopyConstructorDispatcher
215 * @brief Copies the object stored in Constraint::Function.
218 * @param[in] object The object to copy
219 * @return Newly allocated clone of the object
221 static UndefinedClass* Copy( const UndefinedClass* object )
223 T* copy = new T( *( reinterpret_cast< const T* >( object ) ) );
224 return reinterpret_cast< UndefinedClass* >( copy );
228 Function( const Function& ) = delete; ///< Deleted copy constructor. @SINCE_1_0.0
229 Function( Function&& ) = delete; ///< Deleted move constructor. @SINCE_1_9.25
230 Function& operator=( const Function& ) = delete; ///< Deleted copy assignment operator. @SINCE_1_0.0
231 Function& operator=( Function&& ) = delete; ///< Deleted move assignment operator. @SINCE_1_9.25
234 * @brief Constructor used when copying the stored object.
237 * @param[in] object A newly copied object
238 * @param[in] memberFunction The member function of the object
239 * @param[in] dispatcher Used to call the actual object
240 * @param[in] destructor Used to delete the owned object
241 * @param[in] copyConstructorDispatcher Used to create a copy of the owned object
243 Function( void* object,
244 CallbackBase::MemberFunction memberFunction,
245 CallbackBase::Dispatcher dispatcher,
246 CallbackBase::Destructor destructor,
247 CopyConstructorDispatcher copyConstructorDispatcher )
248 : CallbackBase( object, memberFunction, dispatcher, destructor ),
249 mCopyConstructorDispatcher( copyConstructorDispatcher )
254 * @brief Constructor used when copying a simple stored function.
257 * @param[in] function The function to call
259 Function( CallbackBase::Function function )
260 : CallbackBase( function ),
261 mCopyConstructorDispatcher( NULL )
267 CopyConstructorDispatcher mCopyConstructorDispatcher; ///< Function to call to copy the stored object
271 * @brief Enumeration for the action that will happen when the constraint is removed.
273 * The final value may be "baked" i.e. saved permanently.
274 * Alternatively the constrained value may be discarded when the constraint is removed.
279 Bake, ///< When the constraint is fully-applied, the constrained value is saved. @SINCE_1_0.0
280 Discard ///< When the constraint is removed, the constrained value is discarded. @SINCE_1_0.0
283 static const RemoveAction DEFAULT_REMOVE_ACTION; ///< Bake
286 * @brief Creates an uninitialized Constraint; this can be initialized with Constraint::New().
288 * Calling member functions with an uninitialized Constraint handle is not allowed.
294 * @brief Creates a constraint which targets a property using a function or a static class member.
296 * The expected signature, for a Vector3 type for example, of the function is:
298 * void MyFunction( Vector3&, const PropertyInputContainer& );
301 * Create the constraint with this function as follows:
304 * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, &MyFunction );
308 * @param[in] handle The handle to the property-owning object
309 * @param[in] targetIndex The index of the property to constrain
310 * @param[in] function The function to call to set the constrained property value
312 * @tparam P The type of the property to constrain
313 * @return The new constraint
316 static Constraint New( Handle handle, Property::Index targetIndex, void( *function )( P&, const PropertyInputContainer& ) )
318 CallbackBase* callback = new Constraint::Function< P >( function );
319 return New( handle, targetIndex, PropertyTypes::Get< P >(), callback );
323 * @brief Creates a constraint which targets a property using a functor object.
325 * The expected structure, for a Vector3 type for example, of the functor object is:
329 * void operator() ( Vector3&, const PropertyInputContainer& );
333 * Create the constraint with this object as follows:
336 * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, MyObject() );
340 * @param[in] handle The handle to the property-owning object
341 * @param[in] targetIndex The index of the property to constraint
342 * @param[in] object The functor object whose functor is called to set the constrained property value
344 * @tparam P The type of the property to constrain
345 * @tparam T The type of the object
346 * @return The new constraint
348 template< class P, class T >
349 static Constraint New( Handle handle, Property::Index targetIndex, const T& object )
351 CallbackBase* function = new Constraint::Function< P >( object );
352 return New( handle, targetIndex, PropertyTypes::Get< P >(), function );
356 * @brief Creates a constraint which targets a property using an object method.
358 * The expected structure, for a Vector3 type for example, of the object is:
362 * void MyMethod( Vector3&, const PropertyInputContainer& );
366 * Create the constraint with this object as follows:
369 * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, MyObject(), &MyObject::MyMethod );
373 * @param[in] handle The handle to the property-owning object
374 * @param[in] targetIndex The index of the property to constraint
375 * @param[in] object The object whose member function is called to set the constrained property value
376 * @param[in] memberFunction The member function to call to set the constrained property value
377 * @return The new constraint
379 * @tparam P The type of the property to constrain
380 * @tparam T The type of the object
382 template< class P, class T >
383 static Constraint New( Handle handle, Property::Index targetIndex, const T& object, void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
385 CallbackBase* function = new Constraint::Function< P >( object, memberFunction );
386 return New( handle, targetIndex, PropertyTypes::Get< P >(), function );
390 * @brief Creates a clone of this constraint for another object.
393 * @param[in] handle The handle to the property-owning object this constraint is to be cloned for
394 * @return The new constraint
396 Constraint Clone( Handle handle );
401 * This is non-virtual since derived Handle types must not contain data or virtual methods.
407 * @brief This copy constructor is required for (smart) pointer semantics.
410 * @param[in] constraint A reference to the copied handle
412 Constraint( const Constraint& constraint );
415 * @brief This assignment operator is required for (smart) pointer semantics.
418 * @param[in] rhs A reference to the copied handle
419 * @return A reference to this
421 Constraint& operator=( const Constraint& rhs );
424 * @brief Move constructor.
427 * @param[in] rhs A reference to the moved handle
429 Constraint( Constraint&& rhs );
432 * @brief Move assignment operator.
435 * @param[in] rhs A reference to the moved handle
436 * @return A reference to this handle
438 Constraint& operator=( Constraint&& rhs );
441 * @brief Downcasts a handle to Constraint handle.
443 * If handle points to a Constraint object, the downcast produces valid handle.
444 * If not, the returned handle is left uninitialized.
446 * @param[in] baseHandle BaseHandle to an object
447 * @return Handle to a Constraint object or an uninitialized handle
449 static Constraint DownCast( BaseHandle baseHandle );
452 * @brief Adds a constraint source to the constraint.
455 * @param[in] source The constraint source input to add
457 void AddSource( ConstraintSource source );
460 * @brief Applies this constraint.
463 * @pre The constraint must be initialized.
464 * @pre The target object must still be alive.
465 * @pre The source inputs should not have been destroyed.
470 * @brief Removes this constraint.
476 * @brief Retrieves the object which this constraint is targeting.
479 * @return The target object
481 Handle GetTargetObject();
484 * @brief Retrieves the property which this constraint is targeting.
487 * @return The target property
489 Dali::Property::Index GetTargetProperty();
492 * @brief Sets the remove action. Constraint::Bake will "bake" a value when fully-applied.
494 * In case of Constraint::Discard, the constrained value will be discarded, when the constraint is removed.
495 * The default value is Constraint::Bake.
497 * @param[in] action The remove-action
499 void SetRemoveAction( RemoveAction action );
502 * @brief Retrieves the remove action that will happen when the constraint is removed.
505 * @return The remove-action
507 RemoveAction GetRemoveAction() const;
510 * @brief Sets a tag for the constraint so it can be identified later.
513 * @param[in] tag An integer to identify the constraint
515 void SetTag( const uint32_t tag );
518 * @brief Gets the tag.
523 uint32_t GetTag() const;
525 public: // Not intended for use by Application developers
529 * @brief This constructor is used by Constraint::New() methods.
531 * @param[in] constraint A pointer to a newly allocated Dali resource
533 explicit DALI_INTERNAL Constraint( Internal::ConstraintBase* constraint );
536 private: // Not intended for use by Application developers
540 * @brief Constructs a new constraint which targets a property.
543 * @param[in] handle The handle to the property-owning object
544 * @param[in] targetIndex The index of the property to constrain
545 * @param[in] targetType Type The type of the constrained property
546 * @param[in] function The constraint function
547 * @return The new constraint
549 static Constraint New( Handle handle, Property::Index targetIndex, Property::Type targetType, CallbackBase* function );
558 #endif // DALI_CONSTRAINT_H