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 QList<Handler> handlers; QHash<QObject *, Handler> filters; QSet<QObject *> ignored; uint type = event->type(); bool checkDupes = false; // special handling for numeric IrcEvents if ((type & ~IrcEventNumericMask) == IrcEventNumeric) { ::IrcEventNumeric *numEvent = static_cast< ::IrcEventNumeric *>(event); if (!numEvent) qWarning() << "Invalid event type for IrcEventNumeric!"; else { int num = numEvent->number(); if (num > 0) { insertHandlers(registeredHandlers().value(type + num), handlers, false); insertFilters(registeredFilters().value(type + num), filters); checkDupes = true; } } } // exact type insertHandlers(registeredHandlers().value(type), handlers, checkDupes); insertFilters(registeredFilters().value(type), filters); // check if we have a generic handler for the event group if ((type & EventGroupMask) != type) { insertHandlers(registeredHandlers().value(type & EventGroupMask), handlers, true); insertFilters(registeredFilters().value(type & EventGroupMask), filters); } // now dispatch the event QList<Handler>::const_iterator it; for (it = handlers.begin(); it != handlers.end() && !event->isStopped(); ++it) { QObject *obj = it->object; if (ignored.contains(obj)) // object has filtered the event continue; if (filters.contains(obj)) { // we have a filter, so let's check if we want to deliver the event Handler filter = filters.value(obj); bool result = false; void *param[] = { Q_RETURN_ARG(bool, result).data(), Q_ARG(Event *, event).data() }; obj->qt_metacall(QMetaObject::InvokeMetaMethod, filter.methodIndex, param); if (!result) { ignored.insert(obj); continue; // mmmh, event filter told us to not accept } }
void EventManager::registerEventHandler(QList<EventType> events, QObject *object, const char *slot, Priority priority, bool isFilter) { int methodIndex = object->metaObject()->indexOfMethod(slot); if(methodIndex < 0) { qWarning() << Q_FUNC_INFO << QString("Slot %1 not found in object %2").arg(slot).arg(object->objectName()); return; } Handler handler(object, methodIndex, priority); foreach(EventType event, events) { if(isFilter) { registeredFilters()[event].append(handler); qDebug() << "Registered event filter for" << event << "in" << object; } else { registeredHandlers()[event].append(handler); qDebug() << "Registered event handler for" << event << "in" << object; } } }
void EventManager::registerObject(QObject *object, Priority priority, const QString &methodPrefix, const QString &filterPrefix) { for(int i = object->metaObject()->methodOffset(); i < object->metaObject()->methodCount(); i++) { QString methodSignature(object->metaObject()->method(i).signature()); int eventType = findEventType(methodSignature, methodPrefix); if(eventType > 0) { Handler handler(object, i, priority); registeredHandlers()[eventType].append(handler); //qDebug() << "Registered event handler for" << methodSignature << "in" << object; } eventType = findEventType(methodSignature, filterPrefix); if(eventType > 0) { Handler handler(object, i, priority); registeredFilters()[eventType].append(handler); //qDebug() << "Registered event filterer for" << methodSignature << "in" << object; } } }