Introducing the first shiny stuff for our new event-based core backend
authorManuel Nickschas <sputnick@quassel-irc.org>
Sun, 5 Sep 2010 18:15:45 +0000 (20:15 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 13 Oct 2010 23:06:31 +0000 (01:06 +0200)
This adds a (very rudimentary) base class for events, and a (very rudimentary)
EventManager. The manager so far allows registering event handlers (even via explicit
methods, or by providing a QObject. In the latter case, matching slots will be automatically
registered (i.e. a method handleIrcEventJoin() will be registered as handler for
IrcEventJoin).

src/common/CMakeLists.txt
src/common/event.cpp [new file with mode: 0644]
src/common/event.h [new file with mode: 0644]
src/common/eventmanager.cpp [new file with mode: 0644]
src/common/eventmanager.h [new file with mode: 0644]

index 9298b77..b27a2f1 100644 (file)
@@ -12,6 +12,8 @@ set(SOURCES
     bufferviewconfig.cpp
     bufferviewmanager.cpp
     cliparser.cpp
     bufferviewconfig.cpp
     bufferviewmanager.cpp
     cliparser.cpp
+    event.cpp
+    eventmanager.cpp
     identity.cpp
     ignorelistmanager.cpp
     ircchannel.cpp
     identity.cpp
     ignorelistmanager.cpp
     ircchannel.cpp
@@ -35,6 +37,7 @@ set(MOC_HDRS
     bufferviewconfig.h
     bufferviewmanager.h
     coreinfo.h
     bufferviewconfig.h
     bufferviewmanager.h
     coreinfo.h
+    eventmanager.h
     identity.h
     ignorelistmanager.h
     ircchannel.h
     identity.h
     ignorelistmanager.h
     ircchannel.h
@@ -50,6 +53,7 @@ set(HEADERS ${MOC_HDRS}
     abstractcliparser.h
     bufferinfo.h
     cliparser.h
     abstractcliparser.h
     bufferinfo.h
     cliparser.h
+    event.h
     logger.h
     message.h
     types.h
     logger.h
     message.h
     types.h
diff --git a/src/common/event.cpp b/src/common/event.cpp
new file mode 100644 (file)
index 0000000..826af7c
--- /dev/null
@@ -0,0 +1,21 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2010 by the Quassel Project                        *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "event.h"
diff --git a/src/common/event.h b/src/common/event.h
new file mode 100644 (file)
index 0000000..ed82f7e
--- /dev/null
@@ -0,0 +1,36 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2010 by the Quassel Project                        *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef EVENT_H
+#define EVENT_H
+
+#include <QStringList>
+
+class Event {
+
+public:
+  Event();
+  virtual ~Event();
+
+  virtual QStringList params() const;
+
+};
+
+#endif
diff --git a/src/common/eventmanager.cpp b/src/common/eventmanager.cpp
new file mode 100644 (file)
index 0000000..a8ddd67
--- /dev/null
@@ -0,0 +1,74 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2010 by the Quassel Project                        *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "eventmanager.h"
+
+#include <QDebug>
+#include <QMetaEnum>
+
+EventManager::EventManager(QObject *parent) : QObject(parent) {
+
+}
+
+void EventManager::registerObject(QObject *object, RegistrationMode mode, const QString &methodPrefix) {
+  int eventEnumIndex = metaObject()->indexOfEnumerator("EventType");
+  Q_ASSERT(eventEnumIndex >= 0);
+  QMetaEnum eventEnum = metaObject()->enumerator(eventEnumIndex);
+
+  for(int i = object->metaObject()->methodOffset(); i < object->metaObject()->methodCount(); i++) {
+    QString methodSignature(object->metaObject()->method(i).signature());
+
+    if(!methodSignature.startsWith(methodPrefix))
+      continue;
+
+    methodSignature = methodSignature.section('(',0,0);  // chop the attribute list
+    methodSignature = methodSignature.mid(methodPrefix.length()); // strip prefix
+
+    int eventType = eventEnum.keyToValue(methodSignature.toAscii());
+    if(eventType < 0) {
+      qWarning() << Q_FUNC_INFO << QString("Could not find EventType %1").arg(methodSignature);
+      continue;
+    }
+    Handler handler(object, i);
+    mode == Prepend ? registeredHandlers()[static_cast<EventType>(eventType)].prepend(handler)
+                    : registeredHandlers()[static_cast<EventType>(eventType)].append(handler);
+
+    qDebug() << "Registered event handler for" << methodSignature << "in" << object;
+  }
+}
+
+void EventManager::registerEventHandler(EventType event, QObject *object, const char *slot, RegistrationMode mode) {
+  registerEventHandler(QList<EventType>() << event, object, slot, mode);
+}
+
+void EventManager::registerEventHandler(QList<EventType> events, QObject *object, const char *slot, RegistrationMode mode) {
+  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);
+  foreach(EventType event, events) {
+    mode == Prepend ? registeredHandlers()[event].prepend(handler)
+                    : registeredHandlers()[event].append(handler);
+
+    qDebug() << "Registered event handler for" << event << "in" << object;
+  }
+}
diff --git a/src/common/eventmanager.h b/src/common/eventmanager.h
new file mode 100644 (file)
index 0000000..78a72ac
--- /dev/null
@@ -0,0 +1,107 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2010 by the Quassel Project                        *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef EVENTMANAGER_H
+#define EVENTMANAGER_H
+
+#include <QHash>
+#include <QObject>
+
+class Event;
+
+class EventManager : public QObject {
+  Q_OBJECT
+  Q_ENUMS(EventType)
+
+public:
+
+  enum RegistrationMode {
+    Prepend,
+    Append
+  };
+
+  /*
+
+  */
+  enum EventType {
+    Invalid                     = 0xffffffff,
+    GenericEvent                  = 0x000000,
+
+    IrcServerEvent                = 0x010000,
+    IrcServerLooking              = 0x010001,
+    IrcServerConnecting           = 0x010002,
+    IrcServerConnected            = 0x010003,
+    IrcServerConnectionFailure    = 0x010004,
+    IrcServerDisconnected         = 0x010005,
+    IrcServerQuit                 = 0x010006,
+
+    IrcServerIncoming             = 0x010007,
+
+    IrcEvent                      = 0x020000,
+    IrcEventCap                   = 0x020001,
+    IrcEventCapAuthenticate       = 0x020002,
+    IrcEventInvite                = 0x020003,
+    IrcEventJoin                  = 0x020004,
+    IrcEventKick                  = 0x020005,
+    IrcEventMode                  = 0x020006,
+    IrcEventNick                  = 0x020007,
+    IrcEventNotice                = 0x020008,
+    IrcEventPart                  = 0x020009,
+    IrcEventPing                  = 0x02000a,
+    IrcEventPong                  = 0x02000b,
+    IrcEventPrivmsg               = 0x02000c,
+    IrcEventQuit                  = 0x02000d,
+    IrcEventTopic                 = 0x02000e,
+
+    IrcEventNumeric               = 0x021000 /* needs 1000 (0x03e8) consecutive free values! */
+  };
+
+  EventManager(QObject *parent = 0);
+  //virtual ~EventManager();
+
+  QStringList providesEnums();
+
+public slots:
+  void registerObject(QObject *object, RegistrationMode mode = Append, const QString &methodPrefix = "handle");
+  void registerEventHandler(EventType event, QObject *object, const char *slot, RegistrationMode mode = Append);
+  void registerEventHandler(QList<EventType> events, QObject *object, const char *slot, RegistrationMode mode = Append);
+
+  //void sendEvent(Event *event);
+
+private:
+  struct Handler {
+    QObject *object;
+    int methodIndex;
+
+    explicit Handler(QObject *obj = 0, int method = 0) {
+      object = obj;
+      methodIndex = method;
+    }
+  };
+
+  typedef QHash<EventType, QList<Handler> > HandlerHash;
+
+  inline const HandlerHash &registeredHandlers() const { return _registeredHandlers; }
+  inline HandlerHash &registeredHandlers() { return _registeredHandlers; }
+  HandlerHash _registeredHandlers;
+
+};
+
+#endif