X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Feventmanager.cpp;h=2709b557fd338d718ee866af6fd59824f3b857fb;hp=3fe581cf1252a18afb4a4b2489838b8f1f78afda;hb=88b350153eb364853e75d237d3eed2dfaf839d59;hpb=393ac8b4bca9db98f297cb4756ef2e79364bf6f0 diff --git a/src/common/eventmanager.cpp b/src/common/eventmanager.cpp index 3fe581cf..2709b557 100644 --- a/src/common/eventmanager.cpp +++ b/src/common/eventmanager.cpp @@ -27,13 +27,21 @@ #include "event.h" #include "ircevent.h" -EventManager::EventManager(QObject *parent) : QObject(parent) { - -} - -EventManager::~EventManager() { - // pending events won't be delivered anymore, but we do need to delete them - qDeleteAll(_eventQueue); +// ============================================================ +// QueuedEvent +// ============================================================ +class QueuedQuasselEvent : public QEvent { +public: + QueuedQuasselEvent(Event *event) + : QEvent(QEvent::User), event(event) {} + Event *event; +}; + +// ============================================================ +// EventManager +// ============================================================ +EventManager::EventManager(QObject *parent) + : QObject(parent) { } QMetaEnum EventManager::eventEnum() const { @@ -157,31 +165,35 @@ 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; - _eventQueue.append(event); - if(_eventQueue.count() == 1) // we're not currently processing another event - processEvents(); +void EventManager::postEvent(Event *event) { + if(sender() && sender()->thread() != this->thread()) { + QueuedQuasselEvent *queuedEvent = new QueuedQuasselEvent(event); + QCoreApplication::postEvent(this, queuedEvent); + } else { + if(_eventQueue.isEmpty()) + // we're currently not processing events + processEvent(event); + else + _eventQueue.append(event); + } } void EventManager::customEvent(QEvent *event) { if(event->type() == QEvent::User) { - processEvents(); + QueuedQuasselEvent *queuedEvent = static_cast(event); + processEvent(queuedEvent->event); 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)); - else - emit eventQueueEmptied(); +void EventManager::processEvent(Event *event) { + Q_ASSERT(_eventQueue.isEmpty()); + dispatchEvent(event); + // dispatching the event might cause new events to be generated. we process those afterwards. + while(!_eventQueue.isEmpty()) { + dispatchEvent(_eventQueue.first()); + _eventQueue.removeFirst(); + } } void EventManager::dispatchEvent(Event *event) {