Using a queue ensures that events will be processed in order, i.e. if processing
an events generates new ones, those won't be handled before the first one is fully done.
We also let Qt process its own QEvents in between, in order to not block things like
network handling.
#include "eventmanager.h"
#include "eventmanager.h"
+#include <QCoreApplication>
+#include <QEvent>
#include <QDebug>
#include "event.h"
#include <QDebug>
#include "event.h"
+EventManager::~EventManager() {
+ // pending events won't be delivered anymore, but we do need to delete them
+ qDeleteAll(_eventQueue);
+}
+
QMetaEnum EventManager::eventEnum() const {
if(!_enum.isValid()) {
int eventEnumIndex = metaObject()->indexOfEnumerator("EventType");
QMetaEnum EventManager::eventEnum() const {
if(!_enum.isValid()) {
int eventEnumIndex = metaObject()->indexOfEnumerator("EventType");
// not threadsafe! if we should want that, we need to add a mutexed queue somewhere in this general area.
void EventManager::sendEvent(Event *event) {
// qDebug() << "Sending" << event;
// not threadsafe! if we should want that, we need to add a mutexed queue somewhere in this general area.
void EventManager::sendEvent(Event *event) {
// qDebug() << "Sending" << event;
+ _eventQueue.append(event);
+ if(_eventQueue.count() == 1) // we're not currently processing another event
+ processEvents();
+}
+
+void EventManager::customEvent(QEvent *event) {
+ if(event->type() == QEvent::User) {
+ processEvents();
+ event->accept();
+ }
+}
+
+void EventManager::processEvents() {
+ // we only process one event at a time for now, and let Qt's own event processing come in between
+ if(_eventQueue.isEmpty())
+ return;
+ dispatchEvent(_eventQueue.first());
+ _eventQueue.removeFirst();
+ if(_eventQueue.count())
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
}
void EventManager::dispatchEvent(Event *event) {
}
void EventManager::dispatchEvent(Event *event) {
+ //qDebug() << "Dispatching" << event;
+
// we try handlers from specialized to generic by masking the enum
// build a list sorted by priorities that contains all eligible handlers
// we try handlers from specialized to generic by masking the enum
// build a list sorted by priorities that contains all eligible handlers
};
EventManager(QObject *parent = 0);
};
EventManager(QObject *parent = 0);
- //virtual ~EventManager();
+ virtual ~EventManager();
EventType eventTypeByName(const QString &name) const;
EventType eventGroupByName(const QString &name) const;
EventType eventTypeByName(const QString &name) const;
EventType eventGroupByName(const QString &name) const;
*/
void sendEvent(Event *event);
*/
void sendEvent(Event *event);
+protected:
+ virtual void customEvent(QEvent *event);
+
private:
struct Handler {
QObject *object;
private:
struct Handler {
QObject *object;
//! Add handlers to an existing sorted (by priority) handler list
void insertHandlers(const QList<Handler> &newHandlers, QList<Handler> &existing);
//! Add handlers to an existing sorted (by priority) handler list
void insertHandlers(const QList<Handler> &newHandlers, QList<Handler> &existing);
void dispatchEvent(Event *event);
//! @return the EventType enum
void dispatchEvent(Event *event);
//! @return the EventType enum
HandlerHash _registeredHandlers;
mutable QMetaEnum _enum;
HandlerHash _registeredHandlers;
mutable QMetaEnum _enum;
+
+ QList<Event *> _eventQueue;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(EventManager::EventFlags);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(EventManager::EventFlags);