/** * @file Common/eventqueue.cpp * @brief Event queue interface implementation * @author Enar Vaikene * * Copyright (c) 2011 Enar Vaikene * * This file is part of the eVaf C++ cross-platform application development framework. * * This file can be used under the terms of the GNU General Public License * version 3.0 as published by the Free Software Foundation and appearing in * the file LICENSE included in the packaging of this file. Please review the * the following information to ensure the GNU General Public License version * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. * * Alternatively, this file may be used in accordance with the Commercial License * Agreement provided with the Software. */ #include "eventqueue.h" #include "event.h" #include "globals.h" #include "iregistry.h" #include "version.h" #include //------------------------------------------------------------------- using namespace eVaf::Common; iEventQueue * iEventQueue::instance() { static Internal::EventQueue singleton; return &singleton; } //------------------------------------------------------------------- using namespace eVaf::Common::Internal; EventQueue::EventQueue() : iEventQueue() , mNextEventId(1) { iRegistry::instance()->registerInterface("iEventQueue", this); } EventQueue::~EventQueue() { } bool EventQueue::event(QEvent * e) { // Is it an eVaf event? if (e->type() == Event::eVafEvent) { Event * event = static_cast(e); uint id = event->id(); // Verify that this event is registered QHash::const_iterator eventsIt = mEvents.constFind(id); if (eventsIt == mEvents.constEnd()) { return true; // We don't know it, but it is an eVaf event and we should handle it } // Send the event to all the subscribers QHash > >::const_iterator subscribersIt = mSubscribers.constFind(id); if (subscribersIt != mSubscribers.constEnd()) { QVector > subscribers = *subscribersIt; int sz = subscribers.size(); for (int i = 0; i < sz; ++i) { // Get the subscriber object and make sure that it is still alive QWeakPointer obj = subscribers.at(i); if (obj.isNull()) { continue; } // Notify the subscriber bool rval = QCoreApplication::sendEvent(obj.data(), e); if (rval) { // The event was consumed and should be sent to any other subscribers break; } } } return true; } else return iEventQueue::event(e); } uint EventQueue::registerEvent(QString const & name) { uint id = queryEvent(name); if (id == 0) { mEvents.insert(mNextEventId, name); id = mNextEventId++; } return id; } uint EventQueue::queryEvent(QString const & name) const { return mEvents.key(name, 0); } void EventQueue::unregisterEvent(uint id) { mEvents.remove(id); mSubscribers.remove(id); } uint EventQueue::subscribeEvent(uint id, QObject * obj) { if (id == 0) return 0; // Only registered events please if (mEvents.constFind(id) == mEvents.constEnd()) { return 0; } // Check for duplicates if (mSubscribers[id].indexOf(obj) != -1) return id; mSubscribers[id].append(obj); return id; } void EventQueue::unsubscribeEvent(uint id, QObject * obj) { if (id == 0) return; // Is the event registered? if (mEvents.constFind(id) == mEvents.constEnd()) return; // Remove from the list of subscribers QVector >::iterator it = mSubscribers[id].begin(); QVector >::iterator e = mSubscribers[id].end(); while (it != e) { if (!it->isNull() && it->data() == obj) it = mSubscribers[id].erase(it); else ++it; } } void EventQueue::broadcastEvent(Event * event) { QCoreApplication::postEvent(this, event); }