Automatically register method types in QSignalSpy.

Change-Id: I3655291dca6dbd3d8d09ee835b85983caa911b64
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
This commit is contained in:
Stephen Kelly 2013-01-03 01:22:47 +01:00 committed by The Qt Project
parent 6769e0783a
commit 21d607c81a
2 changed files with 51 additions and 2 deletions

View File

@ -97,7 +97,7 @@ public:
return; return;
} }
sig = ba; sig = ba;
initArgs(mo->method(sigIndex)); initArgs(mo->method(sigIndex), obj);
} }
inline bool isValid() const { return !sig.isEmpty(); } inline bool isValid() const { return !sig.isEmpty(); }
@ -130,11 +130,24 @@ public:
private: private:
void initArgs(const QMetaMethod &member) void initArgs(const QMetaMethod &member)
{
initArgs(member, 0);
}
void initArgs(const QMetaMethod &member, const QObject *obj)
{ {
const QList<QByteArray> params = member.parameterTypes(); const QList<QByteArray> params = member.parameterTypes();
args.reserve(params.size()); args.reserve(params.size());
for (int i = 0; i < params.count(); ++i) { for (int i = 0; i < params.count(); ++i) {
const int tp = QMetaType::type(params.at(i).constData()); int tp = QMetaType::type(params.at(i).constData());
if (tp == QMetaType::UnknownType && obj) {
void *argv[] = { &tp, &i };
QMetaObject::metacall(const_cast<QObject*>(obj),
QMetaObject::RegisterMethodArgumentMetaType,
member.methodIndex(), argv);
if (tp == -1)
tp = QMetaType::UnknownType;
}
if (tp == QMetaType::UnknownType) { if (tp == QMetaType::UnknownType) {
Q_ASSERT(tp != QMetaType::Void); // void parameter => metaobject is corrupt Q_ASSERT(tp != QMetaType::Void); // void parameter => metaobject is corrupt
qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.", qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.",

View File

@ -553,6 +553,7 @@ private slots:
void explicitOverrideControl(); void explicitOverrideControl();
void autoPropertyMetaTypeRegistration(); void autoPropertyMetaTypeRegistration();
void autoMethodArgumentMetaTypeRegistration(); void autoMethodArgumentMetaTypeRegistration();
void autoSignalSpyMetaTypeRegistration();
void parseDefines(); void parseDefines();
void preprocessorOnly(); void preprocessorOnly();
@ -2388,6 +2389,7 @@ struct CustomObject8 {};
struct CustomObject9 {}; struct CustomObject9 {};
struct CustomObject10 {}; struct CustomObject10 {};
struct CustomObject11 {}; struct CustomObject11 {};
struct CustomObject12 {};
Q_DECLARE_METATYPE(CustomObject3) Q_DECLARE_METATYPE(CustomObject3)
Q_DECLARE_METATYPE(CustomObject4) Q_DECLARE_METATYPE(CustomObject4)
@ -2398,6 +2400,7 @@ Q_DECLARE_METATYPE(CustomObject8)
Q_DECLARE_METATYPE(CustomObject9) Q_DECLARE_METATYPE(CustomObject9)
Q_DECLARE_METATYPE(CustomObject10) Q_DECLARE_METATYPE(CustomObject10)
Q_DECLARE_METATYPE(CustomObject11) Q_DECLARE_METATYPE(CustomObject11)
Q_DECLARE_METATYPE(CustomObject12)
class AutoRegistrationObject : public QObject class AutoRegistrationObject : public QObject
{ {
@ -2520,6 +2523,9 @@ public slots:
void ref2(QList<int>&) {} void ref2(QList<int>&) {}
void ref3(CustomQObject2&) {} void ref3(CustomQObject2&) {}
void ref4(QSharedPointer<CustomQObject2>&) {} void ref4(QSharedPointer<CustomQObject2>&) {}
signals:
void someSignal(CustomObject12);
}; };
void tst_Moc::autoPropertyMetaTypeRegistration() void tst_Moc::autoPropertyMetaTypeRegistration()
@ -2583,6 +2589,16 @@ void tst_Moc::autoMethodArgumentMetaTypeRegistration()
int i = metaObject->methodOffset(); // Start after QObject built-in slots; int i = metaObject->methodOffset(); // Start after QObject built-in slots;
while (i < metaObject->methodCount()) {
// Skip over signals so we start at the first slot.
const QMetaMethod method = metaObject->method(i);
if (method.methodType() == QMetaMethod::Signal)
++i;
else
break;
}
#define TYPE_LOOP(TYPE) \ #define TYPE_LOOP(TYPE) \
{ \ { \
const QMetaMethod method = metaObject->method(i); \ const QMetaMethod method = metaObject->method(i); \
@ -2709,6 +2725,26 @@ void tst_Moc::autoMethodArgumentMetaTypeRegistration()
} }
void tst_Moc::autoSignalSpyMetaTypeRegistration()
{
AutoRegistrationObject aro;
QVector<int> methodArgMetaTypeIds;
const QMetaObject *metaObject = aro.metaObject();
int i = metaObject->indexOfSignal(QMetaObject::normalizedSignature("someSignal(CustomObject12)"));
QVERIFY(i > 0);
QCOMPARE(QMetaType::type("CustomObject12"), (int)QMetaType::UnknownType);
QSignalSpy spy(&aro, SIGNAL(someSignal(CustomObject12)));
QVERIFY(QMetaType::type("CustomObject12") != QMetaType::UnknownType);
QCOMPARE(QMetaType::type("CustomObject12"), qMetaTypeId<CustomObject12>());
}
void tst_Moc::parseDefines() void tst_Moc::parseDefines()
{ {
const QMetaObject *mo = &PD_NAMESPACE::PD_CLASSNAME::staticMetaObject; const QMetaObject *mo = &PD_NAMESPACE::PD_CLASSNAME::staticMetaObject;