]> vaikene.ee Git - evaf/blob - src/libs/Common/eventqueue.cpp
* The iEventQueue interface is now properly registered.
[evaf] / src / libs / Common / eventqueue.cpp
1 /**
2 * @file Common/eventqueue.cpp
3 * @brief Event queue interface implementation
4 * @author Enar Vaikene
5 *
6 * Copyright (c) 2011 Enar Vaikene
7 *
8 * This file is part of the eVaf C++ cross-platform application development framework.
9 *
10 * This file can be used under the terms of the GNU General Public License
11 * version 3.0 as published by the Free Software Foundation and appearing in
12 * the file LICENSE included in the packaging of this file. Please review the
13 * the following information to ensure the GNU General Public License version
14 * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
15 *
16 * Alternatively, this file may be used in accordance with the Commercial License
17 * Agreement provided with the Software.
18 */
19
20 #include "eventqueue.h"
21 #include "event.h"
22 #include "globals.h"
23 #include "iregistry.h"
24 #include "version.h"
25
26 #include <QtCore>
27
28
29 //-------------------------------------------------------------------
30
31 using namespace eVaf::Common;
32
33 iEventQueue * iEventQueue::instance()
34 {
35 static Internal::EventQueue singleton;
36 return &singleton;
37 }
38
39
40 //-------------------------------------------------------------------
41
42 using namespace eVaf::Common::Internal;
43
44 EventQueue::EventQueue()
45 : iEventQueue()
46 , mNextEventId(1)
47 {
48 iRegistry::instance()->registerInterface("iEventQueue", this);
49 }
50
51 EventQueue::~EventQueue()
52 {
53 }
54
55 bool EventQueue::event(QEvent * e)
56 {
57 // Is it an eVaf event?
58 if (e->type() == Event::eVafEvent) {
59
60 Event * event = static_cast<Event *>(e);
61
62 uint id = event->id();
63
64 // Verify that this event is registered
65 QHash<uint, QString>::const_iterator eventsIt = mEvents.constFind(id);
66 if (eventsIt == mEvents.constEnd()) {
67 return true; // We don't know it, but it is an eVaf event and we should handle it
68 }
69
70 // Send the event to all the subscribers
71 QHash<uint, QVector<QWeakPointer<QObject> > >::const_iterator subscribersIt = mSubscribers.constFind(id);
72 if (subscribersIt != mSubscribers.constEnd()) {
73 QVector<QWeakPointer<QObject> > subscribers = *subscribersIt;
74 int sz = subscribers.size();
75 for (int i = 0; i < sz; ++i) {
76
77 // Get the subscriber object and make sure that it is still alive
78 QWeakPointer<QObject> obj = subscribers.at(i);
79 if (obj.isNull()) {
80 continue;
81 }
82
83 // Notify the subscriber
84 bool rval = QCoreApplication::sendEvent(obj.data(), e);
85
86 if (rval) {
87 // The event was consumed and should be sent to any other subscribers
88 break;
89 }
90 }
91 }
92
93 return true;
94 }
95 else
96 return iEventQueue::event(e);
97 }
98
99 uint EventQueue::registerEvent(QString const & name)
100 {
101 uint id = queryEvent(name);
102
103 if (id == 0) {
104 mEvents.insert(mNextEventId, name);
105 id = mNextEventId++;
106 }
107
108 return id;
109 }
110
111 uint EventQueue::queryEvent(QString const & name) const
112 {
113 return mEvents.key(name, 0);
114 }
115
116 void EventQueue::unregisterEvent(uint id)
117 {
118 mEvents.remove(id);
119 mSubscribers.remove(id);
120 }
121
122 uint EventQueue::subscribeEvent(uint id, QObject * obj)
123 {
124 if (id == 0)
125 return 0;
126
127 // Only registered events please
128 if (mEvents.constFind(id) == mEvents.constEnd()) {
129 return 0;
130 }
131
132 // Check for duplicates
133 if (mSubscribers[id].indexOf(obj) != -1)
134 return id;
135
136 mSubscribers[id].append(obj);
137
138 return id;
139 }
140
141 void EventQueue::unsubscribeEvent(uint id, QObject * obj)
142 {
143 if (id == 0)
144 return;
145
146 // Is the event registered?
147 if (mEvents.constFind(id) == mEvents.constEnd())
148 return;
149
150 // Remove from the list of subscribers
151 QVector<QWeakPointer<QObject> >::iterator it = mSubscribers[id].begin();
152 QVector<QWeakPointer<QObject> >::iterator e = mSubscribers[id].end();
153 while (it != e) {
154 if (!it->isNull() && it->data() == obj)
155 it = mSubscribers[id].erase(it);
156 else
157 ++it;
158 }
159 }
160
161 void EventQueue::broadcastEvent(Event * event)
162 {
163 QCoreApplication::postEvent(this, event);
164 }