Refactor system classes
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / linux / callback-manager-ecore.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/system/linux/callback-manager-ecore.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/internal/system/linux/dali-ecore.h>
23
24 #include <dali/integration-api/debug.h>
25
26 // INTERNAL INCLUDES
27
28 namespace Dali
29 {
30 namespace Internal
31 {
32 namespace Adaptor
33 {
34 /**
35  * Structure contains the callback function and control options
36  */
37 struct CallbackData
38 {
39   /**
40    * Constructor
41    */
42   CallbackData(CallbackBase* callback, bool hasReturnValue)
43   : mCallback(callback),
44     mRemoveFromContainerFunction(NULL),
45     mIdler(NULL),
46     mIdleEnterer(NULL),
47     mHasReturnValue(hasReturnValue)
48   {
49   }
50   /**
51    * Destructor
52    */
53   ~CallbackData()
54   {
55     delete mCallback;
56     delete mRemoveFromContainerFunction;
57   }
58
59   CallbackBase*       mCallback;                    ///< call back
60   CallbackBase*       mRemoveFromContainerFunction; ///< Called to remove the callbackdata from the callback container
61   Ecore_Idler*        mIdler;                       ///< ecore idler
62   Ecore_Idle_Enterer* mIdleEnterer;                 ///< ecore idle enterer
63   bool                mHasReturnValue;              ///< true if the callback function has a return value.
64 };
65
66 namespace
67 {
68 /**
69  * Called from the main thread while idle.
70  */
71 Eina_Bool IdleCallback(void* data)
72 {
73   Eina_Bool     ret          = ECORE_CALLBACK_CANCEL; // CALLBACK Cancel will delete the idler so we don't need to call ecore_idler_del
74   CallbackData* callbackData = static_cast<CallbackData*>(data);
75
76   if(callbackData->mHasReturnValue)
77   {
78     // run the function
79     bool retValue = CallbackBase::ExecuteReturn<bool>(*callbackData->mCallback);
80     if(retValue)
81     {
82       // keep the callback
83       ret = ECORE_CALLBACK_RENEW;
84     }
85     else
86     {
87       // remove callback data from the container
88       CallbackBase::Execute(*callbackData->mRemoveFromContainerFunction, callbackData);
89
90       // delete our data
91       delete callbackData;
92     }
93   }
94   else
95   {
96     // remove callback data from the container
97     CallbackBase::Execute(*callbackData->mRemoveFromContainerFunction, callbackData);
98
99     // run the function
100     CallbackBase::Execute(*callbackData->mCallback);
101
102     // delete our data
103     delete callbackData;
104   }
105
106   return ret;
107 }
108
109 } // unnamed namespace
110
111 EcoreCallbackManager::EcoreCallbackManager()
112 : mRunning(false)
113 {
114 }
115
116 void EcoreCallbackManager::Start()
117 {
118   DALI_ASSERT_DEBUG(mRunning == false);
119
120   mRunning = true;
121 }
122
123 void EcoreCallbackManager::Stop()
124 {
125   // make sure we're not called twice
126   DALI_ASSERT_DEBUG(mRunning == true);
127
128   RemoveAllCallbacks();
129
130   mRunning = false;
131 }
132
133 bool EcoreCallbackManager::AddIdleCallback(CallbackBase* callback, bool hasReturnValue)
134 {
135   if(!mRunning)
136   {
137     return false;
138   }
139
140   CallbackData* callbackData = new CallbackData(callback, hasReturnValue);
141
142   callbackData->mRemoveFromContainerFunction = MakeCallback(this, &EcoreCallbackManager::RemoveCallbackFromContainer);
143
144   // add the call back to the container
145   mCallbackContainer.push_front(callbackData);
146
147   // add the idler
148   callbackData->mIdler = ecore_idler_add(IdleCallback, callbackData);
149
150   DALI_ASSERT_ALWAYS((callbackData->mIdler != NULL) && "Idle method not created");
151
152   return true;
153 }
154
155 void EcoreCallbackManager::RemoveIdleCallback(CallbackBase* callback)
156 {
157   for(CallbackList::iterator it    = mCallbackContainer.begin(),
158                              endIt = mCallbackContainer.end();
159       it != endIt;
160       ++it)
161   {
162     CallbackData* data = *it;
163
164     if(data->mCallback == callback)
165     {
166       // remove callback data from the container.
167       CallbackBase::Execute(*data->mRemoveFromContainerFunction, data);
168
169       ecore_idler_del(data->mIdler);
170
171       // delete our data
172       delete data;
173
174       return;
175     }
176   }
177 }
178
179 bool EcoreCallbackManager::ProcessIdle()
180 {
181   // @todo To be implemented.
182   return false;
183 }
184
185 void EcoreCallbackManager::ClearIdleCallbacks()
186 {
187   // @todo To be implemented.
188 }
189
190 bool EcoreCallbackManager::AddIdleEntererCallback(CallbackBase* callback)
191 {
192   if(!mRunning)
193   {
194     return false;
195   }
196
197   CallbackData* callbackData = new CallbackData(callback, true);
198
199   callbackData->mRemoveFromContainerFunction = MakeCallback(this, &EcoreCallbackManager::RemoveCallbackFromContainer);
200
201   // add the call back to the container
202   mCallbackContainer.push_front(callbackData);
203
204   // add the idler
205   callbackData->mIdleEnterer = ecore_idle_enterer_add(IdleCallback, callbackData);
206
207   DALI_ASSERT_ALWAYS((callbackData->mIdleEnterer != NULL) && "Idle method not created");
208
209   return true;
210 }
211
212 void EcoreCallbackManager::RemoveIdleEntererCallback(CallbackBase* callback)
213 {
214   for(CallbackList::iterator it    = mCallbackContainer.begin(),
215                              endIt = mCallbackContainer.end();
216       it != endIt;
217       ++it)
218   {
219     CallbackData* data = *it;
220
221     if(data->mCallback == callback)
222     {
223       // remove callback data from the container.
224       CallbackBase::Execute(*data->mRemoveFromContainerFunction, data);
225
226       ecore_idle_enterer_del(data->mIdleEnterer);
227
228       // delete our data
229       delete data;
230
231       return;
232     }
233   }
234 }
235
236 void EcoreCallbackManager::RemoveCallbackFromContainer(CallbackData* callbackData)
237 {
238   mCallbackContainer.remove(callbackData);
239 }
240
241 void EcoreCallbackManager::RemoveAllCallbacks()
242 {
243   // always called from main thread
244   for(CallbackList::iterator iter = mCallbackContainer.begin(); iter != mCallbackContainer.end(); ++iter)
245   {
246     CallbackData* data = (*iter);
247
248     if(data->mIdler)
249     {
250       ecore_idler_del(data->mIdler);
251     }
252     else if(data->mIdleEnterer)
253     {
254       ecore_idle_enterer_del(data->mIdleEnterer);
255     }
256
257     delete data;
258   }
259   mCallbackContainer.clear();
260 }
261
262 } // namespace Adaptor
263
264 } // namespace Internal
265
266 } // namespace Dali