Merge "Revert "fixed PLM issue. Assert occured when an application was closed using...
[platform/framework/native/appfw.git] / src / base / runtime / FBaseRt_Event.cpp
1 //
2 // Copyright (c) 2012 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  * @file        FBaseRt_Event.cpp
19  * @brief       This is the implementation file for the _Event class.
20  *
21  */
22
23 #include <new>
24
25 #include <FBaseColIEnumeratorT.h>
26
27 #include <FBaseSysLog.h>
28 #include "FBaseRt_Event.h"
29 #include "FBaseRt_EventManager.h"
30
31 using namespace Tizen::Base;
32 using namespace Tizen::Base::Collection;
33 using namespace Tizen::Base::Runtime;
34
35 namespace Tizen { namespace Base { namespace Runtime
36 {
37
38 _Event::_ListenerInfo&
39 _Event::_ListenerInfo::operator =(const _ListenerInfo& rhs)
40 {
41         if (this != &rhs)
42         {
43                 pListener = rhs.pListener;
44                 listener = rhs.listener;
45                 eventManager = rhs.eventManager;
46         }
47
48         return *this;
49 }
50
51 bool
52 _Event::_ListenerInfo::operator ==(const _ListenerInfo& rhs) const
53 {
54         if (listener == rhs.listener && eventManager == rhs.eventManager)
55         {
56                 return true;
57         }
58
59         return false;
60 }
61
62 bool
63 _Event::_ListenerInfo::operator !=(const _ListenerInfo& rhs) const
64 {
65         if (listener != rhs.listener || eventManager != rhs.eventManager)
66         {
67                 return true;
68         }
69
70         return false;
71 }
72
73 _Event::_RefCount::_RefCount(void)
74         : __count(1)
75         , __destroyed(false)
76 {
77
78 }
79
80 _Event::_RefCount::~_RefCount(void)
81 {
82
83 }
84
85 int
86 _Event::_RefCount::AddRef(void)
87 {
88         __count++;
89         return __count;
90 }
91
92 int
93 _Event::_RefCount::Release(void)
94 {
95         __count--;
96         if (__count == 0)
97         {
98                 delete this;
99                 return 0;
100         }
101
102         return __count;
103 }
104
105 _Event::_Event(void)
106 {
107         __pRefCount = new (std::nothrow) _RefCount();
108
109         __handle = _EventManager::GetEventObjectManager().Register(*this);
110 }
111
112 _Event::~_Event(void)
113 {
114         __pRefCount->__destroyed = true;
115         __pRefCount->Release();
116
117         if (__handle.IsValid())
118         {
119                 _EventManager::GetEventObjectManager().Unregister(__handle);
120         }
121 }
122
123 result
124 _Event::AddListener(const IEventListener& listener, bool calledByCallerThread)
125 {
126         result r = E_SUCCESS;
127         bool exist = false;
128         _ListenerInfo listenerInfo;
129         _HandleT< _EventManager > eventManager;
130
131         if (calledByCallerThread)
132         {
133                 _EventManager* pEventManager = _EventManager::GetCurrentEventManager();
134                 SysTryReturnResult(NID_BASE_RT, pEventManager != null, E_INVALID_OPERATION
135                                                   , "The caller thread is not an event driven thread.");
136
137                 eventManager = pEventManager->GetHandle();
138         }
139
140         IEnumeratorT< _ListenerInfo >* pEnum = __listeners.GetEnumeratorN();
141         SysTryReturnResult(NID_BASE_RT, pEnum != null, E_OUT_OF_MEMORY, "Not enough memory.");
142
143         while (pEnum->MoveNext() == E_SUCCESS)
144         {
145                 pEnum->GetCurrent(listenerInfo);
146
147                 if (&listener == listenerInfo.pListener)
148                 {
149                         exist = true;
150                         break;
151                 }
152         }
153
154         delete pEnum;
155
156         SysTryReturnResult(NID_BASE_RT, !exist, E_OBJ_ALREADY_EXIST, "[E_OBJ_ALREADY_EXIST] Listener already exist.");
157
158         listenerInfo.pListener = &listener;
159         listenerInfo.listener = _EventManager::GetEventListenerObjectManager().Register(listener);
160         listenerInfo.eventManager = eventManager;
161
162         r = __listeners.Add(listenerInfo);
163         SysTryReturn(NID_BASE_RT, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
164
165         return E_SUCCESS;
166 }
167
168 result
169 _Event::RemoveListener(const IEventListener& listener)
170 {
171         result r = E_SUCCESS;
172         bool exist = false;
173         _ListenerInfo listenerInfo;
174
175         IEnumeratorT< _ListenerInfo >* pEnum = __listeners.GetEnumeratorN();
176         SysTryReturnResult(NID_BASE_RT, pEnum != null, E_OUT_OF_MEMORY, "Not enough memory.");
177
178         while (pEnum->MoveNext() == E_SUCCESS)
179         {
180                 pEnum->GetCurrent(listenerInfo);
181
182                 if (listenerInfo.pListener == &listener)
183                 {
184                         r = __listeners.Remove(listenerInfo);
185                         SysTryLog(NID_BASE_RT, !IsFailed(r), "[%s] Propagating.", GetErrorMessage(r));
186
187                         _EventManager::GetEventListenerObjectManager().Unregister(listenerInfo.listener);
188
189                         exist = true;
190                         break;
191                 }
192         }
193
194         delete pEnum;
195
196         SysTryReturnResult(NID_BASE_RT, exist, E_OBJ_NOT_FOUND, "Listener not found.");
197
198         return E_SUCCESS;
199 }
200
201 result
202 _Event::Initialize(void)
203 {
204         result r = E_SUCCESS;
205
206         _EventManager* pEventManager = _EventManager::GetCurrentEventManager();
207         SysTryReturnResult(NID_BASE_RT, pEventManager != null, E_INVALID_OPERATION, "Event manager does not exist.");
208
209         r = pEventManager->RegisterEvent(this->GetHandle());
210         SysTryReturn(NID_BASE_RT, !IsFailed(r), r, r, "[%s] Failed to register an event.", GetErrorMessage(r));
211
212         __eventManager = pEventManager->GetHandle();
213
214         return E_SUCCESS;
215 }
216
217 result
218 _Event::FireAsync(IEventArg& arg)
219 {
220         SysTryReturnResult(NID_BASE_RT, __eventManager.IsValid(), E_INVALID_STATE, "Event manager is invalid state.");
221
222         _EventManager* pEventManager = _EventManager::GetEventManagerByHandle(__eventManager);
223         SysTryReturnResult(NID_BASE_RT, pEventManager != null, E_INVALID_STATE, "Event manager is invalid state.");
224
225         pEventManager->FireEventAsync(__handle, std::tr1::shared_ptr< IEventArg >(&arg));
226
227         return E_SUCCESS;
228 }
229
230 result
231 _Event::Fire(IEventArg& arg)
232 {
233         std::tr1::shared_ptr< IEventArg > sharedArg(&arg);
234
235         return Fire(sharedArg);
236 }
237
238 result
239 _Event::Fire(std::tr1::shared_ptr< IEventArg > arg)
240 {
241         _RefCount* pRefCount = __pRefCount;
242
243         pRefCount->AddRef();
244
245         ProcessListeners(arg);
246
247         pRefCount->Release();
248
249         return E_SUCCESS;
250 }
251
252 result
253 _Event::ProcessListeners(std::tr1::shared_ptr< IEventArg > arg)
254 {
255         _RefCount* pRefCount = __pRefCount;
256
257         _ListenerInfo listenerInfo;
258         _EventManager* pEventManager = null;
259         IEventListener* pEventListener = null;
260
261         IEnumeratorT< _ListenerInfo >* pEnum = __listeners.GetEnumeratorN();
262         SysTryReturnResult(NID_BASE_RT, pEnum != null, E_OUT_OF_MEMORY, "Not enough memory.");
263
264         while (pEnum->MoveNext() == E_SUCCESS)
265         {
266                 pEnum->GetCurrent(listenerInfo);
267
268                 if (listenerInfo.eventManager.IsValid())
269                 {
270                         pEventManager = _EventManager::GetEventManagerByHandle(listenerInfo.eventManager);
271                         if (pEventManager == null)
272                         {
273                                 continue;
274                         }
275
276                         _EventManager* pCurrentEventManager = _EventManager::GetCurrentEventManager();
277                         if (pCurrentEventManager != null)
278                         {
279                                 if (pEventManager->GetHandle() != pCurrentEventManager->GetHandle())
280                                 {
281                                         pEventManager->CallListenerAsync(this->GetHandle(), arg, listenerInfo.listener);
282                                         continue;
283                                 }
284                         }
285                         else
286                         {
287                                 pEventManager->CallListenerAsync(this->GetHandle(), arg, listenerInfo.listener);
288                                 continue;
289
290                         }
291                 }
292
293                 pEventListener = _EventManager::GetEventListenerObjectManager().GetObject(listenerInfo.listener);
294                 if (pEventListener != null)
295                 {
296                         FireImpl(*pEventListener, *arg);
297                         if (pRefCount->__destroyed)
298                         {
299                                 break;
300                         }
301                 }
302         }
303
304         delete pEnum;
305         return E_SUCCESS;
306 }
307
308 int 
309 _Event::GetListenerCount(void)
310 {
311         return __listeners.GetCount();  
312 }
313
314 const _HandleT< _Event >
315 _Event::GetHandle(void) const
316 {
317         return __handle;
318 }
319
320 _HandleT< _Event >
321 _Event::GetHandle(void)
322 {
323         return __handle;
324 }
325
326 void
327 _Event::FireImpl(IEventListener& listener, const IEventArg& arg)
328 {
329
330 }
331 } } } // Tizen::Base::Runtime