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