From eca32e09b23dd261d7eaf11a4843949220b302d4 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Sat, 25 Sep 2010 17:04:26 +0200 Subject: [PATCH] Use a queue for events 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. --- src/common/eventmanager.cpp | 30 +++++++++++++++++++++++++++++- src/common/eventmanager.h | 8 +++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/common/eventmanager.cpp b/src/common/eventmanager.cpp index 552765a2..96648646 100644 --- a/src/common/eventmanager.cpp +++ b/src/common/eventmanager.cpp @@ -20,6 +20,8 @@ #include "eventmanager.h" +#include +#include #include #include "event.h" @@ -28,6 +30,11 @@ EventManager::EventManager(QObject *parent) : QObject(parent) { } +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"); @@ -107,10 +114,31 @@ void EventManager::registerEventHandler(QList events, QObject *object // 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; - dispatchEvent(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) { + //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 diff --git a/src/common/eventmanager.h b/src/common/eventmanager.h index 73ff8b7e..698b3746 100644 --- a/src/common/eventmanager.h +++ b/src/common/eventmanager.h @@ -101,7 +101,7 @@ public: }; EventManager(QObject *parent = 0); - //virtual ~EventManager(); + virtual ~EventManager(); EventType eventTypeByName(const QString &name) const; EventType eventGroupByName(const QString &name) const; @@ -120,6 +120,9 @@ public slots: */ void sendEvent(Event *event); +protected: + virtual void customEvent(QEvent *event); + private: struct Handler { QObject *object; @@ -141,6 +144,7 @@ private: //! Add handlers to an existing sorted (by priority) handler list void insertHandlers(const QList &newHandlers, QList &existing); + void processEvents(); void dispatchEvent(Event *event); //! @return the EventType enum @@ -148,6 +152,8 @@ private: HandlerHash _registeredHandlers; mutable QMetaEnum _enum; + + QList _eventQueue; }; Q_DECLARE_OPERATORS_FOR_FLAGS(EventManager::EventFlags); -- 2.20.1