From ffeadf7a7c09971fab09ed08b1f3f503c6facb7e Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 22 Sep 2011 13:14:00 +1000 Subject: [PATCH] Add convenience macro for fast connects in declarative. We already follow this pattern several places, so this commit creates a convenience macro for it, and replaces previous usage where appropriate. Also adds the macro several places as further optimization. Change-Id: Ieff5ed6cc51c34d0a1c8aa42ac40314ea243477a Reviewed-on: http://codereview.qt-project.org/5342 Reviewed-by: Qt Sanity Bot Reviewed-by: Aaron Kennedy --- src/declarative/items/qsgborderimage.cpp | 13 +-- src/declarative/items/qsgborderimage_p_p.h | 8 +- src/declarative/items/qsgflickable.cpp | 16 +--- src/declarative/items/qsgitem.cpp | 4 +- src/declarative/items/qsgpathview.cpp | 11 +-- src/declarative/qml/qdeclarativeglobal_p.h | 26 +++++ src/declarative/util/qdeclarativeanimation.cpp | 3 +- src/declarative/util/qdeclarativebehavior.cpp | 8 +- .../qdeclarativecpputils/qdeclarativecpputils.pro | 9 ++ .../tst_qdeclarativecpputils.cpp | 106 +++++++++++++++++++++ 10 files changed, 154 insertions(+), 50 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativecpputils/qdeclarativecpputils.pro create mode 100644 tests/auto/declarative/qdeclarativecpputils/tst_qdeclarativecpputils.cpp diff --git a/src/declarative/items/qsgborderimage.cpp b/src/declarative/items/qsgborderimage.cpp index 30b1032..fb407d7 100644 --- a/src/declarative/items/qsgborderimage.cpp +++ b/src/declarative/items/qsgborderimage.cpp @@ -314,18 +314,7 @@ void QSGBorderImage::load() } else { QNetworkRequest req(d->url); d->sciReply = qmlEngine(this)->networkAccessManager()->get(req); - - static int sciReplyFinished = -1; - static int thisSciRequestFinished = -1; - if (sciReplyFinished == -1) { - sciReplyFinished = - QNetworkReply::staticMetaObject.indexOfSignal("finished()"); - thisSciRequestFinished = - QSGBorderImage::staticMetaObject.indexOfSlot("sciRequestFinished()"); - } - - QMetaObject::connect(d->sciReply, sciReplyFinished, this, - thisSciRequestFinished, Qt::DirectConnection); + FAST_CONNECT(d->sciReply, SIGNAL(finished()), this, SLOT(sciRequestFinished())) } } else { diff --git a/src/declarative/items/qsgborderimage_p_p.h b/src/declarative/items/qsgborderimage_p_p.h index 69e02cd..2781669 100644 --- a/src/declarative/items/qsgborderimage_p_p.h +++ b/src/declarative/items/qsgborderimage_p_p.h @@ -83,13 +83,7 @@ public: Q_Q(QSGBorderImage); if (!border) { border = new QSGScaleGrid(q); - static int borderChangedSignalIdx = -1; - static int doUpdateSlotIdx = -1; - if (borderChangedSignalIdx < 0) - borderChangedSignalIdx = QSGScaleGrid::staticMetaObject.indexOfSignal("borderChanged()"); - if (doUpdateSlotIdx < 0) - doUpdateSlotIdx = QSGBorderImage::staticMetaObject.indexOfSlot("doUpdate()"); - QMetaObject::connect(border, borderChangedSignalIdx, q, doUpdateSlotIdx); + FAST_CONNECT(border, SIGNAL(borderChanged()), q, SLOT(doUpdate())) } return border; } diff --git a/src/declarative/items/qsgflickable.cpp b/src/declarative/items/qsgflickable.cpp index 13cb966..91a93b6 100644 --- a/src/declarative/items/qsgflickable.cpp +++ b/src/declarative/items/qsgflickable.cpp @@ -190,20 +190,8 @@ void QSGFlickablePrivate::init() Q_Q(QSGFlickable); QDeclarative_setParent_noEvent(contentItem, q); contentItem->setParentItem(q); - static int timelineUpdatedIdx = -1; - static int timelineCompletedIdx = -1; - static int flickableTickedIdx = -1; - static int flickableMovementEndingIdx = -1; - if (timelineUpdatedIdx == -1) { - timelineUpdatedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("updated()"); - timelineCompletedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("completed()"); - flickableTickedIdx = QSGFlickable::staticMetaObject.indexOfSlot("ticked()"); - flickableMovementEndingIdx = QSGFlickable::staticMetaObject.indexOfSlot("movementEnding()"); - } - QMetaObject::connect(&timeline, timelineUpdatedIdx, - q, flickableTickedIdx, Qt::DirectConnection); - QMetaObject::connect(&timeline, timelineCompletedIdx, - q, flickableMovementEndingIdx, Qt::DirectConnection); + FAST_CONNECT(&timeline, SIGNAL(updated()), q, SLOT(ticked())) + FAST_CONNECT(&timeline, SIGNAL(completed()), q, SLOT(movementEnding())) q->setAcceptedMouseButtons(Qt::LeftButton); q->setFiltersChildMouseEvents(true); QSGItemPrivate *viewportPrivate = QSGItemPrivate::get(contentItem); diff --git a/src/declarative/items/qsgitem.cpp b/src/declarative/items/qsgitem.cpp index a1e4317..76a1f1b 100644 --- a/src/declarative/items/qsgitem.cpp +++ b/src/declarative/items/qsgitem.cpp @@ -3244,8 +3244,8 @@ QDeclarativeStateGroup *QSGItemPrivate::_states() _stateGroup = new QDeclarativeStateGroup; if (!componentComplete) _stateGroup->classBegin(); - QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)), - q, SIGNAL(stateChanged(QString))); + FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)), + q, SIGNAL(stateChanged(QString))) } return _stateGroup; diff --git a/src/declarative/items/qsgpathview.cpp b/src/declarative/items/qsgpathview.cpp index 10161e5..6f54d46 100644 --- a/src/declarative/items/qsgpathview.cpp +++ b/src/declarative/items/qsgpathview.cpp @@ -101,16 +101,9 @@ void QSGPathViewPrivate::init() q->setAcceptedMouseButtons(Qt::LeftButton); q->setFlag(QSGItem::ItemIsFocusScope); q->setFiltersChildMouseEvents(true); - q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked())); + FAST_CONNECT(&tl, SIGNAL(updated()), q, SLOT(ticked())) lastPosTime.invalidate(); - static int timelineCompletedIdx = -1; - static int movementEndingIdx = -1; - if (timelineCompletedIdx == -1) { - timelineCompletedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("completed()"); - movementEndingIdx = QSGPathView::staticMetaObject.indexOfSlot("movementEnding()"); - } - QMetaObject::connect(&tl, timelineCompletedIdx, - q, movementEndingIdx, Qt::DirectConnection); + FAST_CONNECT(&tl, SIGNAL(completed()), q, SLOT(movementEnding())) } QSGItem *QSGPathViewPrivate::getItem(int modelIndex, bool onPath) diff --git a/src/declarative/qml/qdeclarativeglobal_p.h b/src/declarative/qml/qdeclarativeglobal_p.h index 87be79f..cc0a4b6 100644 --- a/src/declarative/qml/qdeclarativeglobal_p.h +++ b/src/declarative/qml/qdeclarativeglobal_p.h @@ -64,6 +64,32 @@ QT_MODULE(Declarative) return status == Yes; \ } +#define FAST_CONNECT(Sender, Signal, Receiver, Method) \ +{ \ + QObject *sender = (Sender); \ + QObject *receiver = (Receiver); \ + const char *signal = (Signal); \ + const char *method = (Method); \ + static int signalIdx = -1; \ + static int methodIdx = -1; \ + if (signalIdx < 0) { \ + if (((int)(*signal) - '0') == QSIGNAL_CODE) \ + signalIdx = sender->metaObject()->indexOfSignal(signal+1); \ + else \ + qWarning("FAST_CONNECT: Invalid signal %s. Please make sure you are using the SIGNAL macro.", signal); \ + } \ + if (methodIdx < 0) { \ + int code = ((int)(*method) - '0'); \ + if (code == QSLOT_CODE) \ + methodIdx = receiver->metaObject()->indexOfSlot(method+1); \ + else if (code == QSIGNAL_CODE) \ + methodIdx = receiver->metaObject()->indexOfSignal(method+1); \ + else \ + qWarning("FAST_CONNECT: Invalid method %s. Please make sure you are using the SIGNAL or SLOT macro.", method); \ + } \ + QMetaObject::connect(sender, signalIdx, receiver, methodIdx, Qt::DirectConnection); \ +} + #ifdef Q_OS_SYMBIAN #define Q_DECLARATIVE_PRIVATE_EXPORT Q_AUTOTEST_EXPORT #else diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 6cdba7c..e642f11 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -215,8 +215,7 @@ void QDeclarativeAbstractAnimation::setRunning(bool r) } if (!d->connectedTimeLine) { - QObject::connect(qtAnimation(), SIGNAL(finished()), - this, SLOT(timelineComplete())); + FAST_CONNECT(qtAnimation(), SIGNAL(finished()), this, SLOT(timelineComplete())) d->connectedTimeLine = true; } if (!supressStart) diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp index 550b8a3..3038d3a 100644 --- a/src/declarative/util/qdeclarativebehavior.cpp +++ b/src/declarative/util/qdeclarativebehavior.cpp @@ -132,10 +132,10 @@ void QDeclarativeBehavior::setAnimation(QDeclarativeAbstractAnimation *animation if (d->animation) { d->animation->setDefaultTarget(d->property); d->animation->setDisableUserControl(); - connect(d->animation->qtAnimation(), - SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)), - this, - SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + FAST_CONNECT(d->animation->qtAnimation(), + SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)), + this, + SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State))) } } diff --git a/tests/auto/declarative/qdeclarativecpputils/qdeclarativecpputils.pro b/tests/auto/declarative/qdeclarativecpputils/qdeclarativecpputils.pro new file mode 100644 index 0000000..aa7ca09 --- /dev/null +++ b/tests/auto/declarative/qdeclarativecpputils/qdeclarativecpputils.pro @@ -0,0 +1,9 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativecpputils.cpp + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private diff --git a/tests/auto/declarative/qdeclarativecpputils/tst_qdeclarativecpputils.cpp b/tests/auto/declarative/qdeclarativecpputils/tst_qdeclarativecpputils.cpp new file mode 100644 index 0000000..d72e6d3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativecpputils/tst_qdeclarativecpputils.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +class tst_qdeclarativecpputils : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativecpputils() {} + +private slots: + void fastConnect(); +}; + +class MyObject : public QObject { + Q_OBJECT +public: + MyObject() : slotCount(0) {} + friend class tst_qdeclarativecpputils; + + int slotCount; + +signals: + void signal1(); + void signal2(); + +public slots: + void slot1() { slotCount++; } +}; + +void tst_qdeclarativecpputils::fastConnect() +{ + { + MyObject *obj = new MyObject; + FAST_CONNECT(obj, SIGNAL(signal1()), obj, SLOT(slot1())); + + obj->signal1(); + QCOMPARE(obj->slotCount, 1); + + delete obj; + } + + { + MyObject obj; + FAST_CONNECT(&obj, SIGNAL(signal1()), &obj, SLOT(slot1())) + + obj.signal1(); + QCOMPARE(obj.slotCount, 1); + } + + { + MyObject *obj = new MyObject; + QSignalSpy spy(obj, SIGNAL(signal2())); + FAST_CONNECT(obj, SIGNAL(signal1()), obj, SIGNAL(signal2())); + + obj->signal1(); + QCOMPARE(spy.count(), 1); + + delete obj; + } +} + +QTEST_MAIN(tst_qdeclarativecpputils) + +#include "tst_qdeclarativecpputils.moc" -- 2.7.4