From a912b14c755137ed5529854027b9ab3f7e06c5e9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sat, 18 Aug 2012 13:05:16 +0200 Subject: Add automatic metatype registration for invokable methods. This works similarly to the automatic registration for Q_PROPERTY types, but in this case it mostly affects the need for users to call qRegisterMetaType() before using queued connections with methods using non-built-in metatypes, or before using invokeMethod manually. Change-Id: Ib17d0606b77b0130624b6a88b57c36d26e97d12d Reviewed-by: Kent Hansen --- tests/auto/tools/moc/tst_moc.cpp | 234 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) (limited to 'tests/auto/tools') diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index c6178c7c2e..795a8307f3 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -550,6 +550,7 @@ private slots: void explicitOverrideControl_data(); void explicitOverrideControl(); void autoPropertyMetaTypeRegistration(); + void autoMethodArgumentMetaTypeRegistration(); signals: void sigWithUnsignedArg(unsigned foo); @@ -2332,6 +2333,68 @@ struct NamespacedNonQObject {}; } Q_DECLARE_METATYPE(SomeNamespace::NamespacedNonQObject) +// Need different types for the invokable method tests because otherwise the registration +// done in the property test would interfere. + +class CustomQObject2 : public QObject +{ + Q_OBJECT + Q_ENUMS(Number) +public: + enum Number { + Zero, + One, + Two + }; + explicit CustomQObject2(QObject *parent = 0) + : QObject(parent) + { + } +}; + +Q_DECLARE_METATYPE(CustomQObject2::Number) + +typedef CustomQObject2* CustomQObject2Star; +Q_DECLARE_METATYPE(CustomQObject2Star); + +namespace SomeNamespace2 { + +class NamespacedQObject2 : public QObject +{ + Q_OBJECT +public: + explicit NamespacedQObject2(QObject *parent = 0) + : QObject(parent) + { + + } +}; + +struct NamespacedNonQObject2 {}; +} +Q_DECLARE_METATYPE(SomeNamespace2::NamespacedNonQObject2) + + +struct CustomObject3 {}; +struct CustomObject4 {}; +struct CustomObject5 {}; +struct CustomObject6 {}; +struct CustomObject7 {}; +struct CustomObject8 {}; +struct CustomObject9 {}; +struct CustomObject10 {}; +struct CustomObject11 {}; + +Q_DECLARE_METATYPE(CustomObject3) +Q_DECLARE_METATYPE(CustomObject4) +Q_DECLARE_METATYPE(CustomObject5) +Q_DECLARE_METATYPE(CustomObject6) +Q_DECLARE_METATYPE(CustomObject7) +Q_DECLARE_METATYPE(CustomObject8) +Q_DECLARE_METATYPE(CustomObject9) +Q_DECLARE_METATYPE(CustomObject10) +Q_DECLARE_METATYPE(CustomObject11) + class AutoRegistrationObject : public QObject { Q_OBJECT @@ -2424,6 +2487,29 @@ public: { return SomeNamespace::NamespacedNonQObject(); } + +public slots: + void objectSlot(QObject*) {} + void customObjectSlot(CustomQObject2*) {} + void sharedPointerSlot(QSharedPointer) {} + void weakPointerSlot(QWeakPointer) {} + void trackingPointerSlot(QPointer) {} + void listIntSlot(QList) {} + void vectorVariantSlot(QVector) {} + void listCustomObjectSlot(QList) {} + void vectorListIntSlot(QVector >) {} + void vectorListCustomObjectSlot(QVector >) {} + void enumSlot(CustomQObject2::Number) {} + void typedefSlot(CustomQObject2Star) {} + void namespacedQObjectSlot(SomeNamespace2::NamespacedQObject2*) {} + void namespacedNonQObjectSlot(SomeNamespace2::NamespacedNonQObject2) {} + + void bu1(int, CustomObject3) {} + void bu2(CustomObject4, int) {} + void bu3(CustomObject5, CustomObject6) {} + void bu4(CustomObject7, int, CustomObject8) {} + void bu5(int, CustomObject9, CustomObject10) {} + void bu6(int, CustomObject11, int) {} }; void tst_Moc::autoPropertyMetaTypeRegistration() @@ -2465,6 +2551,154 @@ void tst_Moc::autoPropertyMetaTypeRegistration() QCOMPARE(propertyMetaTypeIds, expectedMetaTypeIds); } +template +struct DefaultConstructor +{ + static inline T construct() { return T(); } +}; + +template +struct DefaultConstructor +{ + static inline T* construct() { return 0; } +}; + +void tst_Moc::autoMethodArgumentMetaTypeRegistration() +{ + AutoRegistrationObject aro; + + QVector methodArgMetaTypeIds; + + const QMetaObject *metaObject = aro.metaObject(); + + int i = metaObject->methodOffset(); // Start after QObject built-in slots; + +#define TYPE_LOOP(TYPE) \ + { \ + const QMetaMethod method = metaObject->method(i); \ + for (int j = 0; j < method.parameterCount(); ++j) \ + methodArgMetaTypeIds.append(method.parameterType(j)); \ + QVERIFY(method.invoke(&aro, Q_ARG(TYPE, DefaultConstructor::construct()))); \ + ++i; \ + } + +#define FOR_EACH_SLOT_ARG_TYPE(F) \ + F(QObject*) \ + F(CustomQObject2*) \ + F(QSharedPointer) \ + F(QWeakPointer) \ + F(QPointer) \ + F(QList) \ + F(QVector) \ + F(QList) \ + F(QVector >) \ + F(QVector >) \ + F(CustomQObject2::Number) \ + F(CustomQObject2Star) \ + F(SomeNamespace2::NamespacedQObject2*) \ + F(SomeNamespace2::NamespacedNonQObject2) + + // Note: mulit-arg slots are tested below. + + FOR_EACH_SLOT_ARG_TYPE(TYPE_LOOP) + +#undef TYPE_LOOP +#undef FOR_EACH_SLOT_ARG_TYPE + + QVector expectedMetaTypeIds = QVector() + << QMetaType::QObjectStar + << qMetaTypeId() + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId >() + << qMetaTypeId > >() + << qMetaTypeId > >() + << qMetaTypeId() + << qMetaTypeId() + << qMetaTypeId() + << qMetaTypeId() + ; + + QCOMPARE(methodArgMetaTypeIds, expectedMetaTypeIds); + + + QVector methodMultiArgMetaTypeIds; + + { + const QMetaMethod method = metaObject->method(i); + QCOMPARE(method.name(), QByteArray("bu1")); + for (int j = 0; j < method.parameterCount(); ++j) + methodMultiArgMetaTypeIds.append(method.parameterType(j)); + QVERIFY(method.invoke(&aro, Q_ARG(int, 42), Q_ARG(CustomObject3, CustomObject3()))); + ++i; + } + { + const QMetaMethod method = metaObject->method(i); + QCOMPARE(method.name(), QByteArray("bu2")); + for (int j = 0; j < method.parameterCount(); ++j) + methodMultiArgMetaTypeIds.append(method.parameterType(j)); + QVERIFY(method.invoke(&aro, Q_ARG(CustomObject4, CustomObject4()), Q_ARG(int, 42))); + ++i; + } + { + const QMetaMethod method = metaObject->method(i); + QCOMPARE(method.name(), QByteArray("bu3")); + for (int j = 0; j < method.parameterCount(); ++j) + methodMultiArgMetaTypeIds.append(method.parameterType(j)); + QVERIFY(method.invoke(&aro, Q_ARG(CustomObject5, CustomObject5()), Q_ARG(CustomObject6, CustomObject6()))); + ++i; + } + { + const QMetaMethod method = metaObject->method(i); + QCOMPARE(method.name(), QByteArray("bu4")); + for (int j = 0; j < method.parameterCount(); ++j) + methodMultiArgMetaTypeIds.append(method.parameterType(j)); + QVERIFY(method.invoke(&aro, Q_ARG(CustomObject7, CustomObject7()), Q_ARG(int, 42), Q_ARG(CustomObject8, CustomObject8()))); + ++i; + } + { + const QMetaMethod method = metaObject->method(i); + QCOMPARE(method.name(), QByteArray("bu5")); + for (int j = 0; j < method.parameterCount(); ++j) + methodMultiArgMetaTypeIds.append(method.parameterType(j)); + QVERIFY(method.invoke(&aro, Q_ARG(int, 42), Q_ARG(CustomObject9, CustomObject9()), Q_ARG(CustomObject10, CustomObject10()))); + ++i; + } + { + const QMetaMethod method = metaObject->method(i); + QCOMPARE(method.name(), QByteArray("bu6")); + for (int j = 0; j < method.parameterCount(); ++j) + methodMultiArgMetaTypeIds.append(method.parameterType(j)); + QVERIFY(method.invoke(&aro, Q_ARG(int, 42), Q_ARG(CustomObject11, CustomObject11()), Q_ARG(int, 42))); + ++i; + } + + QVector expectedMultiMetaTypeIds = QVector() + << QMetaType::Int + << qMetaTypeId() + << qMetaTypeId() + << QMetaType::Int + << qMetaTypeId() + << qMetaTypeId() + << qMetaTypeId() + << QMetaType::Int + << qMetaTypeId() + << QMetaType::Int + << qMetaTypeId() + << qMetaTypeId() + << QMetaType::Int + << qMetaTypeId() + << QMetaType::Int + ; + + QCOMPARE(methodMultiArgMetaTypeIds, expectedMultiMetaTypeIds); + + +} + QTEST_MAIN(tst_Moc) #include "tst_moc.moc" -- cgit v1.2.3