Add convenience macro for fast connects in declarative.
authorMichael Brasser <michael.brasser@nokia.com>
Thu, 22 Sep 2011 03:14:00 +0000 (13:14 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 27 Sep 2011 04:16:46 +0000 (06:16 +0200)
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 <qt_sanity_bot@ovi.com>
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
src/declarative/items/qsgborderimage.cpp
src/declarative/items/qsgborderimage_p_p.h
src/declarative/items/qsgflickable.cpp
src/declarative/items/qsgitem.cpp
src/declarative/items/qsgpathview.cpp
src/declarative/qml/qdeclarativeglobal_p.h
src/declarative/util/qdeclarativeanimation.cpp
src/declarative/util/qdeclarativebehavior.cpp
tests/auto/declarative/qdeclarativecpputils/qdeclarativecpputils.pro [new file with mode: 0644]
tests/auto/declarative/qdeclarativecpputils/tst_qdeclarativecpputils.cpp [new file with mode: 0644]

index 30b1032..fb407d7 100644 (file)
@@ -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 {
 
index 69e02cd..2781669 100644 (file)
@@ -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;
     }
index 13cb966..91a93b6 100644 (file)
@@ -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);
index a1e4317..76a1f1b 100644 (file)
@@ -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;
index 10161e5..6f54d46 100644 (file)
@@ -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)
index 87be79f..cc0a4b6 100644 (file)
@@ -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
index 6cdba7c..e642f11 100644 (file)
@@ -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)
index 550b8a3..3038d3a 100644 (file)
@@ -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 (file)
index 0000000..aa7ca09
--- /dev/null
@@ -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 (file)
index 0000000..d72e6d3
--- /dev/null
@@ -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 <qtest.h>
+#include <qsignalspy.h>
+#include <private/qdeclarativeglobal_p.h>
+
+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"