]> vaikene.ee Git - evaf/blob - src/libs/Common/eventqueue.cpp
33e73c0d6e54e26888f3fd1e7651f3fe1435c5a8
[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 }
49
50 EventQueue::~EventQueue()
51 {
52 }
53
54 bool EventQueue::event(QEvent * e)
55 {
56 // Is it an eVaf event?
57 if (e->type() == Event::eVafEvent) {
58
59 Event * event = static_cast<Event *>(e);
60
61 uint id = event->id();
62
63 // Verify that this event is registered
64 QHash<uint, QString>::const_iterator eventsIt = mEvents.constFind(id);
65 if (eventsIt == mEvents.constEnd()) {
66 return true; // We don't know it, but it is an eVaf event and we should handle it
67 }
68
69 // Send the event to all the subscribers
70 QHash<uint, QVector<QWeakPointer<QObject> > >::const_iterator subscribersIt = mSubscribers.constFind(id);
71 if (subscribersIt != mSubscribers.constEnd()) {
72 QVector<QWeakPointer<QObject> > subscribers = *subscribersIt;
73 int sz = subscribers.size();
74 for (int i = 0; i < sz; ++i) {
75
76 // Get the subscriber object and make sure that it is still alive
77 QWeakPointer<QObject> obj = subscribers.at(i);
78 if (obj.isNull()) {
79 continue;
80 }
81
82 // Notify the subscriber
83 bool rval = QCoreApplication::sendEvent(obj.data(), e);
84
85 if (rval) {
86 // The event was consumed and should be sent to any other subscribers
87 break;
88 }
89 }
90 }
91
92 return true;
93 }
94 else
95 return iEventQueue::event(e);
96 }
97
98 uint EventQueue::registerEvent(QString const & name)
99 {
100 uint id = queryEvent(name);
101
102 if (id == 0) {
103 mEvents.insert(mNextEventId, name);
104 id = mNextEventId++;
105 }
106
107 return id;
108 }
109
110 uint EventQueue::queryEvent(QString const & name) const
111 {
112 return mEvents.key(name, 0);
113 }
114
115 void EventQueue::unregisterEvent(uint id)
116 {
117 mEvents.remove(id);
118 mSubscribers.remove(id);
119 }
120
121 uint EventQueue::subscribeEvent(uint id, QObject * obj)
122 {
123 if (id == 0)
124 return 0;
125
126 // Only registered events please
127 if (mEvents.constFind(id) == mEvents.constEnd()) {
128 return 0;
129 }
130
131 // Check for duplicates
132 if (mSubscribers[id].indexOf(obj) != -1)
133 return id;
134
135 mSubscribers[id].append(obj);
136
137 return id;
138 }
139
140 void EventQueue::unsubscribeEvent(uint id, QObject * obj)
141 {
142 if (id == 0)
143 return;
144
145 // Is the event registered?
146 if (mEvents.constFind(id) == mEvents.constEnd())
147 return;
148
149 // Remove from the list of subscribers
150 QVector<QWeakPointer<QObject> >::iterator it = mSubscribers[id].begin();
151 QVector<QWeakPointer<QObject> >::iterator e = mSubscribers[id].end();
152 while (it != e) {
153 if (!it->isNull() && it->data() == obj)
154 it = mSubscribers[id].erase(it);
155 else
156 ++it;
157 }
158 }
159
160 void EventQueue::broadcastEvent(Event * event)
161 {
162 QCoreApplication::postEvent(this, event);
163 }