diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-08-28 13:34:12 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-08-30 14:18:17 +0200 |
commit | 4cdf0643b442a57b0cf0dcef104e71c0196dba06 (patch) | |
tree | 53d809ab1b42070c435c8325856e71ec30799255 /src/qml/qml/qqml.cpp | |
parent | 041b326fe6f5b98bf4f808976bdfc1a8d5aaeede (diff) |
QtQml: Key singletons by singleton instance info
We can keep the singleton instance info the same across multiple types
created in a single registration call. The result is that we only get
one singleton instance per engine, rather than separate ones for each
version. If you invoke qmlRegisterSingletonType separately, you still
get separate instances, though.
[ChangeLog][QtQml][Important Behavior Changes] The QML engine will now
refrain from creating separate instances of a singleton type for each
version it is registered for if the singleton is registered
declaratively (using QML_SINGLETON). The behavior of procedurally
registered singletons (using the qmlRegisterSingletonType() family of
functions) remains the same: For each registration call, a separate
singleton instance is created.
Task-number: QTBUG-116432
Change-Id: Ic8a5de0f88ef530670cfd81b192201a8ab49b2f7
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqml.cpp')
-rw-r--r-- | src/qml/qml/qqml.cpp | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 0abd8ec261..3b855e10e7 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -477,13 +477,43 @@ static void uniqueRevisions(QVector<QTypeRevision> *revisions, QTypeRevision def revisions->erase(it, revisions->end()); } +static QQmlType::SingletonInstanceInfo::ConstPtr singletonInstanceInfo( + const QQmlPrivate::RegisterSingletonType &type) +{ + QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create(); + siinfo->scriptCallback = type.scriptApi; + siinfo->qobjectCallback = type.qObjectApi; + siinfo->typeName = QString::fromUtf8(type.typeName); + return QQmlType::SingletonInstanceInfo::ConstPtr( + siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt); +} + +static QQmlType::SingletonInstanceInfo::ConstPtr singletonInstanceInfo( + const QQmlPrivate::RegisterCompositeSingletonType &type) +{ + QQmlType::SingletonInstanceInfo::Ptr siinfo = QQmlType::SingletonInstanceInfo::create(); + siinfo->url = QQmlTypeLoader::normalize(type.url); + siinfo->typeName = QString::fromUtf8(type.typeName); + return QQmlType::SingletonInstanceInfo::ConstPtr( + siinfo.take(), QQmlType::SingletonInstanceInfo::ConstPtr::Adopt); +} + +static int finalizeType(const QQmlType &dtype) +{ + if (!dtype.isValid()) + return -1; + + QQmlMetaType::registerUndeletableType(dtype); + return dtype.index(); +} + /* This method is "over generalized" to allow us to (potentially) register more types of things in the future without adding exported symbols. */ int QQmlPrivate::qmlregister(RegistrationType type, void *data) { - QQmlType dtype; + switch (type) { case AutoParentRegistration: return QQmlMetaType::registerAutoParentFunction( @@ -616,6 +646,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) type.extensionMetaObject, QTypeRevision() }; + const QQmlType::SingletonInstanceInfo::ConstPtr siinfo + = singletonInstanceInfo(revisionRegistration); const QTypeRevision added = revisionClassInfo( type.classInfoMetaObject, "QML.AddedInVersion", @@ -644,7 +676,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) revisionRegistration.qObjectApi = type.qObjectApi; } - const int id = qmlregister(SingletonRegistration, &revisionRegistration); + const int id = finalizeType( + QQmlMetaType::registerSingletonType(revisionRegistration, siinfo)); if (type.qmlTypeIds) type.qmlTypeIds->append(id); } @@ -685,32 +718,30 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) break; } case TypeRegistration: - dtype = QQmlMetaType::registerType(*reinterpret_cast<RegisterType *>(data)); - break; + return finalizeType( + QQmlMetaType::registerType(*reinterpret_cast<RegisterType *>(data))); case InterfaceRegistration: - dtype = QQmlMetaType::registerInterface(*reinterpret_cast<RegisterInterface *>(data)); - break; + return finalizeType( + QQmlMetaType::registerInterface(*reinterpret_cast<RegisterInterface *>(data))); case SingletonRegistration: - dtype = QQmlMetaType::registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data)); - break; + return finalizeType(QQmlMetaType::registerSingletonType( + *reinterpret_cast<RegisterSingletonType *>(data), + singletonInstanceInfo(*reinterpret_cast<RegisterSingletonType *>(data)))); case CompositeRegistration: - dtype = QQmlMetaType::registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data)); - break; + return finalizeType(QQmlMetaType::registerCompositeType( + *reinterpret_cast<RegisterCompositeType *>(data))); case CompositeSingletonRegistration: - dtype = QQmlMetaType::registerCompositeSingletonType(*reinterpret_cast<RegisterCompositeSingletonType *>(data)); - break; + return finalizeType(QQmlMetaType::registerCompositeSingletonType( + *reinterpret_cast<RegisterCompositeSingletonType *>(data), + singletonInstanceInfo(*reinterpret_cast<RegisterCompositeSingletonType *>(data)))); case SequentialContainerRegistration: - dtype = QQmlMetaType::registerSequentialContainer(*reinterpret_cast<RegisterSequentialContainer *>(data)); - break; + return finalizeType(QQmlMetaType::registerSequentialContainer( + *reinterpret_cast<RegisterSequentialContainer *>(data))); default: return -1; } - if (!dtype.isValid()) - return -1; - - QQmlMetaType::registerUndeletableType(dtype); - return dtype.index(); + return -1; } void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data) |