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