From 268006ee2f7c5f736ed3d16cdf126fdb28a9dc3b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 27 Aug 2024 10:11:06 -0700 Subject: [PATCH] QArgumentType: store a QMetaType instead of an id This would avoid an indirection through the QMetaType constructor. But I'm also making it so effectively we either have valid QMetaTypes or we don't. If it can be looked up in the constructor, then string comparisons aren't necessary at all. Change-Id: I9a3b2a1a781c27c7271afffd3e5acbca06632476 Reviewed-by: Ulf Hermann --- src/corelib/kernel/qmetaobject.cpp | 9 +++++---- src/corelib/kernel/qmetaobject_p.h | 26 ++++++++++++-------------- src/corelib/kernel/qobject.cpp | 7 +++++-- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 83f670d9a50..e2e3c9b8083 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -646,10 +646,11 @@ bool QMetaObjectPrivate::methodMatch(const QMetaObject *m, const QMetaMethod &me int paramsIndex = data.parameters() + 1; for (int i = 0; i < argc; ++i) { uint typeInfo = m->d.data[paramsIndex + i]; - if (int id = types[i].type()) { - if (id == QMetaType(ifaces[i]).id()) + QMetaType mt = types[i].metaType(); + if (mt.isValid()) { + if (mt == QMetaType(ifaces[i])) continue; - if (id != typeFromTypeInfo(m, typeInfo)) + if (mt.id() != typeFromTypeInfo(m, typeInfo)) return false; } else { if (types[i].name() == QMetaType(ifaces[i]).name()) @@ -3994,7 +3995,7 @@ int QMetaProperty::notifySignalIndex() const if (idx >= 0) return idx + m->methodOffset(); // try 1-arg signal - QArgumentType argType(typeId()); + QArgumentType argType(metaType()); idx = QMetaObjectPrivate::indexOfMethodRelative(&m, signalName, 1, &argType); if (idx >= 0) return idx + m->methodOffset(); diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index c2b716ac52d..1c59a57cce4 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -41,21 +41,19 @@ Q_CORE_EXPORT int qMetaTypeTypeInternal(const char *); class QArgumentType { public: - QArgumentType(int type) - : _type(type) + QArgumentType() = default; + QArgumentType(QMetaType metaType) + : _metaType(metaType) {} QArgumentType(const QByteArray &name) - : _type(qMetaTypeTypeInternal(name.constData())), _name(name) + : _metaType(QMetaType(qMetaTypeTypeInternal(name.constData()))), _name(name) {} - QArgumentType() - : _type(0) - {} - int type() const - { return _type; } - QByteArray name() const + QMetaType metaType() const noexcept + { return _metaType; } + QByteArrayView name() const noexcept { - if (_type && _name.isEmpty()) - const_cast(this)->_name = QMetaType(_type).name(); + if (_name.isEmpty()) + return metaType().name(); return _name; } @@ -63,14 +61,14 @@ private: friend bool comparesEqual(const QArgumentType &lhs, const QArgumentType &rhs) { - if (lhs._type && rhs._type) - return lhs._type == rhs._type; + if (lhs.metaType().isValid() && rhs.metaType().isValid()) + return lhs.metaType() == rhs.metaType(); else return lhs.name() == rhs.name(); } Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QArgumentType) - int _type; + QMetaType _metaType; QByteArray _name; }; Q_DECLARE_TYPEINFO(QArgumentType, Q_RELOCATABLE_TYPE); diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 188cfd28a02..36505fae62f 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -101,13 +101,14 @@ static int *queuedConnectionTypes(const QMetaMethod &method) return typeIds; } +// ### Future work: replace with an array of QMetaType or QtPrivate::QMetaTypeInterface * static int *queuedConnectionTypes(const QArgumentType *argumentTypes, int argc) { auto types = std::make_unique(argc + 1); for (int i = 0; i < argc; ++i) { const QArgumentType &type = argumentTypes[i]; - if (type.type()) - types[i] = type.type(); + if (type.metaType().isValid()) + types[i] = type.metaType().id(); else if (type.name().endsWith('*')) types[i] = QMetaType::VoidStar; else @@ -3059,6 +3060,8 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign return QMetaObject::Connection(nullptr); } + // ### Future work: attempt get the metatypes from the meta object first + // because it's possible they're all registered. int *types = nullptr; if ((type == Qt::QueuedConnection) && !(types = queuedConnectionTypes(signalTypes.constData(), signalTypes.size()))) {