ProcessIdle method added to Adaptor.
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / android / callback-manager-android.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/android/callback-manager-android.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/adaptor-framework/android/android-framework.h>
24
25 // INTERNAL INCLUDES
26 #include <dali/internal/adaptor/common/framework.h>
27 #include <dali/internal/adaptor/android/android-framework-impl.h>
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   : mIdleId( 0 ),
49     mCallback( callback ),
50     mRemoveFromContainerFunction( NULL ),
51     mHasReturnValue( hasReturnValue )
52   {
53   }
54   /**
55    * Destructor
56    */
57   ~CallbackData()
58   {
59     delete mCallback;
60     delete mRemoveFromContainerFunction;
61   }
62
63   unsigned int                    mIdleId;
64   CallbackBase*                   mCallback;       ///< call back
65   CallbackBase*                   mRemoveFromContainerFunction; ///< Called to remove the callbackdata from the callback container
66   bool                            mHasReturnValue; ///< true if the callback function has a return value.
67 };
68
69 namespace
70 {
71
72 /**
73  * Called from the main thread while idle.
74  */
75 bool IdleCallback(void *data)
76 {
77   bool ret = false;
78   CallbackData *callbackData = static_cast< CallbackData * >( data );
79
80   if( callbackData->mHasReturnValue )
81   {
82     // run the function
83     bool retValue = CallbackBase::ExecuteReturn< bool >( *callbackData->mCallback );
84     if( retValue )
85     {
86       // keep the callback
87       ret = true;
88     }
89     else
90     {
91       // remove callback data from the container
92       CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData );
93
94       // delete our data
95       delete callbackData;
96     }
97   }
98   else
99   {
100     // remove callback data from the container
101     CallbackBase::Execute( *callbackData->mRemoveFromContainerFunction, callbackData );
102
103     // run the function
104     CallbackBase::Execute( *callbackData->mCallback );
105
106     // delete our data
107     delete callbackData;
108   }
109
110   return ret;
111 }
112
113 } // unnamed namespace
114
115 AndroidCallbackManager::AndroidCallbackManager()
116   : mRunning( false )
117 {
118 }
119
120
121 void AndroidCallbackManager::Start()
122 {
123   DALI_ASSERT_DEBUG( mRunning == false );
124
125   mRunning = true;
126 }
127
128 void AndroidCallbackManager::Stop()
129 {
130   // make sure we're not called twice
131   DALI_ASSERT_DEBUG( mRunning == true );
132
133   RemoveAllCallbacks();
134
135   mRunning = false;
136
137 }
138
139 bool AndroidCallbackManager::AddIdleCallback( CallbackBase* callback, bool hasReturnValue )
140 {
141   if( !mRunning )
142   {
143     return false;
144   }
145
146   CallbackData* callbackData = new CallbackData( callback, hasReturnValue );
147   callbackData->mRemoveFromContainerFunction = MakeCallback( this, &AndroidCallbackManager::RemoveCallbackFromContainer );
148   callbackData->mIdleId = AndroidFramework::GetFramework( Dali::Integration::AndroidFramework::Get() ).AddIdle( 0, callbackData, IdleCallback );
149
150   // add the call back to the container
151   mCallbackContainer.push_front( callbackData );
152   return true;
153 }
154
155 void AndroidCallbackManager::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       AndroidFramework::GetFramework( AndroidFramework::Get() ).RemoveIdle( data->mIdleId );
169       return;
170     }
171   }
172 }
173
174 bool AndroidCallbackManager::ProcessIdle()
175 {
176   // @todo To be implemented.
177   return false;
178 }
179
180 void AndroidCallbackManager::ClearIdleCallbacks()
181 {
182   // @todo To be implemented.
183 }
184
185 bool AndroidCallbackManager::AddIdleEntererCallback( CallbackBase* callback )
186 {
187   if( !mRunning )
188   {
189     return false;
190   }
191
192   CallbackData* callbackData = new CallbackData( callback, true );
193
194   callbackData->mRemoveFromContainerFunction = MakeCallback( this, &AndroidCallbackManager::RemoveCallbackFromContainer );
195   callbackData->mIdleId = AndroidFramework::GetFramework( Dali::Integration::AndroidFramework::Get() ).AddIdle( 0, callbackData, IdleCallback );
196
197   // add the call back to the container
198   mCallbackContainer.push_front( callbackData );
199   return true;
200 }
201
202 void AndroidCallbackManager::RemoveIdleEntererCallback( CallbackBase* callback )
203 {
204   for( CallbackList::iterator it = mCallbackContainer.begin(),
205          endIt = mCallbackContainer.end();
206        it != endIt;
207        ++it )
208   {
209     CallbackData* data = *it;
210
211     if( data->mCallback == callback )
212     {
213       // remove callback data from the container.
214       CallbackBase::Execute( *data->mRemoveFromContainerFunction, data );
215       AndroidFramework::GetFramework( Dali::Integration::AndroidFramework::Get() ).RemoveIdle( data->mIdleId );
216       return;
217     }
218   }
219 }
220
221 void AndroidCallbackManager::RemoveCallbackFromContainer( CallbackData *callbackData )
222 {
223   mCallbackContainer.remove( callbackData );
224 }
225
226 void AndroidCallbackManager::RemoveAllCallbacks()
227 {
228   // always called from main thread
229   for( CallbackList::iterator  iter =  mCallbackContainer.begin(); iter != mCallbackContainer.end(); ++iter )
230   {
231     CallbackData* data = (*iter);
232     AndroidFramework::GetFramework( Dali::Integration::AndroidFramework::Get() ).RemoveIdle( data->mIdleId );
233     delete data;
234   }
235   mCallbackContainer.clear();
236 }
237
238 // Creates a concrete interface for CallbackManager
239 CallbackManager* CallbackManager::New()
240 {
241   return new AndroidCallbackManager;
242 }
243
244 } // namespace Adaptor
245
246 } // namespace Internal
247
248 } // namespace Dali
249
250