From cd78f70e75d797cb6217b32fceebdfb6022fbe83 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Thu, 23 Sep 2010 10:59:49 +0200 Subject: [PATCH] ++API, ++EventFlags --- src/common/event.h | 13 ++++++++++++ src/common/eventmanager.cpp | 41 +++++++++++++++++++++++++++++++------ src/common/eventmanager.h | 25 ++++++++++++++++++---- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/common/event.h b/src/common/event.h index a0e82d70..9fd6373f 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -31,8 +31,21 @@ public: inline EventManager::EventType type() const { return _type; } + inline void setFlag(EventManager::EventFlag flag) { _flags |= flag; } + inline void setFlags(EventManager::EventFlags flags) { _flags = flags; } + + inline EventManager::EventFlags flags() const { return _flags; } + + inline void stop() { setFlag(EventManager::Stopped); } + inline bool isStopped() { return _flags.testFlag(EventManager::Stopped); } + + inline void setData(const QVariant &data) { _data = data; } + inline QVariant data() const { return _data; } + private: EventManager::EventType _type; + EventManager::EventFlags _flags; + QVariant _data; }; /*******/ diff --git a/src/common/eventmanager.cpp b/src/common/eventmanager.cpp index c5f01b63..2a20b214 100644 --- a/src/common/eventmanager.cpp +++ b/src/common/eventmanager.cpp @@ -21,7 +21,6 @@ #include "eventmanager.h" #include -#include #include "event.h" @@ -29,11 +28,41 @@ EventManager::EventManager(QObject *parent) : QObject(parent) { } -void EventManager::registerObject(QObject *object, Priority priority, const QString &methodPrefix) { - int eventEnumIndex = metaObject()->indexOfEnumerator("EventType"); - Q_ASSERT(eventEnumIndex >= 0); - QMetaEnum eventEnum = metaObject()->enumerator(eventEnumIndex); +QMetaEnum EventManager::eventEnum() const { + if(!_enum.isValid()) { + int eventEnumIndex = metaObject()->indexOfEnumerator("EventType"); + Q_ASSERT(eventEnumIndex >= 0); + _enum = metaObject()->enumerator(eventEnumIndex); + Q_ASSERT(_enum.isValid()); + } + return _enum; +} +EventManager::EventType EventManager::eventTypeByName(const QString &name) const { + int val = eventEnum().keyToValue(name.toLatin1()); + return (val == -1) ? Invalid : static_cast(val); +} + +EventManager::EventType EventManager::eventGroupByName(const QString &name) const { + EventType type = eventTypeByName(name); + return type == Invalid? Invalid : static_cast(type & EventGroupMask); +} + +/* NOTE: + Registering and calling handlers works fine even if they specify a subclass of Event as their parameter. + However, this most probably is a result from a reinterpret_cast somewhere deep inside Qt, so there is *no* + type safety. If the event sent is of the wrong class type, you'll get a neat segfault! + Thus, we need to make sure that events are of the correct class type when sending! + + We might add a registration-time check later, which will require matching the enum base name (e.g. "IrcEvent") with + the type the handler claims to support. This still won't protect us from someone sending an IrcEvent object + with an enum type "NetworkIncoming", for example. + + Another way would be to add a check into the various Event subclasses, such that the ctor matches the given event type + with the actual class. Possibly (optionally) using rtti... +*/ + +void EventManager::registerObject(QObject *object, Priority priority, const QString &methodPrefix) { for(int i = object->metaObject()->methodOffset(); i < object->metaObject()->methodCount(); i++) { QString methodSignature(object->metaObject()->method(i).signature()); @@ -43,7 +72,7 @@ void EventManager::registerObject(QObject *object, Priority priority, const QStr methodSignature = methodSignature.section('(',0,0); // chop the attribute list methodSignature = methodSignature.mid(methodPrefix.length()); // strip prefix - int eventType = eventEnum.keyToValue(methodSignature.toAscii()); + int eventType = eventEnum().keyToValue(methodSignature.toAscii()); if(eventType < 0) { qWarning() << Q_FUNC_INFO << QString("Could not find EventType %1").arg(methodSignature); continue; diff --git a/src/common/eventmanager.h b/src/common/eventmanager.h index 54d27214..d7480d1c 100644 --- a/src/common/eventmanager.h +++ b/src/common/eventmanager.h @@ -21,13 +21,13 @@ #ifndef EVENTMANAGER_H #define EVENTMANAGER_H -#include -#include +#include class Event; class EventManager : public QObject { Q_OBJECT + Q_FLAGS(EventFlag EventFlags) Q_ENUMS(EventType) public: @@ -45,6 +45,12 @@ public: HighestPriority }; + enum EventFlag { + Backlog = 0x40, + Stopped = 0x80 + }; + Q_DECLARE_FLAGS(EventFlags, EventFlag) + /* */ @@ -85,14 +91,20 @@ public: IrcEventPrivmsg, IrcEventQuit, IrcEventTopic, + IrcEventRawPrivmsg, ///< Undecoded privmsg (still needs CTCP parsing) + IrcEventRawNotice, ///< Undecoded notice (still needs CTCP parsing) + IrcEventUnknown, ///< Unknown non-numeric cmd IrcEventNumeric = 0x00031000, /* needs 1000 (0x03e8) consecutive free values! */ + + MessageEvent = 0x00040000, ///< Stringified event suitable for converting to Message }; EventManager(QObject *parent = 0); //virtual ~EventManager(); - QStringList providesEnums(); + EventType eventTypeByName(const QString &name) const; + EventType eventGroupByName(const QString &name) const; public slots: void registerObject(QObject *object, Priority priority = NormalPriority, const QString &methodPrefix = "handle"); @@ -130,8 +142,13 @@ private: void dispatchEvent(Event *event); - HandlerHash _registeredHandlers; + //! @return the EventType enum + QMetaEnum eventEnum() const; + HandlerHash _registeredHandlers; + mutable QMetaEnum _enum; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(EventManager::EventFlags); + #endif -- 2.20.1