tizen beta release
[framework/web/wrt-plugins-common.git] / src / Commons / ListenerEventEmitter.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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  * @author    Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
18  */
19
20 #ifndef WRTDEVICEAPIS_COMMONS_LISTENER_EVENT_EMITTER_H_
21 #define WRTDEVICEAPIS_COMMONS_LISTENER_EVENT_EMITTER_H_
22
23 #include <stdint.h>
24 #include <dpl/noncopyable.h>
25 #include <dpl/shared_ptr.h>
26 #include <dpl/mutex.h>
27 #include <Commons/EventListener.h>
28 #include <Commons/ListenerEvent.h>
29
30 namespace WrtDeviceApis {
31 namespace Commons {
32
33 template<class EmitterClass>
34 class Emitters;
35
36 /**
37  * Creates listener events in the abstraction layer in response to some
38  * asynchronous action.
39  * To enable passing events from abstract layer to layer that uses it, first
40  * proper event emitter should be registered in abstract layer by the layer
41  * that uses it. Then when some action happens in abstract layer event should be
42  * created and passed to this emitter's emit() function. Then emitter passes
43  * this event to proper listener.
44  * Template parameter should be class that derives from @see ListenerEvent.
45  */
46 template<class EventClass>
47 class ListenerEventEmitter : private DPL::Noncopyable
48 {
49   public:
50     typedef EventClass EventType;
51     typedef DPL::SharedPtr<EventType> EventPtrType;
52     typedef ListenerEventEmitter<EventType> Type;
53     typedef typename ListenerEvent<EventType>::PrivateDataType
54     EventPrivateDataType;
55     typedef typename ListenerEvent<EventType>::PrivateDataTypePtr
56     EventPrivateDataTypePtr;
57     typedef EventListener<EventType> ListenerType;
58     typedef uintptr_t IdType;
59
60     /**
61      * Empty (NULL) value of emitter's Id.
62      */
63     static const IdType emptyId;
64
65   public:
66     ListenerEventEmitter() : m_listener(NULL)
67     {
68     }
69
70   public:
71     virtual ~ListenerEventEmitter()
72     {
73     }
74
75     /**
76      * Sets event's private data.
77      * Event's private data object has to implement @see IEventPrivateData interface.
78      * @param data Private data.
79      * @remarks Practically private dat should be only set at object creation and
80      *          not chaged during this object lifetime.
81      */
82     virtual void setEventPrivateData(const EventPrivateDataTypePtr& data)
83     {
84         DPL::Mutex::ScopedLock lock(&m_mtx);
85         m_privateData = data;
86     }
87
88     /**
89      * Gets event's private data.
90      * @return Private data.
91      */
92     virtual EventPrivateDataTypePtr getEventPrivateData()
93     {
94         DPL::Mutex::ScopedLock lock(&m_mtx);
95         return m_privateData;
96     }
97
98     /**
99      * Sets listener.
100      * Object set as listener has to implement @see EventListener interface.
101      * @param listener Listener object.
102      * @remarks Doesn't take ownership over this object.
103      *          It's suggested to use singletons to have one listener for all
104      *          events (no dynamic allocation overhead).
105      */
106     virtual void setListener(ListenerType* listener)
107     {
108         DPL::Mutex::ScopedLock lock(&m_mtx);
109         m_listener = listener;
110     }
111
112     /**
113      * Emits event.
114      * @param event Event to emit.
115      */
116     virtual void emit(const EventPtrType& event)
117     {
118         DPL::Mutex::ScopedLock lock(&m_mtx);
119         EventPtrType copy(new EventType(*event.Get()));
120         if (m_listener) {
121             copy->setPrivateData(m_privateData);
122             m_listener->postAnswer(copy);
123         }
124     }
125
126     /**
127      * Gets id.
128      * @return Event's id.
129      * @remarks Id is implemented as value of `this` pointer.
130      */
131     virtual IdType getId()
132     {
133         return reinterpret_cast<IdType>(this);
134     }
135
136   protected:
137     DPL::Mutex m_mtx; ///< Mutex for thread-safety.
138     ListenerType* m_listener; ///< Event listener object.
139     EventPrivateDataTypePtr m_privateData; ///< Private data.
140 };
141
142 template<class EventClass>
143 const typename ListenerEventEmitter<EventClass>::IdType ListenerEventEmitter<
144     EventClass>::emptyId = 0;
145
146 }
147 } // WrtDeviceApisCommon
148
149 #endif // WRTDEVICEAPIS_COMMONS_LISTENER_EVENT_EMITTER_H_