Initial copy from dali-adaptor repository
[platform/core/uifw/dali-adaptor-legacy.git] / dali / internal / system / linux / callback-manager-ecore.cpp
1 /*
2  * Copyright (c) 2019 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
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 namespace Adaptor
36 {
37
38 /**
39  * Structure contains the callback function and control options
40  */
41 struct CallbackData
42 {
43
44   /**
45    * Constructor
46    */
47   CallbackData( CallbackBase* callback, bool hasReturnValue )
48   :  mCallback( callback ),
49      mRemoveFromContainerFunction( NULL ),
50      mIdler( NULL ),
51      mIdleEnterer( NULL ),
52      mHasReturnValue( hasReturnValue )
53   {
54   }
55   /**
56    * Destructor
57    */
58   ~CallbackData()
59   {
60     delete mCallback;
61     delete mRemoveFromContainerFunction;
62   }
63
64   CallbackBase*                   mCallback;       ///< call back
65   CallbackBase*                   mRemoveFromContainerFunction; ///< Called to remove the callbackdata from the callback container
66   Ecore_Idler*                    mIdler;          ///< ecore idler
67   Ecore_Idle_Enterer*             mIdleEnterer;    ///< ecore idle enterer
68   bool                            mHasReturnValue; ///< true if the callback function has a return value.
69 };
70
71 namespace
72 {
73
74 /**
75  * Called from the main thread while idle.
76  */
77 Eina_Bool IdleCallback(void *data)
78 {
79   Eina_Bool ret = ECORE_CALLBACK_CANCEL;    // CALLBACK Cancel will delete the idler so we don't need to call ecore_idler_del
80   CallbackData *callbackData = static_cast< CallbackData * >( data );
81
82   if( callbackData->mHasReturnValue )
83   {
84     // run the function
85     bool retValue = CallbackBase::ExecuteReturn< bool >( *callbackData->mCallback );
86     if( retValue )
87     {
88       // keep the callback
89       ret = ECORE_CALLBACK_RENEW;
90     }
91     else
92     {
93       // remove callback data from the container
94       CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData );
95
96       // delete our data
97       delete callbackData;
98     }
99   }
100   else
101   {
102     // remove callback data from the container
103     CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData );
104
105     // run the function
106     CallbackBase::Execute( *callbackData->mCallback );
107
108     // delete our data
109     delete callbackData;
110   }
111
112   return ret;
113 }
114
115 } // unnamed namespace
116
117 EcoreCallbackManager::EcoreCallbackManager()
118 :mRunning(false)
119 {
120 }
121
122
123 void EcoreCallbackManager::Start()
124 {
125   DALI_ASSERT_DEBUG( mRunning == false );
126
127   mRunning = true;
128 }
129
130 void EcoreCallbackManager::Stop()
131 {
132   // make sure we're not called twice
133   DALI_ASSERT_DEBUG( mRunning == true );
134
135   RemoveAllCallbacks();
136
137   mRunning = false;
138
139 }
140
141 bool EcoreCallbackManager::AddIdleCallback( CallbackBase* callback, bool hasReturnValue )
142 {
143   if( !mRunning )
144   {
145     return false;
146   }
147
148   CallbackData* callbackData = new CallbackData( callback, hasReturnValue );
149
150   callbackData->mRemoveFromContainerFunction =  MakeCallback( this, &EcoreCallbackManager::RemoveCallbackFromContainer );
151
152   // add the call back to the container
153   mCallbackContainer.push_front(callbackData);
154
155   // add the idler
156   callbackData->mIdler = ecore_idler_add( IdleCallback, callbackData);
157
158   DALI_ASSERT_ALWAYS( ( callbackData->mIdler != NULL ) && "Idle method not created" );
159
160   return true;
161 }
162
163 void EcoreCallbackManager::RemoveIdleCallback( CallbackBase* callback )
164 {
165   for( CallbackList::iterator it = mCallbackContainer.begin(),
166          endIt = mCallbackContainer.end();
167        it != endIt;
168        ++it )
169   {
170     CallbackData* data = *it;
171
172     if( data->mCallback == callback )
173     {
174       // remove callback data from the container.
175       CallbackBase::Execute( *data->mRemoveFromContainerFunction, data );
176
177       ecore_idler_del( data->mIdler );
178
179       // delete our data
180       delete data;
181
182       return;
183     }
184   }
185 }
186
187 bool EcoreCallbackManager::ProcessIdle()
188 {
189   // @todo To be implemented.
190   return false;
191 }
192
193 void EcoreCallbackManager::ClearIdleCallbacks()
194 {
195   // @todo To be implemented.
196 }
197
198 bool EcoreCallbackManager::AddIdleEntererCallback( CallbackBase* callback )
199 {
200   if( !mRunning )
201   {
202     return false;
203   }
204
205   CallbackData* callbackData = new CallbackData( callback, true );
206
207   callbackData->mRemoveFromContainerFunction = MakeCallback( this, &EcoreCallbackManager::RemoveCallbackFromContainer );
208
209   // add the call back to the container
210   mCallbackContainer.push_front( callbackData );
211
212   // add the idler
213   callbackData->mIdleEnterer = ecore_idle_enterer_add( IdleCallback, callbackData );
214
215   DALI_ASSERT_ALWAYS( ( callbackData->mIdleEnterer != NULL ) && "Idle method not created" );
216
217   return true;
218 }
219
220 void EcoreCallbackManager::RemoveIdleEntererCallback( CallbackBase* callback )
221 {
222   for( CallbackList::iterator it = mCallbackContainer.begin(),
223          endIt = mCallbackContainer.end();
224        it != endIt;
225        ++it )
226   {
227     CallbackData* data = *it;
228
229     if( data->mCallback == callback )
230     {
231       // remove callback data from the container.
232       CallbackBase::Execute( *data->mRemoveFromContainerFunction, data );
233
234       ecore_idle_enterer_del( data->mIdleEnterer );
235
236       // delete our data
237       delete data;
238
239       return;
240     }
241   }
242 }
243
244 void EcoreCallbackManager::RemoveCallbackFromContainer(CallbackData *callbackData)
245 {
246   mCallbackContainer.remove(callbackData);
247 }
248
249 void EcoreCallbackManager::RemoveAllCallbacks()
250 {
251   // always called from main thread
252   for( CallbackList::iterator  iter =  mCallbackContainer.begin(); iter != mCallbackContainer.end(); ++iter)
253   {
254     CallbackData* data = (*iter);
255
256     if( data->mIdler )
257     {
258       ecore_idler_del( data->mIdler );
259     }
260     else if( data->mIdleEnterer )
261     {
262       ecore_idle_enterer_del( data->mIdleEnterer );
263     }
264
265     delete data;
266   }
267   mCallbackContainer.clear();
268 }
269
270 // Creates a concrete interface for CallbackManager
271 CallbackManager* CallbackManager::New()
272 {
273   return new EcoreCallbackManager;
274 }
275
276 } // namespace Adaptor
277
278 } // namespace Internal
279
280 } // namespace Dali