Adaptor refactor
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / common / callback-manager-ecore.cpp
1 /*
2  * Copyright (c) 2017 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/common/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 )
51   :  mCallback(callback),
52      mRemoveFromContainerFunction(NULL),
53      mIdler(NULL)
54   {
55   }
56   /**
57    * Destructor
58    */
59   ~CallbackData()
60   {
61     delete mCallback;
62     delete mRemoveFromContainerFunction;
63   }
64
65   CallbackBase*                   mCallback;      ///< call back
66   CallbackBase*                   mRemoveFromContainerFunction; ///< Called to remove the callbackdata from the callback container
67   Ecore_Idler*                    mIdler;         ///< ecore idler
68  };
69
70 namespace
71 {
72
73 /**
74  * Called from the main thread while idle.
75  */
76 Eina_Bool IdleCallback(void *data)
77 {
78   CallbackData *callbackData = static_cast< CallbackData * >( data );
79
80   // remove callback data from the container
81   CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData );
82
83   // run the function
84   CallbackBase::Execute( *callbackData->mCallback );
85
86   // delete our data
87   delete callbackData;
88
89   // CALLBACK Cancel will delete the idler so we don't need to call ecore_idler_del
90   return ECORE_CALLBACK_CANCEL;
91 }
92
93 } // unnamed namespace
94
95 EcoreCallbackManager::EcoreCallbackManager()
96 :mRunning(false)
97 {
98 }
99
100
101 void EcoreCallbackManager::Start()
102 {
103   DALI_ASSERT_DEBUG( mRunning == false );
104
105   mRunning = true;
106 }
107
108 void EcoreCallbackManager::Stop()
109 {
110   // make sure we're not called twice
111   DALI_ASSERT_DEBUG( mRunning == true );
112
113   RemoveAllCallbacks();
114
115   mRunning = false;
116
117 }
118
119 bool EcoreCallbackManager::AddIdleCallback( CallbackBase* callback )
120 {
121   if( !mRunning )
122   {
123     return false;
124   }
125
126   CallbackData* callbackData = new CallbackData( callback );
127
128   callbackData->mRemoveFromContainerFunction =  MakeCallback( this, &EcoreCallbackManager::RemoveCallbackFromContainer );
129
130   // add the call back to the container
131   mCallbackContainer.push_front(callbackData);
132
133   // add the idler
134   callbackData->mIdler = ecore_idler_add( IdleCallback, callbackData);
135
136   DALI_ASSERT_ALWAYS( ( callbackData->mIdler != NULL ) && "Idle method not created" );
137
138   return true;
139 }
140
141 void EcoreCallbackManager::RemoveIdleCallback( CallbackBase* callback )
142 {
143   for( CallbackList::iterator it = mCallbackContainer.begin(),
144          endIt = mCallbackContainer.end();
145        it != endIt;
146        ++it )
147   {
148     CallbackData* data = *it;
149
150     if( data->mCallback == callback )
151     {
152       // remove callback data from the container.
153       CallbackBase::Execute( *data->mRemoveFromContainerFunction, data );
154
155       ecore_idler_del( data->mIdler );
156     }
157   }
158 }
159
160 void EcoreCallbackManager::RemoveCallbackFromContainer(CallbackData *callbackData)
161 {
162   mCallbackContainer.remove(callbackData);
163 }
164
165 void EcoreCallbackManager::RemoveAllCallbacks()
166 {
167   // always called from main thread
168   for( CallbackList::iterator  iter =  mCallbackContainer.begin(); iter != mCallbackContainer.end(); ++iter)
169   {
170     CallbackData* data = (*iter);
171
172     ecore_idler_del( data->mIdler );
173
174     delete data;
175
176   }
177   mCallbackContainer.clear();
178 }
179
180 // Creates a concrete interface for CallbackManager
181 CallbackManager* CallbackManager::New()
182 {
183   return new EcoreCallbackManager;
184 }
185
186 } // namespace Adaptor
187
188 } // namespace Internal
189
190 } // namespace Dali
191
192 #pragma GCC diagnostic pop