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