From 4de6dc4a93b470cf9f000bae24a57ef1661b2519 Mon Sep 17 00:00:00 2001 From: Yonggang Luo Date: Sat, 30 Jul 2022 04:59:55 +0800 Subject: [PATCH] QMetaMethod: Add QMetaMethod::from(&MyClass:myFunction) support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add QMetaMethod::from QMetaMethod::fromInvokable QMetaMethod::fromSlot Task-number: QTBUG-36861 Signed-off-by: Yonggang Luo --- src/corelib/kernel/qmetaobject.h | 44 ++++++++++++++++++++++++++++---- src/tools/moc/generator.cpp | 8 +++--- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 0740acef60a0..bfd30dd32b4d 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -138,14 +138,48 @@ class Q_CORE_EXPORT QMetaMethod template static inline QMetaMethod fromSignal(PointerToMemberFunction signal) { - typedef QtPrivate::FunctionPointer SignalType; - static_assert(QtPrivate::HasQ_OBJECT_Macro::Value, - "No Q_OBJECT in the class with the signal"); - return fromSignalImpl(&SignalType::Object::staticMetaObject, - reinterpret_cast(&signal)); + QMetaMethod method = from(signal); + if (method.methodType() == Signal) + { + return method; + } + return QMetaMethod(); + } + + template + static inline QMetaMethod fromSlot(PointerToMemberFunction slot) + { + QMetaMethod method = from(slot); + if (method.methodType() == Slot) + { + return method; + } + return QMetaMethod(); + } + + template + static inline QMetaMethod fromInvokable(PointerToMemberFunction invokable) + { + QMetaMethod method = from(invokable); + if (method.methodType() == Method) + { + return method; + } + return QMetaMethod(); + } + + template + static inline QMetaMethod from(PointerToMemberFunction func) + { + typedef QtPrivate::FunctionPointer ClassType; + static_assert(QtPrivate::HasQ_OBJECT_Macro::Value, + "No Q_OBJECT in the class with the func"); + return fromSignalImpl(&ClassType::Object::staticMetaObject, + reinterpret_cast(&func)); } private: + // ### Qt 7: rename fromSignalImpl to fromImpl static QMetaMethod fromSignalImpl(const QMetaObject *, void **); static QMetaMethod fromRelativeMethodIndex(const QMetaObject *mobj, int index); static QMetaMethod fromRelativeConstructorIndex(const QMetaObject *mobj, int index); diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 0e8ba0bb7279..807ba3a85d98 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1157,13 +1157,13 @@ void Generator::generateStaticMetacall() } } - if (!cdef->signalList.isEmpty()) { - Q_ASSERT(needElse); // if there is signal, there was method. + if (!methodList.isEmpty()) { + Q_ASSERT(needElse); // there was method. fprintf(out, " else if (_c == QMetaObject::IndexOfMethod) {\n"); fprintf(out, " int *result = reinterpret_cast(_a[0]);\n"); bool anythingUsed = false; - for (int methodindex = 0; methodindex < cdef->signalList.size(); ++methodindex) { - const FunctionDef &f = cdef->signalList.at(methodindex); + for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) { + const FunctionDef &f = methodList.at(methodindex); if (f.wasCloned || !f.inPrivateClass.isEmpty() || f.isStatic) continue; anythingUsed = true;