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 --- src/tools/moc/generator.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++- src/tools/moc/generator.h | 1 + 2 files changed, 52 insertions(+), 1 deletion(-) (limited to 'src/tools') 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(_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 Generator::automaticPropertyMetaTypesHelper() return automaticPropertyMetaTypes; } +QMap > Generator::methodsWithAutomaticTypesHelper(const QList &methodList) +{ + QMap > 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 > methodsWithAutomaticTypes = methodsWithAutomaticTypesHelper(methodList); + + if (!methodsWithAutomaticTypes.isEmpty()) { + fprintf(out, " else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {\n"); + fprintf(out, " switch (_id) {\n"); + fprintf(out, " default: *reinterpret_cast(_a[0]) = -1; break;\n"); + QMap >::const_iterator it = methodsWithAutomaticTypes.constBegin(); + const QMap >::const_iterator end = methodsWithAutomaticTypes.constEnd(); + for ( ; it != end; ++it) { + fprintf(out, " case %d:\n", it.key()); + fprintf(out, " switch (*reinterpret_cast(_a[1])) {\n"); + fprintf(out, " default: *reinterpret_cast(_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(_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 automaticPropertyMetaTypesHelper(); + QMap > methodsWithAutomaticTypesHelper(const QList &methodList); void strreg(const QByteArray &); // registers a string int stridx(const QByteArray &); // returns a string's id -- cgit v1.2.3