Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-core.git] / dali / public-api / signals / functor-delegate.h
1 #ifndef DALI_FUNCTOR_DELEGATE_H
2 #define DALI_FUNCTOR_DELEGATE_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 // INTERNAL INCLUDES
22 #include <dali/public-api/common/dali-common.h>
23
24 namespace Dali
25 {
26 /**
27  * @addtogroup dali_core_signals
28  * @{
29  */
30
31 /**
32  * @brief Dispatcher to call a functor.
33  * @SINCE_1_0.0
34  */
35 template<typename T>
36 struct FunctorDispatcher
37 {
38   /**
39    * @brief Calls a function object.
40    *
41    * @SINCE_1_0.0
42    * @param[in] functorPtr The functor to call
43    */
44   static void Dispatch(void* functorPtr)
45   {
46     // "downcast" the functor type back to the correct one
47     T* functor = reinterpret_cast<T*>(functorPtr);
48     (*functor)();
49   }
50 };
51
52 /**
53  * @brief Dispatcher to delete a functor object.
54  * @SINCE_1_0.0
55  */
56 template<typename T>
57 struct FunctorDestroyer
58 {
59   /**
60    * @brief Dispatcher to delete an object.
61    * @SINCE_1_0.0
62    * @param[in] functorPtr A functor object to delete
63    */
64   static void Delete(void* functorPtr)
65   {
66     // FunctorDelegate owns the object but we're the only one who knows the real type so need
67     // to delete by "downcasting" from void* to the correct type
68     delete reinterpret_cast<T*>(functorPtr);
69   }
70 };
71
72 /**
73  * @brief Used to connect a void() functor to a signal via BaseObject::SignalConnect().
74  * @SINCE_1_0.0
75  */
76 class DALI_CORE_API FunctorDelegate
77 {
78 public:
79   /**
80    * @brief Constructor which copies a function object.
81    *
82    * @SINCE_1_0.0
83    * @param[in] functor The functor object to copy, either a class with operator() or a C function
84    * @return A pointer to the new function object
85    */
86   template<typename T>
87   static FunctorDelegate* New(const T& functor)
88   {
89     return new FunctorDelegate(reinterpret_cast<void*>(new T(functor)), // heap allocate the functor
90                                reinterpret_cast<FunctorDelegate::Dispatcher>(&FunctorDispatcher<T>::Dispatch),
91                                reinterpret_cast<FunctorDelegate::Destructor>(&FunctorDestroyer<T>::Delete));
92   }
93
94   /**
95    * @brief Non-virtual destructor; not intended as a base class.
96    * @SINCE_1_0.0
97    */
98   ~FunctorDelegate();
99
100   /**
101    * @brief Function to call the function or member function dispatcher.
102    * @SINCE_1_0.0
103    */
104   void Execute();
105
106 private:
107   /**
108    * @brief Used to call the correct function.
109    * @SINCE_1_0.0
110    */
111   using Dispatcher = void (*)(void*);
112
113   /**
114    * @brief Used to destroy mObjectPointer.
115    * @SINCE_1_0.0
116    */
117   using Destructor = void (*)(void*);
118
119   /**
120    * @brief Not defined.
121    * @SINCE_1_0.0
122    */
123   FunctorDelegate(const FunctorDelegate& rhs);
124
125   /**
126    * @brief Not defined.
127    * @SINCE_1_0.0
128    */
129   const FunctorDelegate& operator=(const FunctorDelegate& rhs);
130
131   /**
132    * @brief Private constructor.
133    *
134    * @SINCE_1_0.0
135    * @param[in] functorPtr A newly allocated functor object (takes ownership)
136    * @param dispatcher Used to call the actual function
137    * @param destructor Used to delete the owned functor object
138    */
139   FunctorDelegate(void* functorPtr, Dispatcher dispatcher, Destructor destructor);
140
141 public:
142   // Data for deriving classes & Dispatchers
143
144   void*      mFunctorPointer;           ///< Functor that will be called
145   Dispatcher mMemberFunctionDispatcher; ///< Dispatcher for member functions
146   Destructor mDestructorDispatcher;     ///< Destructor for owned objects
147 };
148
149 /**
150  * @}
151  */
152 } // namespace Dali
153
154 #endif // DALI_FUNCTOR_DELEGATE_H