From f9fc50a5e043668a2525a6c0903ea339d4ba05b7 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Sun, 13 Jan 2008 18:42:37 +0000 Subject: [PATCH 1/1] - Improved the speed of IrcServerHandler (and other BasicHandler derivatives). Command Dispatching no longer uses the slow invokeMethod() - fixed the Name of some enums to make quassel compile again... --- src/core/basichandler.cpp | 71 ++++++++++++++++++++---------- src/core/basichandler.h | 20 +++++---- src/qtui/mainwin.cpp | 4 +- src/uisupport/bufferview.cpp | 2 +- src/uisupport/bufferviewfilter.cpp | 4 +- 5 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/core/basichandler.cpp b/src/core/basichandler.cpp index 8ddfc0be..732c7976 100644 --- a/src/core/basichandler.cpp +++ b/src/core/basichandler.cpp @@ -25,8 +25,10 @@ BasicHandler::BasicHandler(NetworkConnection *parent) : QObject(parent), - server(parent) { - + server(parent), + defaultHandler(-1), + initDone(false) +{ connect(this, SIGNAL(displayMsg(Message::Type, QString, QString, QString, quint8)), server, SIGNAL(displayMsg(Message::Type, QString, QString, QString, quint8))); @@ -37,36 +39,57 @@ BasicHandler::BasicHandler(NetworkConnection *parent) server, SLOT(putRawLine(QString))); } -QStringList BasicHandler::providesHandlers() const { - QStringList handlers; - for(int i=0; i < metaObject()->methodCount(); i++) { - QString methodSignature(metaObject()->method(i).signature()); - if(!methodSignature.startsWith("handle")) - continue; +QStringList BasicHandler::providesHandlers() { + return handlerHash().keys(); +} - methodSignature = methodSignature.section('(',0,0); // chop the attribute list - methodSignature = methodSignature.mid(6); // strip "handle" - handlers << methodSignature; +const QHash &BasicHandler::handlerHash() { + if(!initDone) { + for(int i = metaObject()->methodOffset(); i < metaObject()->methodCount(); i++) { + QString methodSignature(metaObject()->method(i).signature()); + if(methodSignature.startsWith("defaultHandler")) { + defaultHandler = i; + continue; + } + + if(!methodSignature.startsWith("handle")) + continue; + + methodSignature = methodSignature.section('(',0,0); // chop the attribute list + methodSignature = methodSignature.mid(6); // strip "handle" + _handlerHash[methodSignature] = i; + } + initDone = true; } - return handlers; + return _handlerHash; } - -void BasicHandler::handle(const QString &member, const QGenericArgument &val0, - const QGenericArgument &val1, const QGenericArgument &val2, - const QGenericArgument &val3, const QGenericArgument &val4, - const QGenericArgument &val5, const QGenericArgument &val6, - const QGenericArgument &val7, const QGenericArgument &val8) { - +void BasicHandler::handle(const QString &member, QGenericArgument val0, + QGenericArgument val1, QGenericArgument val2, + QGenericArgument val3, QGenericArgument val4, + QGenericArgument val5, QGenericArgument val6, + QGenericArgument val7, QGenericArgument val8) { // Now we try to find a handler for this message. BTW, I do love the Trolltech guys ;-) + // and now we even have a fast lookup! Thanks thiago! + QString handler = member.toLower(); handler[0] = handler[0].toUpper(); - handler = "handle" + handler; - if(!QMetaObject::invokeMethod(this, handler.toAscii(), val0, val1, val2, val3, val4, val5, val6, val7, val8)) - // Ok. Default handler it is. - QMetaObject::invokeMethod(this, "defaultHandler", Q_ARG(QString, member), val0, val1, val2, val3, val4, val5, val6, val7, val8); - + if(!handlerHash().contains(handler)) { + if(defaultHandler == -1) { + qWarning() << QString("No such Handler: %1::handle%2").arg(metaObject()->className(), handler); + return; + } else { + void *param[] = {0, Q_ARG(QString, member).data(), val0.data(), val1.data(), val2.data(), val3.data(), val4.data(), + val5.data(), val6.data(), val7.data(), val8.data(), val8.data()}; + qt_metacall(QMetaObject::InvokeMetaMethod, defaultHandler, param); + return; + } + } + + void *param[] = {0, val0.data(), val1.data(), val2.data(), val3.data(), val4.data(), + val5.data(), val6.data(), val7.data(), val8.data(), val8.data(), 0}; + qt_metacall(QMetaObject::InvokeMetaMethod, handlerHash()[handler], param); } // ==================== diff --git a/src/core/basichandler.h b/src/core/basichandler.h index 6ae8d2e0..a3cc5a89 100644 --- a/src/core/basichandler.h +++ b/src/core/basichandler.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "message.h" @@ -37,7 +38,7 @@ class BasicHandler : public QObject { public: BasicHandler(NetworkConnection *parent = 0); - QStringList providesHandlers() const; + QStringList providesHandlers(); signals: void displayMsg(Message::Type, QString target, QString text, QString sender = "", quint8 flags = Message::None); @@ -45,17 +46,20 @@ signals: void putRawLine(QString msg); protected: - virtual void handle(const QString &member, const QGenericArgument &val0 = QGenericArgument(0), - const QGenericArgument &val1 = QGenericArgument(), const QGenericArgument &val2 = QGenericArgument(), - const QGenericArgument &val3 = QGenericArgument(), const QGenericArgument &val4 = QGenericArgument(), - const QGenericArgument &val5 = QGenericArgument(), const QGenericArgument &val6 = QGenericArgument(), - const QGenericArgument &val7 = QGenericArgument(), const QGenericArgument &val8 = QGenericArgument()); + virtual void handle(const QString &member, QGenericArgument val0 = QGenericArgument(0), + QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), + QGenericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), + QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), + QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument()); NetworkConnection *server; - -protected: Network *network() const; +private: + const QHash &handlerHash(); + QHash _handlerHash; + int defaultHandler; + bool initDone; }; #endif diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index 1ad31414..6c63404f 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -127,12 +127,12 @@ void MainWin::init() { // attach the BufferWidget to the PropertyMapper - Client::bufferModel()->mapProperty(0, NetworkModel::BufferUidRole, ui.bufferWidget, "currentBuffer"); + Client::bufferModel()->mapProperty(0, NetworkModel::BufferIdRole, ui.bufferWidget, "currentBuffer"); connect(Client::networkModel(), SIGNAL(bufferAboutToBeRemoved(BufferId)), ui.bufferWidget, SLOT(removeBuffer(BufferId))); // attach the NickList to the PropertyMapper - Client::bufferModel()->mapProperty(0, NetworkModel::BufferUidRole, nickListWidget, "currentBuffer"); + Client::bufferModel()->mapProperty(0, NetworkModel::BufferIdRole, nickListWidget, "currentBuffer"); #ifdef SPUTDEV diff --git a/src/uisupport/bufferview.cpp b/src/uisupport/bufferview.cpp index 5374338f..14b27ec8 100644 --- a/src/uisupport/bufferview.cpp +++ b/src/uisupport/bufferview.cpp @@ -87,7 +87,7 @@ void BufferView::joinChannel(const QModelIndex &index) { if(bufferType != BufferItem::ChannelType) return; - Client::fakeInput(index.data(NetworkModel::BufferUidRole).toUInt(), QString("/JOIN %1").arg(index.sibling(index.row(), 0).data().toString())); + Client::fakeInput(index.data(NetworkModel::BufferIdRole).toUInt(), QString("/JOIN %1").arg(index.sibling(index.row(), 0).data().toString())); } void BufferView::keyPressEvent(QKeyEvent *event) { diff --git a/src/uisupport/bufferviewfilter.cpp b/src/uisupport/bufferviewfilter.cpp index 139ca894..cf3d4685 100644 --- a/src/uisupport/bufferviewfilter.cpp +++ b/src/uisupport/bufferviewfilter.cpp @@ -95,7 +95,7 @@ void BufferViewFilter::removeBuffer(const QModelIndex &index) { bool lastBuffer = (rowCount(index.parent()) == 1); uint netId = index.data(NetworkModel::NetworkIdRole).toUInt(); - uint bufferuid = index.data(NetworkModel::BufferUidRole).toUInt(); + uint bufferuid = index.data(NetworkModel::BufferIdRole).toUInt(); if(buffers.contains(bufferuid)) { buffers.remove(bufferuid); @@ -128,7 +128,7 @@ bool BufferViewFilter::filterAcceptBuffer(const QModelIndex &source_bufferIndex) // return false; if((mode & FullCustom)) { - uint bufferuid = source_bufferIndex.data(NetworkModel::BufferUidRole).toUInt(); + uint bufferuid = source_bufferIndex.data(NetworkModel::BufferIdRole).toUInt(); return buffers.contains(bufferuid); } -- 2.20.1