[Tizen] Add codes for Dali Windows Backend
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / linux / callback-manager-ecore.cpp
1 /*
2  * Copyright (c) 2018 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 // Ecore is littered with C style cast
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wold-style-cast"
25 #include <Ecore.h>
26
27 #include <dali/integration-api/debug.h>
28
29 // INTERNAL INCLUDES
30
31
32 namespace Dali
33 {
34
35 namespace Internal
36 {
37
38 namespace Adaptor
39 {
40
41 /**
42  * Structure contains the callback function and control options
43  */
44 struct CallbackData
45 {
46
47   /**
48    * Constructor
49    */
50   CallbackData( CallbackBase* callback, bool hasReturnValue )
51   :  mCallback( callback ),
52      mRemoveFromContainerFunction( NULL ),
53      mIdler( NULL ),
54      mIdleEnterer( NULL ),
55      mHasReturnValue( hasReturnValue )
56   {
57   }
58   /**
59    * Destructor
60    */
61   ~CallbackData()
62   {
63     delete mCallback;
64     delete mRemoveFromContainerFunction;
65   }
66
67   CallbackBase*                   mCallback;       ///< call back
68   CallbackBase*                   mRemoveFromContainerFunction; ///< Called to remove the callbackdata from the callback container
69   Ecore_Idler*                    mIdler;          ///< ecore idler
70   Ecore_Idle_Enterer*             mIdleEnterer;    ///< ecore idle enterer
71   bool                            mHasReturnValue; ///< true if the callback function has a return value.
72 };
73
74 namespace
75 {
76
77 /**
78  * Called from the main thread while idle.
79  */
80 Eina_Bool IdleCallback(void *data)
81 {
82   Eina_Bool ret = ECORE_CALLBACK_CANCEL;    // CALLBACK Cancel will delete the idler so we don't need to call ecore_idler_del
83   CallbackData *callbackData = static_cast< CallbackData * >( data );
84
85   if( callbackData->mHasReturnValue )
86   {
87     // run the function
88     bool retValue = CallbackBase::ExecuteReturn< bool >( *callbackData->mCallback );
89     if( retValue )
90     {
91       // keep the callback
92       ret = ECORE_CALLBACK_RENEW;
93     }
94     else
95     {
96       // remove callback data from the container
97       CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData );
98
99       // delete our data
100       delete callbackData;
101     }
102   }
103   else
104   {
105     // remove callback data from the container
106     CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData );
107
108     // run the function
109     CallbackBase::Execute( *callbackData->mCallback );
110
111     // delete our data
112     delete callbackData;
113   }
114
115   return ret;
116 }
117
118 } // unnamed namespace
119
120 EcoreCallbackManager::EcoreCallbackManager()
121 :mRunning(false)
122 {
123 }
124
125
126 void EcoreCallbackManager::Start()
127 {
128   DALI_ASSERT_DEBUG( mRunning == false );
129
130   mRunning = true;
131 }
132
133 void EcoreCallbackManager::Stop()
134 {
135   // make sure we're not called twice
136   DALI_ASSERT_DEBUG( mRunning == true );
137
138   RemoveAllCallbacks();
139
140   mRunning = false;
141
142 }
143
144 bool EcoreCallbackManager::AddIdleCallback( CallbackBase* callback, bool hasReturnValue )
145 {
146   if( !mRunning )
147   {
148     return false;
149   }
150
151   CallbackData* callbackData = new CallbackData( callback, hasReturnValue );
152
153   callbackData->mRemoveFromContainerFunction =  MakeCallback( this, &EcoreCallbackManager::RemoveCallbackFromContainer );
154
155   // add the call back to the container
156   mCallbackContainer.push_front(callbackData);
157
158   // add the idler
159   callbackData->mIdler = ecore_idler_add( IdleCallback, callbackData);
160
161   DALI_ASSERT_ALWAYS( ( callbackData->mIdler != NULL ) && "Idle method not created" );
162
163   return true;
164 }
165
166 void EcoreCallbackManager::RemoveIdleCallback( CallbackBase* callback )
167 {
168   for( CallbackList::iterator it = mCallbackContainer.begin(),
169          endIt = mCallbackContainer.end();
170        it != endIt;
171        ++it )
172   {
173     CallbackData* data = *it;
174
175     if( data->mCallback == callback )
176     {
177       // remove callback data from the container.
178       CallbackBase::Execute( *data->mRemoveFromContainerFunction, data );
179
180       ecore_idler_del( data->mIdler );
181
182       // delete our data
183       delete data;
184
185       return;
186     }
187   }
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 // Creates a concrete interface for CallbackManager
263 CallbackManager* CallbackManager::New()
264 {
265   return new EcoreCallbackManager;
266 }
267
268 } // namespace Adaptor
269
270 } // namespace Internal
271
272 } // namespace Dali
273
274 #pragma GCC diagnostic pop