Added support for Event creation in worker thread
[platform/framework/native/appfw.git] / src / base / inc / FBaseRt_Event.h
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.h
19  * @brief       This is the header file for the %_Event class.
20  *
21  * This file contains the declarations of the %_Event class.
22  */
23 #ifndef _FBASE_RT_INTERNAL_EVENT_H_
24 #define _FBASE_RT_INTERNAL_EVENT_H_
25
26 #include <tr1/memory>
27 #include <FOspConfig.h>
28 #include <FBaseResult.h>
29 #include <FBaseObject.h>
30 #include <FBaseColLinkedListT.h>
31 #include <FBaseRtIEventListener.h>
32 #include "FBaseRtIEventArg.h"
33 #include "FBase_HandleT.h"
34 #include "FBase_ObjectManagerT.h"
35
36 namespace Tizen { namespace Base { namespace Runtime
37 {
38
39 class _EventManager;
40
41 /**
42  * @class _Event
43  * @brief This class provides methods for delivering an event with an argument synchronously and asynchronously.
44  *
45  * This class provides methods for asynchronous operation.
46  * @see IEventListener, IEventArg
47  */
48 class _OSP_EXPORT_ _Event
49         : public Tizen::Base::Object
50 {
51 public:
52         /**
53          * This is the default constructor for this class.
54          *
55          * @since 2.0
56          */
57         _Event(void);
58
59         /**
60          * This is the destructor for this class.
61          *
62          * @since 2.0
63          */
64         virtual ~_Event(void);
65
66         /**
67          * Adds the listener object.
68          * The added listener can listen to events when they are fired.
69          *
70          * @since 2.0
71          *
72          * @return              An error code
73          * @param[in]   listener  Listener to add
74          * @param[in]   calledByCallerThread    true, to call the listener on the caller thread of this method
75          *                                                                              false, to call the listener on the thread in which the event is created.
76          * @exception   E_SUCCESS               This method is successful.
77          * @exception   E_OBJ_ALREADY_EXIST     The listener already exists.
78          * @exception   E_INVALID_OPERATION calledByCallerThread is set to true but the caller thread is a worker thread.
79          */
80         result AddListener(const IEventListener& listener, bool calledByCallerThread = false);
81
82         /**
83          * Removes a listener object.
84          * Removed listener cannot listen to events when they are fired.
85          *
86          * @since 2.0
87          * @return              An error code
88          * @param[in]   listener        Listener to remove
89          * @exception   E_SUCCESS       This method was successful.
90          * @exception   E_OBJ_NOT_FOUND The listener was not found.
91          * @see AddListener
92          */
93         result RemoveListener(const IEventListener& listener);
94
95         /**
96          * Fires the event with an argument synchronously.
97          *
98          * @since 2.0
99          *
100          * @code
101          *      void
102          *      MyClass::SendModeChangeEvent(int mode)
103          *      {
104          *              // An event argument should be created on a heap.
105          *              MyEventArg* pArg = new MyEventArg(MY_EVENT_TYPE_MODE_CHANGED, mode);
106          *
107          *              // Fires a MyEvent with asynchronous mode.
108          *              // _Event takes the ownership of the pArg and will delete it after it is delivered to listeners.
109          *              __pMyEvent->Fire(*pArg);
110          *      }
111          *
112          * @endcode
113          * @return              An error code
114          * @param[in]   arg     The event argument.
115          * @exception   E_SUCCESS               This method was successful.
116          * @exception   E_INVALID_STATE         This event has not been initialized.
117          *
118          * @remark This takes the ownership of @c arg. So arg should be created on a heap and should not be deleted.
119          */
120         result Fire(IEventArg& arg);
121
122         /**
123          * Fires the event with an argument asynchronously.
124          * This post the event in the event queue of the thread that the event belongs to. And the listener will
125          * be called on that thread context.
126          *
127          * @since 2.0
128          *
129          * @code
130          *      void
131          *      MyClass::SendModeChangeEvent(int mode)
132          *      {
133          *              // An event argument should be created on a heap.
134          *              MyEventArg* pArg = new MyEventArg(MY_EVENT_TYPE_MODE_CHANGED, mode);
135          *
136          *              // Fires a MyEvent with asynchronous mode.
137          *              // _Event takes the ownership of the pArg and will delete it after it is delivered to listeners.
138          *              __pMyEvent->Fire(*pArg);
139          *      }
140          *
141          * @endcode
142          * @return              An error code
143          * @param[in]   arg     The event argument.
144          * @exception   E_SUCCESS               This method was successful.
145          * @exception   E_INVALID_STATE         This event has not been initialized.
146          * @exception   E_INVALID_OPERATION     This event does not support asynchronous mode.
147          *
148          * @remark This takes the ownership of @c arg. So arg should be created on a heap and should not be deleted.
149          */
150         result FireAsync(IEventArg& arg);
151
152         /**
153          * Fires the event with an argument asynchronously.
154          *
155          * @since 2.0
156          *
157          * @return              The number of listeners in the current event instance.
158          */
159         int GetListenerCount(void);
160 protected:
161         /**
162          * Initializes the event
163          *
164          * @since 2.0
165          *
166          * @code
167          *      result
168          *      MyEvent::Construct(void)
169          *      {
170          *              _Event::Initialize(); // You should always invoke this method at your event construction phase
171          *      }
172          * @endcode
173          *
174          * @return              An error code
175          * @exception   E_SUCCESS               This method was successful.
176          * @exception   E_INVALID_STATE         The event was already initialized.
177          *
178          * @remark A derived class from _Event should call this method
179          */
180         result Initialize(void);
181
182         /**
183          * Implement to call the corresponding event listener's method.
184          *
185          * @since 2.0
186          *
187          * @code
188          *      void
189          *      MyEvent::FireImpl(IEventListener& listener, const IEventArg& arg)
190          *      {
191          *              const MyEventArg* pMyEventArg = dynamic_cast<const MyEventArg*>(&arg);
192          *              IMyEventListener* pMyEventListener = dynamic_cast<IMyEventListener*>(&listener);
193          *
194          *              if (pMyEventArg->GetType() == MY_EVENT_TYPE_LEVEL_CHANGED)
195          *              {
196          *                      pMyEventListener->OnLevelChanged(pMyEventArg->GetValue());
197          *              }
198          *              else (pMyEventArg->GetType() == MY_EVENT_TYPE_MODE_CHANGED)
199          *              {
200          *                      pMyEventListener->OnModeChanged(pMyEventArg->GetValue());
201          *              }
202          *              else
203          *              {
204          *
205          *              }
206          *      }
207          * @endcode
208          *
209          * @param[in]   listener        The listener instance which is currently processing
210          * @param[in]   arg             The event argument that is fired
211          *
212          * @remark A derived class must override this method.
213          */
214         virtual void FireImpl(IEventListener& listener, const IEventArg& arg);
215
216 private:
217         _Event(const _Event& rhs);
218
219         _Event& operator =(const _Event& rhs);
220
221         result Fire(std::tr1::shared_ptr< IEventArg > arg);
222
223         result ProcessListeners(std::tr1::shared_ptr< IEventArg > arg);
224
225         const _HandleT< _Event > GetHandle(void) const;
226
227         _HandleT< _Event > GetHandle(void);
228
229 private:
230         struct _ListenerInfo
231         {
232                 _ListenerInfo(void)
233                         : pListener(null)
234                 {
235                 }
236
237                 const IEventListener* pListener;
238                 _HandleT< IEventListener > listener;
239                 _HandleT< _EventManager > eventManager;
240
241                 bool operator ==(const _ListenerInfo& rhs) const;
242                 bool operator !=(const _ListenerInfo& rhs) const;
243
244                 _ListenerInfo& operator =(const _ListenerInfo& rhs);
245         };
246
247         struct _RefCount
248         {
249                 _RefCount(void);
250                 ~_RefCount(void);
251
252                 int AddRef(void);
253                 int Release(void);
254
255         private:
256                 int __count;
257                 bool __destroyed;
258
259                 friend class _Event;
260         };
261
262 private:
263         Tizen::Base::Collection::LinkedListT< _ListenerInfo > __listeners;
264
265         _RefCount* __pRefCount;
266
267         _HandleT< _EventManager > __eventManager;
268         _HandleT< _Event > __handle;
269
270         friend class _EventManager;
271 }; // _Event
272 }}} // Tizen::Base::Runtime
273 #endif // _FBASE_RT_INTERNAL_EVENT_H_