X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Feventmanager.cpp;h=ff206ddcfb3c9a9cddb78b95dfae5e767ce0f255;hp=fd3cf9bdbc655a44e5e8bd2b8fed03eb40570b84;hb=9cb22a9cccbdf2bd71568ec3989d41ca167326da;hpb=d9588ab4fff449eeb77ebb03a6cb1c5c91d1449d diff --git a/src/common/eventmanager.cpp b/src/common/eventmanager.cpp index fd3cf9bd..ff206ddc 100644 --- a/src/common/eventmanager.cpp +++ b/src/common/eventmanager.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2010 by the Quassel Project * + * Copyright (C) 2005-2013 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -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,29 +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)); +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) {