aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlglobal_p.h
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2012-05-11 12:01:41 +0100
committerQt by Nokia <qt-info@nokia.com>2012-05-24 12:52:43 +0200
commitd2e557c2c2d7fcf3bf7c1676df3902e115986dc2 (patch)
tree65f47e443efa9635a2634880c01dc439817f9566 /src/qml/qml/qqmlglobal_p.h
parent0a3ff88f851771e52d119fab90c0254de6950585 (diff)
Lazily create QMetaObjects
For internal QML built types, creating a metaobject each time is just wasteful. Additionally, as the property caches were always created from the intermediate QMetaObject, it was difficult to pass information directly from the compiler to the property cache. Change-Id: I769526b0edaaf16a86883f3065b75618b94e4077 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/qml/qml/qqmlglobal_p.h')
-rw-r--r--src/qml/qml/qqmlglobal_p.h96
1 files changed, 85 insertions, 11 deletions
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 6e233c9fae..3ed7286ed9 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -44,6 +44,7 @@
#include <private/qtqmlglobal_p.h>
#include <QtCore/QObject>
+#include <private/qqmlpropertycache_p.h>
QT_BEGIN_HEADER
@@ -63,32 +64,105 @@ QT_BEGIN_NAMESPACE
return status == Yes; \
}
-#define FAST_CONNECT(Sender, Signal, Receiver, Method) \
+/*!
+ Connect \a Signal of \a Sender to \a Method of \a Receiver. \a Signal must be
+ of type \a SenderType and \a Receiver of type \a ReceiverType.
+
+ Unlike QObject::connect(), this method caches the lookup of the signal and method
+ indexes. It also does not require lazy QMetaObjects to be built so should be
+ preferred in all QML code that might interact with QML built objects.
+
+ \code
+ QQuickTextControl *control;
+ QQuickTextEdit *textEdit;
+ qmlobject_connect(control, QQuickTextControl, SIGNAL(updateRequest(QRectF)),
+ textEdit, QQuickTextEdit, SLOT(updateDocument()));
+ \endcode
+*/
+#define qmlobject_connect(Sender, SenderType, Signal, Receiver, ReceiverType, Method) \
{ \
- QObject *sender = (Sender); \
- QObject *receiver = (Receiver); \
+ SenderType *sender = (Sender); \
+ ReceiverType *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); \
+ Q_ASSERT(((int)(*signal) - '0') == QSIGNAL_CODE); \
+ signalIdx = SenderType::staticMetaObject.indexOfSignal(signal+1); \
} \
if (methodIdx < 0) { \
int code = ((int)(*method) - '0'); \
+ Q_ASSERT(code == QSLOT_CODE || code == QSIGNAL_CODE); \
if (code == QSLOT_CODE) \
- methodIdx = receiver->metaObject()->indexOfSlot(method+1); \
- else if (code == QSIGNAL_CODE) \
- methodIdx = receiver->metaObject()->indexOfSignal(method+1); \
+ methodIdx = ReceiverType::staticMetaObject.indexOfSlot(method+1); \
else \
- qWarning("FAST_CONNECT: Invalid method %s. Please make sure you are using the SIGNAL or SLOT macro.", method); \
+ methodIdx = ReceiverType::staticMetaObject.indexOfSignal(method+1); \
} \
+ Q_ASSERT(signalIdx != -1 && methodIdx != -1); \
QMetaObject::connect(sender, signalIdx, receiver, methodIdx, Qt::DirectConnection); \
}
+/*!
+ Disconnect \a Signal of \a Sender from \a Method of \a Receiver. \a Signal must be
+ of type \a SenderType and \a Receiver of type \a ReceiverType.
+
+ Unlike QObject::disconnect(), this method caches the lookup of the signal and method
+ indexes. It also does not require lazy QMetaObjects to be built so should be
+ preferred in all QML code that might interact with QML built objects.
+
+ \code
+ QQuickTextControl *control;
+ QQuickTextEdit *textEdit;
+ qmlobject_disconnect(control, QQuickTextControl, SIGNAL(updateRequest(QRectF)),
+ textEdit, QQuickTextEdit, SLOT(updateDocument()));
+ \endcode
+*/
+#define qmlobject_disconnect(Sender, SenderType, Signal, Receiver, ReceiverType, Method) \
+{ \
+ SenderType *sender = (Sender); \
+ ReceiverType *receiver = (Receiver); \
+ const char *signal = (Signal); \
+ const char *method = (Method); \
+ static int signalIdx = -1; \
+ static int methodIdx = -1; \
+ if (signalIdx < 0) { \
+ Q_ASSERT(((int)(*signal) - '0') == QSIGNAL_CODE); \
+ signalIdx = SenderType::staticMetaObject.indexOfSignal(signal+1); \
+ } \
+ if (methodIdx < 0) { \
+ int code = ((int)(*method) - '0'); \
+ Q_ASSERT(code == QSLOT_CODE || code == QSIGNAL_CODE); \
+ if (code == QSLOT_CODE) \
+ methodIdx = ReceiverType::staticMetaObject.indexOfSlot(method+1); \
+ else \
+ methodIdx = ReceiverType::staticMetaObject.indexOfSignal(method+1); \
+ } \
+ Q_ASSERT(signalIdx != -1 && methodIdx != -1); \
+ QMetaObject::disconnect(sender, signalIdx, receiver, methodIdx); \
+}
+
+/*!
+ This method is identical to qobject_cast<T>() except that it does not require lazy
+ QMetaObjects to be built, so should be preferred in all QML code that might interact
+ with QML built objects.
+
+ \code
+ QObject *object;
+ if (QQuickTextEdit *textEdit = qmlobject_cast<QQuickTextEdit *>(object)) {
+ // ...Do something...
+ }
+ \endcode
+*/
+template<class T>
+T qmlobject_cast(QObject *object)
+{
+ if (QQmlMetaObject::canConvert(object, &reinterpret_cast<T>(object)->staticMetaObject))
+ return static_cast<T>(object);
+ else
+ return 0;
+}
+
bool Q_QML_PRIVATE_EXPORT QQml_isSignalConnected(QObject*, int, int);
#define IS_SIGNAL_CONNECTED(Sender, Signal) \