++API, ++EventFlags
authorManuel Nickschas <sputnick@quassel-irc.org>
Thu, 23 Sep 2010 08:59:49 +0000 (10:59 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 13 Oct 2010 23:06:31 +0000 (01:06 +0200)
src/common/event.h
src/common/eventmanager.cpp
src/common/eventmanager.h

index a0e82d7..9fd6373 100644 (file)
@@ -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;
 };
 
 /*******/
index c5f01b6..2a20b21 100644 (file)
@@ -21,7 +21,6 @@
 #include "eventmanager.h"
 
 #include <QDebug>
-#include <QMetaEnum>
 
 #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<EventType>(val);
+}
+
+EventManager::EventType EventManager::eventGroupByName(const QString &name) const {
+  EventType type = eventTypeByName(name);
+  return type == Invalid? Invalid : static_cast<EventType>(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;
index 54d2721..d7480d1 100644 (file)
 #ifndef EVENTMANAGER_H
 #define EVENTMANAGER_H
 
-#include <QHash>
-#include <QObject>
+#include <QMetaEnum>
 
 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