diff options
author | Stephen Kelly <stephen.kelly@kdab.com> | 2012-08-18 13:05:16 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-28 18:30:39 +0200 |
commit | a912b14c755137ed5529854027b9ab3f7e06c5e9 (patch) | |
tree | 8593866f1a795d6a3168473e75a56bcb74c920cb /src/tools | |
parent | 62c2061a501563e7f2929c5883f01955af0f2fc1 (diff) |
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<T>() before using queued connections
with methods using non-built-in metatypes, or before using invokeMethod
manually.
Change-Id: Ib17d0606b77b0130624b6a88b57c36d26e97d12d
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/moc/generator.cpp | 52 | ||||
-rw-r--r-- | src/tools/moc/generator.h | 1 |
2 files changed, 52 insertions, 1 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index edf2bf8889..b7175f9bc9 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -869,6 +869,16 @@ void Generator::generateMetacall() fprintf(out, " if (_id < %d)\n", methodList.size()); fprintf(out, " qt_static_metacall(this, _c, _id, _a);\n"); fprintf(out, " _id -= %d;\n }", methodList.size()); + + fprintf(out, " else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {\n"); + fprintf(out, " if (_id < %d)\n", methodList.size()); + + if (methodsWithAutomaticTypesHelper(methodList).isEmpty()) + fprintf(out, " *reinterpret_cast<int*>(_a[0]) = -1;\n"); + else + fprintf(out, " qt_static_metacall(this, _c, _id, _a);\n"); + fprintf(out, " _id -= %d;\n }", methodList.size()); + } if (cdef->propertyList.size()) { @@ -1106,6 +1116,20 @@ QMultiMap<QByteArray, int> Generator::automaticPropertyMetaTypesHelper() return automaticPropertyMetaTypes; } +QMap<int, QMultiMap<QByteArray, int> > Generator::methodsWithAutomaticTypesHelper(const QList<FunctionDef> &methodList) +{ + QMap<int, QMultiMap<QByteArray, int> > methodsWithAutomaticTypes; + for (int i = 0; i < methodList.size(); ++i) { + const FunctionDef &f = methodList.at(i); + for (int j = 0; j < f.arguments.count(); ++j) { + const QByteArray argType = f.arguments.at(j).normalizedType; + if (registerableMetaType(argType) && !isBuiltinType(argType)) + methodsWithAutomaticTypes[i].insert(argType, j); + } + } + return methodsWithAutomaticTypes; +} + void Generator::generateStaticMetacall() { fprintf(out, "void %s::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)\n{\n", @@ -1197,6 +1221,32 @@ void Generator::generateStaticMetacall() fprintf(out, " }\n"); fprintf(out, " }"); needElse = true; + + QMap<int, QMultiMap<QByteArray, int> > methodsWithAutomaticTypes = methodsWithAutomaticTypesHelper(methodList); + + if (!methodsWithAutomaticTypes.isEmpty()) { + fprintf(out, " else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {\n"); + fprintf(out, " switch (_id) {\n"); + fprintf(out, " default: *reinterpret_cast<int*>(_a[0]) = -1; break;\n"); + QMap<int, QMultiMap<QByteArray, int> >::const_iterator it = methodsWithAutomaticTypes.constBegin(); + const QMap<int, QMultiMap<QByteArray, int> >::const_iterator end = methodsWithAutomaticTypes.constEnd(); + for ( ; it != end; ++it) { + fprintf(out, " case %d:\n", it.key()); + fprintf(out, " switch (*reinterpret_cast<int*>(_a[1])) {\n"); + fprintf(out, " default: *reinterpret_cast<int*>(_a[0]) = -1; break;\n"); + foreach (const QByteArray &key, it->uniqueKeys()) { + foreach (int argumentID, it->values(key)) + fprintf(out, " case %d:\n", argumentID); + fprintf(out, " *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< %s >(); break;\n", key.constData()); + } + fprintf(out, " }\n"); + fprintf(out, " break;\n"); + } + fprintf(out, " }\n"); + fprintf(out, " }"); + isUsed_a = true; + } + } if (!cdef->signalList.isEmpty()) { Q_ASSERT(needElse); // if there is signal, there was method. @@ -1265,7 +1315,7 @@ void Generator::generateStaticMetacall() if (methodList.isEmpty()) { fprintf(out, " Q_UNUSED(_o);\n"); - if (cdef->constructorList.isEmpty() && automaticPropertyMetaTypes.isEmpty()) { + if (cdef->constructorList.isEmpty() && automaticPropertyMetaTypes.isEmpty() && methodsWithAutomaticTypesHelper(methodList).isEmpty()) { fprintf(out, " Q_UNUSED(_id);\n"); fprintf(out, " Q_UNUSED(_c);\n"); } diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h index 873681ab88..4fa4d3440c 100644 --- a/src/tools/moc/generator.h +++ b/src/tools/moc/generator.h @@ -72,6 +72,7 @@ private: void generateSignal(FunctionDef *def, int index); void generatePluginMetaData(); QMultiMap<QByteArray, int> automaticPropertyMetaTypesHelper(); + QMap<int, QMultiMap<QByteArray, int> > methodsWithAutomaticTypesHelper(const QList<FunctionDef> &methodList); void strreg(const QByteArray &); // registers a string int stridx(const QByteArray &); // returns a string's id |