eaf4509dd4167b96717fcfe082188d4e2f416929
[platform/core/uifw/dali-core.git] / dali / public-api / animation / constraint.h
1 #ifndef __DALI_CONSTRAINT_H__
2 #define __DALI_CONSTRAINT_H__
3
4 /*
5  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */
20
21 // INTERNAL INCLUDES
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>
28
29 namespace Dali
30 {
31 /**
32  * @addtogroup dali_core_animation
33  * @{
34  */
35
36 class Handle;
37
38 namespace Internal DALI_INTERNAL
39 {
40 class ConstraintBase;
41 }
42
43 typedef Vector< PropertyInput* > PropertyInputContainer;
44
45 /**
46  * @brief An abstract base class for Constraints.
47  *
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.
53  *
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
56  * are also supported.
57  *
58  * A constraint can be applied to an object in the following manner:
59  *
60  * @code
61  * Handle handle = CreateMyObject();
62  * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, &MyFunction );
63  * constraint.AddSource( LocalSource( INPUT_PROPERTY_INDEX ) );
64  * constraint.Apply();
65  * @endcode
66  * @SINCE_1_0.0
67  */
68 class DALI_CORE_API Constraint : public BaseHandle
69 {
70 public:
71
72   /**
73    * @brief Template for the Function that is called by the Constraint system.
74    *
75    * Supports:
76    *  - C style functions
77    *  - Static member methods of an object
78    *  - Member functions of a particular class
79    *  - Functors of a particular class
80    *  - If a functor or method is provided, then a copy of the object is made.
81    *
82    * The expected signature of the callback should be:
83    * @code
84    *   void Function( P&, const PropertyInputContainer& );
85    * @endcode
86    *
87    * The P& parameter is an in,out parameter which stores the current value of the property. The callback
88    * should change this value to the desired one. The PropertyInputContainer is a const reference to the property inputs
89    * added to the Constraint in the order they were added via AddSource().
90    *
91    * @SINCE_1_0.0
92    * @tparam P The property type to constrain
93    */
94   template< typename P >
95   class DALI_INTERNAL Function : public CallbackBase
96   {
97   public:
98
99     /**
100      * @brief Constructor which connects to the provided C function (or a static member function).
101      *
102      * The expected signature of the function is:
103      * @code
104      *   void MyFunction( P&, const PropertyInputContainer& );
105      * @endcode
106      *
107      * @SINCE_1_0.0
108      * @param[in] function The function to call
109      */
110     Function( void( *function )( P&, const PropertyInputContainer& ) )
111     : CallbackBase( reinterpret_cast< CallbackBase::Function >( function ) ),
112       mCopyConstructorDispatcher( NULL )
113     {
114     }
115
116     /**
117      * @brief Constructor which copies a function object and connects to the functor of that object.
118      *
119      * The function object should have a functor with the following signature:
120      * @code
121      *   void operator()( P&, const PropertyInputContainer& );
122      * @endcode
123      *
124      * @SINCE_1_0.0
125      * @param[in] object The object to copy
126      * @tparam T The type of the object
127      */
128     template< class T >
129     Function( const T& object )
130     : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
131                     NULL, // uses operator() instead of member function
132                     reinterpret_cast< CallbackBase::Dispatcher >( &FunctorDispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
133                     reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
134       mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
135     {
136     }
137
138     /**
139      * @brief Constructor which copies a function object and allows a connection to a member method.
140      *
141      * The object should have a method with the signature:
142      * @code
143      *   void MyObject::MyMethod( P&, const PropertyInputContainer& );
144      * @endcode
145      *
146      * @SINCE_1_0.0
147      * @param[in] object The object to copy
148      * @param[in] memberFunction The member function to call. This has to be a member of the same class
149      * @tparam T The type of the object
150      */
151     template< class T >
152     Function( const T& object, void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
153     : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
154                     reinterpret_cast< CallbackBase::MemberFunction >( memberFunction ),
155                     reinterpret_cast< CallbackBase::Dispatcher >( &Dispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
156                     reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
157       mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
158     {
159     }
160
161     /**
162      * @brief Clones the Function object.
163      *
164      * The object, if held by this object, is also copied.
165      *
166      * @SINCE_1_0.0
167      * @return A pointer to a newly-allocated Function
168      */
169     CallbackBase* Clone()
170     {
171       CallbackBase* callback = NULL;
172       if ( mImpl && mImpl->mObjectPointer && mCopyConstructorDispatcher )
173       {
174         callback = new Function( mCopyConstructorDispatcher( reinterpret_cast< UndefinedClass* >( mImpl->mObjectPointer ) ) /* Copy the object */,
175                                  mMemberFunction,
176                                  mImpl->mMemberFunctionDispatcher,
177                                  mImpl->mDestructorDispatcher,
178                                  mCopyConstructorDispatcher );
179       }
180       else
181       {
182         callback = new Function( mFunction );
183       }
184       return callback;
185     }
186
187   private:
188
189     /**
190      * @brief Must not be declared.
191      *
192      * This is used so that no optimisations are done by the compiler when using void*.
193      */
194     class UndefinedClass;
195
196     /**
197      * @brief Used to call the function to copy the stored object.
198      * @SINCE_1_0.0
199      */
200     typedef UndefinedClass* (*CopyConstructorDispatcher) ( UndefinedClass* object );
201
202     /**
203      * @brief Copies the actual object in Constraint::Function.
204      *
205      * @SINCE_1_0.0
206          * @tparam T The type of the object
207      */
208     template< class T >
209     struct ObjectCopyConstructorDispatcher
210     {
211       /**
212        * @brief Copies the object stored in Constraint::Function.
213        *
214        * @SINCE_1_0.0
215        * @param[in] object The object to copy
216        * @return Newly allocated clone of the object
217        */
218       static UndefinedClass* Copy( const UndefinedClass* object )
219       {
220         T* copy = new T( *( reinterpret_cast< const T* >( object ) ) );
221         return reinterpret_cast< UndefinedClass* >( copy );
222       }
223     };
224
225     /**
226      * @brief Undefined copy constructor.
227      * @SINCE_1_0.0
228      */
229     Function( const Function& );
230
231     /**
232      * @brief Undefined assignment operator.
233      * @SINCE_1_0.0
234      */
235     Function& operator=( const Function& );
236
237     /**
238      * @brief Constructor used when copying the stored object.
239      *
240      * @SINCE_1_0.0
241      * @param[in]  object                     A newly copied object
242      * @param[in]  memberFunction             The member function of the object
243      * @param[in]  dispatcher                 Used to call the actual object
244      * @param[in]  destructor                 Used to delete the owned object
245      * @param[in]  copyConstructorDispatcher  Used to create a copy of the owned object
246      */
247     Function( void* object,
248               CallbackBase::MemberFunction memberFunction,
249               CallbackBase::Dispatcher dispatcher,
250               CallbackBase::Destructor destructor,
251               CopyConstructorDispatcher copyConstructorDispatcher )
252     : CallbackBase( object, memberFunction, dispatcher, destructor ),
253       mCopyConstructorDispatcher( copyConstructorDispatcher )
254     {
255     }
256
257     /**
258      * @brief Constructor used when copying a simple stored function.
259      *
260      * @SINCE_1_0.0
261      * @param[in] function The function to call
262      */
263     Function( CallbackBase::Function function )
264     : CallbackBase( function ),
265       mCopyConstructorDispatcher( NULL )
266     {
267     }
268
269     // Data
270
271     CopyConstructorDispatcher mCopyConstructorDispatcher; ///< Function to call to copy the stored object
272   };
273
274   /**
275    * @brief Enumeration for the action that will happen when the constraint is removed.
276    *
277    * The final value may be "baked" i.e. saved permanently.
278    * Alternatively the constrained value may be discarded when the constraint is removed.
279    * @SINCE_1_0.0
280    */
281   enum RemoveAction
282   {
283     Bake,   ///< When the constraint is fully-applied, the constrained value is saved. @SINCE_1_0.0
284     Discard ///< When the constraint is removed, the constrained value is discarded. @SINCE_1_0.0
285   };
286
287   static const RemoveAction  DEFAULT_REMOVE_ACTION;  ///< Bake
288
289   /**
290    * @brief Creates an uninitialized Constraint; this can be initialized with Constraint::New().
291    *
292    * Calling member functions with an uninitialized Constraint handle is not allowed.
293    * @SINCE_1_0.0
294    */
295   Constraint();
296
297   /**
298    * @brief Creates a constraint which targets a property using a function or a static class member.
299    *
300    * The expected signature, for a Vector3 type for example, of the function is:
301    * @code
302    *   void MyFunction( Vector3&, const PropertyInputContainer& );
303    * @endcode
304    *
305    * Create the constraint with this function as follows:
306    *
307    * @code
308    *   Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, &MyFunction );
309    * @endcode
310    *
311    * @SINCE_1_0.0
312    * @param[in] handle      The handle to the property-owning object
313    * @param[in] targetIndex The index of the property to constrain
314    * @param[in] function    The function to call to set the constrained property value
315    *
316    * @tparam P The type of the property to constrain
317    * @return The new constraint
318    */
319   template< class P >
320   static Constraint New( Handle handle, Property::Index targetIndex, void( *function )( P&, const PropertyInputContainer& ) )
321   {
322     CallbackBase* callback = new Constraint::Function< P >( function );
323     return New( handle, targetIndex, PropertyTypes::Get< P >(), callback );
324   }
325
326   /**
327    * @brief Creates a constraint which targets a property using a functor object.
328    *
329    * The expected structure, for a Vector3 type for example, of the functor object is:
330    * @code
331    *   struct MyObject
332    *   {
333    *     void operator() ( Vector3&, const PropertyInputContainer& );
334    *   };
335    * @endcode
336    *
337    * Create the constraint with this object as follows:
338    *
339    * @code
340    *   Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, MyObject() );
341    * @endcode
342    *
343    * @SINCE_1_0.0
344    * @param[in] handle      The handle to the property-owning object
345    * @param[in] targetIndex The index of the property to constraint
346    * @param[in] object      The functor object whose functor is called to set the constrained property value
347    *
348    * @tparam P The type of the property to constrain
349    * @tparam T The type of the object
350    * @return The new constraint
351    */
352   template< class P, class T >
353   static Constraint New( Handle handle, Property::Index targetIndex, const T& object )
354   {
355     CallbackBase* function = new Constraint::Function< P >( object );
356     return New( handle, targetIndex, PropertyTypes::Get< P >(), function );
357   }
358
359   /**
360    * @brief Creates a constraint which targets a property using an object method.
361    *
362    * The expected structure, for a Vector3 type for example, of the object is:
363    * @code
364    *   struct MyObject
365    *   {
366    *     void MyMethod( Vector3&, const PropertyInputContainer& );
367    *   };
368    * @endcode
369    *
370    * Create the constraint with this object as follows:
371    *
372    * @code
373    *   Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, MyObject(), &MyObject::MyMethod );
374    * @endcode
375    *
376    * @SINCE_1_0.0
377    * @param[in] handle         The handle to the property-owning object
378    * @param[in] targetIndex    The index of the property to constraint
379    * @param[in] object         The object whose member function is called to set the constrained property value
380    * @param[in] memberFunction The member function to call to set the constrained property value
381    * @return The new constraint
382    *
383    * @tparam P The type of the property to constrain
384    * @tparam T The type of the object
385    */
386   template< class P, class T >
387   static Constraint New( Handle handle, Property::Index targetIndex, const T& object, void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
388   {
389     CallbackBase* function = new Constraint::Function< P >( object, memberFunction );
390     return New( handle, targetIndex, PropertyTypes::Get< P >(), function );
391   }
392
393   /**
394    * @brief Creates a clone of this constraint for another object.
395    *
396    * @SINCE_1_0.0
397    * @param[in] handle The handle to the property-owning object this constraint is to be cloned for
398    * @return The new constraint
399    */
400   Constraint Clone( Handle handle );
401
402   /**
403    * @brief Destructor.
404    *
405    * This is non-virtual since derived Handle types must not contain data or virtual methods.
406    * @SINCE_1_0.0
407    */
408   ~Constraint();
409
410   /**
411    * @brief This copy constructor is required for (smart) pointer semantics.
412    *
413    * @SINCE_1_0.0
414    * @param[in] constraint A reference to the copied handle
415    */
416   Constraint( const Constraint& constraint );
417
418   /**
419    * @brief This assignment operator is required for (smart) pointer semantics.
420    *
421    * @SINCE_1_0.0
422    * @param[in] rhs A reference to the copied handle
423    * @return A reference to this
424    */
425   Constraint& operator=( const Constraint& rhs );
426
427   /**
428    * @brief Downcasts a handle to Constraint handle.
429    *
430    * If handle points to a Constraint object, the downcast produces valid handle.
431    * If not, the returned handle is left uninitialized.
432    * @SINCE_1_0.0
433    * @param[in] baseHandle BaseHandle to an object
434    * @return Handle to a Constraint object or an uninitialized handle
435    */
436   static Constraint DownCast( BaseHandle baseHandle );
437
438   /**
439    * @brief Adds a constraint source to the constraint.
440    *
441    * @SINCE_1_0.0
442    * @param[in] source The constraint source input to add
443    */
444   void AddSource( ConstraintSource source );
445
446   /**
447    * @brief Applies this constraint.
448    *
449    * @SINCE_1_0.0
450    * @pre The constraint must be initialized.
451    * @pre The target object must still be alive.
452    * @pre The source inputs should not have been destroyed.
453    */
454   void Apply();
455
456   /**
457    * @brief Removes this constraint.
458    * @SINCE_1_0.0
459    */
460   void Remove();
461
462   /**
463    * @brief Retrieves the object which this constraint is targeting.
464    *
465    * @SINCE_1_0.0
466    * @return The target object
467    */
468   Handle GetTargetObject();
469
470   /**
471    * @brief Retrieves the property which this constraint is targeting.
472    *
473    * @SINCE_1_0.0
474    * @return The target property
475    */
476   Dali::Property::Index GetTargetProperty();
477
478   /**
479    * @brief Sets the remove action. Constraint::Bake will "bake" a value when fully-applied.
480    *
481    * In case of Constraint::Discard, the constrained value will be discarded, when the constraint is removed.
482    * The default value is Constraint::Bake.
483    * @SINCE_1_0.0
484    * @param[in] action The remove-action
485    */
486   void SetRemoveAction( RemoveAction action );
487
488   /**
489    * @brief Retrieves the remove action that will happen when the constraint is removed.
490    *
491    * @SINCE_1_0.0
492    * @return The remove-action
493    */
494   RemoveAction GetRemoveAction() const;
495
496   /**
497    * @brief Sets a tag for the constraint so it can be identified later.
498    *
499    * @SINCE_1_0.0
500    * @param[in] tag An integer to identify the constraint
501    */
502   void SetTag( const unsigned int tag );
503
504   /**
505    * @brief Gets the tag.
506    *
507    * @SINCE_1_0.0
508    * @return The tag
509    */
510   unsigned int GetTag() const;
511
512 public: // Not intended for use by Application developers
513
514   /// @cond internal
515   /**
516    * @brief This constructor is used by Constraint::New() methods.
517    * @SINCE_1_0.0
518    * @param[in] constraint A pointer to a newly allocated Dali resource
519    */
520   explicit DALI_INTERNAL Constraint( Internal::ConstraintBase* constraint );
521   /// @endcond
522
523 private: // Not intended for use by Application developers
524
525   /// @cond internal
526   /**
527    * @brief Constructs a new constraint which targets a property.
528    *
529    * @SINCE_1_0.0
530    * @param[in]  handle       The handle to the property-owning object
531    * @param[in]  targetIndex  The index of the property to constrain
532    * @param[in]  targetType   Type The type of the constrained property
533    * @param[in]  function     The constraint function
534    * @return The new constraint
535    */
536   static Constraint New( Handle handle, Property::Index targetIndex, Property::Type targetType, CallbackBase* function );
537   /// @endcond
538 };
539
540 /**
541  * @}
542  */
543 } // namespace Dali
544
545 #endif // __DALI_CONSTRAINT_H__