From 8a4032a05d4f8be285b123c05071ba4d09984978 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 13 Nov 2024 16:27:59 -0800 Subject: [PATCH] QObject: implement the ### Qt7 for dynamicMetaObject() As requested in qtbase/5d174877234477a59eb29818d3cfb99fedc3e704. Change-Id: I5f6568921a25918a5ae3fffdff7c136d3eb455a9 Reviewed-by: Ulf Hermann --- src/qml/qml/qqmlproxymetaobject.cpp | 5 ----- src/qml/qml/qqmlproxymetaobject_p.h | 9 +++++++- src/qml/qml/qqmlvaluetype.cpp | 4 ++++ src/qml/qml/qqmlvaluetype_p.h | 5 +++++ src/qml/qml/qqmlvmemetaobject.cpp | 21 +++++++++++++------ src/qml/qml/qqmlvmemetaobject_p.h | 4 ++++ src/qmlmodels/qqmldmlistaccessordata.cpp | 9 +++++++- src/qmlmodels/qqmldmlistaccessordata_p.h | 4 ++++ src/qmlmodels/qqmllistmodel.cpp | 6 +++++- src/qmlmodels/qqmllistmodel_p_p.h | 6 +++++- .../auto/qml/qmlcppcodegen/data/dynamicmeta.h | 4 ++++ tests/auto/qml/qqmlecmascript/testtypes.h | 7 +++++++ 12 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/qml/qml/qqmlproxymetaobject.cpp b/src/qml/qml/qqmlproxymetaobject.cpp index 6ec4009c37..381e567da5 100644 --- a/src/qml/qml/qqmlproxymetaobject.cpp +++ b/src/qml/qml/qqmlproxymetaobject.cpp @@ -127,11 +127,6 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void return object->qt_metacall(c, id, a); } -QMetaObject *QQmlProxyMetaObject::toDynamicMetaObject(QObject *) -{ - return metaObject; -} - void QQmlProxyMetaObject::objectDestroyed(QObject *object) { if (parent) diff --git a/src/qml/qml/qqmlproxymetaobject_p.h b/src/qml/qml/qqmlproxymetaobject_p.h index 18cf2d4bac..8fa8128754 100644 --- a/src/qml/qml/qqmlproxymetaobject_p.h +++ b/src/qml/qml/qqmlproxymetaobject_p.h @@ -48,7 +48,14 @@ public: protected: int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) override; - QMetaObject *toDynamicMetaObject(QObject *) override; +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + const QMetaObject *toDynamicMetaObject(QObject *) const override +#else + QMetaObject *toDynamicMetaObject(QObject *) override +#endif + { + return metaObject; + } void objectDestroyed(QObject *object) override; private: diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 5b06cf8c14..f09e6ac320 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -91,7 +91,11 @@ const QQmlValueType *QQmlGadgetPtrWrapper::valueType() const return static_cast(d->metaObject); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +const QMetaObject *QQmlValueType::toDynamicMetaObject(QObject *) const +#else QMetaObject *QQmlValueType::toDynamicMetaObject(QObject *) +#endif { if (!m_dynamicMetaObject) { QMetaObjectBuilder builder(m_staticMetaObject); diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index cac3d6c1f6..4b5442223d 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -49,7 +49,11 @@ public: const QMetaObject *staticMetaObject() const { return m_staticMetaObject; } // ---- dynamic meta object data interface +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + const QMetaObject *toDynamicMetaObject(QObject *) const override; +#else QMetaObject *toDynamicMetaObject(QObject *) override; +#endif void objectDestroyed(QObject *) override; int metaCall(QObject *obj, QMetaObject::Call type, int _id, void **argv) override; // ---- @@ -57,6 +61,7 @@ public: private: QMetaType m_metaType; const QMetaObject *m_staticMetaObject = nullptr; + QT7_ONLY(mutable const) QMetaObject *m_dynamicMetaObject = nullptr; }; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index ba5a61911f..8388b64ae3 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -390,26 +390,35 @@ bool QQmlInterceptorMetaObject::doIntercept(QMetaObject::Call c, int id, void ** return false; } -static QMetaObject *stringCastMetaObject(QObject *o, const QMetaObject *top) +static const QMetaObject *stringCastMetaObject(QObject *o, const QMetaObject *top) { for (const QMetaObject *mo = top; mo; mo = mo->superClass()) { if (o->qt_metacast(mo->className()) != nullptr) - return const_cast(mo); + return mo; } return nullptr; } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +const QMetaObject *QQmlInterceptorMetaObject::toDynamicMetaObject(QObject *o) const +#else QMetaObject *QQmlInterceptorMetaObject::toDynamicMetaObject(QObject *o) +#endif { if (!metaObject) metaObject = cache->createMetaObject(); + const QMetaObject *mo = nullptr; if (Q_UNLIKELY(metaObject.tag() == MetaObjectInvalid)) - return stringCastMetaObject(o, metaObject->superClass()); + mo = stringCastMetaObject(o, metaObject->superClass()); + if (!mo) + mo = metaObject.data(); - // ### Qt7: The const_cast is only due to toDynamicMetaObject having the wrong return type. - // It should be const QMetaObject *. Fix this. - return const_cast(metaObject.data()); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + return mo; +#else + return const_cast(mo); +#endif } QQmlVMEMetaObject::QQmlVMEMetaObject(QV4::ExecutionEngine *engine, diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h index 645c62fca2..e05e123c2b 100644 --- a/src/qml/qml/qqmlvmemetaobject_p.h +++ b/src/qml/qml/qqmlvmemetaobject_p.h @@ -108,7 +108,11 @@ public: static QQmlInterceptorMetaObject *get(QObject *obj); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + const QMetaObject *toDynamicMetaObject(QObject *o) const override; +#else QMetaObject *toDynamicMetaObject(QObject *o) override; +#endif // Used by auto-tests for inspection QQmlPropertyCache::ConstPtr propertyCache() const { return cache; } diff --git a/src/qmlmodels/qqmldmlistaccessordata.cpp b/src/qmlmodels/qqmldmlistaccessordata.cpp index bfd353771c..c5ec793f72 100644 --- a/src/qmlmodels/qqmldmlistaccessordata.cpp +++ b/src/qmlmodels/qqmldmlistaccessordata.cpp @@ -124,7 +124,11 @@ int VDMListDelegateDataType::createProperty(const char *name, const char *) return propertyIndex + propertyOffset; } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +const QMetaObject *VDMListDelegateDataType::toDynamicMetaObject(QObject *object) const +#else QMetaObject *VDMListDelegateDataType::toDynamicMetaObject(QObject *object) +#endif { if (const QQmlRefPointer &contextData = static_cast(object)->contextData) { @@ -139,8 +143,11 @@ QMetaObject *VDMListDelegateDataType::toDynamicMetaObject(QObject *object) ddata->propertyCache = propertyCache; } - // ### Qt 7: Return const from toDynamicMetaObject() and drop the const_cast. +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + return &QQmlDMListAccessorData::staticMetaObject; +#else return const_cast(&QQmlDMListAccessorData::staticMetaObject); +#endif } } diff --git a/src/qmlmodels/qqmldmlistaccessordata_p.h b/src/qmlmodels/qqmldmlistaccessordata_p.h index e02c3a88f6..0171ac6a97 100644 --- a/src/qmlmodels/qqmldmlistaccessordata_p.h +++ b/src/qmlmodels/qqmldmlistaccessordata_p.h @@ -280,7 +280,11 @@ public: int metaCall(QObject *object, QMetaObject::Call call, int id, void **arguments) final; int createProperty(const char *name, const char *) final; +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + const QMetaObject *toDynamicMetaObject(QObject *accessors) const final; +#else QMetaObject *toDynamicMetaObject(QObject *accessors) final; +#endif QMetaObjectBuilder builder; QQmlAdaptorModel *model = nullptr; diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp index 524aaa6659..09d20b582d 100644 --- a/src/qmlmodels/qqmllistmodel.cpp +++ b/src/qmlmodels/qqmllistmodel.cpp @@ -1570,11 +1570,15 @@ ModelNodeMetaObject::~ModelNodeMetaObject() { } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +const QMetaObject *ModelNodeMetaObject::toDynamicMetaObject(QObject *object) const +#else QMetaObject *ModelNodeMetaObject::toDynamicMetaObject(QObject *object) +#endif { if (!m_initialized) { m_initialized = true; - initialize(); + const_cast(this)->initialize(); } return QQmlOpenMetaObject::toDynamicMetaObject(object); } diff --git a/src/qmlmodels/qqmllistmodel_p_p.h b/src/qmlmodels/qqmllistmodel_p_p.h index f573a70f51..80ffa3ce93 100644 --- a/src/qmlmodels/qqmllistmodel_p_p.h +++ b/src/qmlmodels/qqmllistmodel_p_p.h @@ -91,7 +91,11 @@ public: ModelNodeMetaObject(QObject *object, QQmlListModel *model, int elementIndex); ~ModelNodeMetaObject(); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + const QMetaObject *toDynamicMetaObject(QObject *object) const override; +#else QMetaObject *toDynamicMetaObject(QObject *object) override; +#endif static ModelNodeMetaObject *get(QObject *obj); @@ -113,7 +117,7 @@ private: void emitDirectNotifies(const int *changedRoles, int roleCount); void initialize(); - bool m_initialized; + mutable bool m_initialized; }; namespace QV4 { diff --git a/tests/auto/qml/qmlcppcodegen/data/dynamicmeta.h b/tests/auto/qml/qmlcppcodegen/data/dynamicmeta.h index d8358b6a9c..d2fb057d0f 100644 --- a/tests/auto/qml/qmlcppcodegen/data/dynamicmeta.h +++ b/tests/auto/qml/qmlcppcodegen/data/dynamicmeta.h @@ -25,7 +25,11 @@ public: free(metaObject); }; +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + const QMetaObject *toDynamicMetaObject(QObject *) const override +#else QMetaObject *toDynamicMetaObject(QObject *) override +#endif { return metaObject; } diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index cc20437fff..7f15e6d374 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -2156,10 +2156,17 @@ public: QDynamicMetaObjectData::objectDestroyed(object); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + const QMetaObject *toDynamicMetaObject(QObject *) const override + { + return &MetaCallInterceptor::staticMetaObject; + } +#else QMetaObject *toDynamicMetaObject(QObject *) override { return const_cast(&MetaCallInterceptor::staticMetaObject); } +#endif int metaCall(QObject *o, QMetaObject::Call call, int idx, void **argv) override {