diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-11-02 12:15:40 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-11-02 14:00:29 +0100 |
commit | 50ba4ffdf48461d38f4dd2137a0fbbc916c9eb0a (patch) | |
tree | 6caac8e7a67d27f0a9025523ec6e6a418196740a /src/qml/qml/qqmltype.cpp | |
parent | e826636a0bebd0d73e6c17038b24ee2a42d92ead (diff) |
QML: Allow singleton types to be extended
It seems we never stated that singletons can not be extended in our
documentation. Therefore this is technically a bug fix and doesn't need
separate documentation.
Change-Id: I7877289bd5a52ecf709f80ba1975137981ec65f0
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmltype.cpp')
-rw-r--r-- | src/qml/qml/qqmltype.cpp | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index e5b3653d2d..811ff668c6 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -78,6 +78,8 @@ QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type) case QQmlType::CompositeSingletonType: extraData.sd = new QQmlSingletonTypeData; extraData.sd->singletonInstanceInfo = nullptr; + extraData.sd->extFunc = nullptr; + extraData.sd->extMetaObject = nullptr; break; case QQmlType::InterfaceType: extraData.cd = nullptr; @@ -214,20 +216,27 @@ void QQmlTypePrivate::init() const return; } - if (regType == QQmlType::CppType) { - // Setup extended meta object + auto setupExtendedMetaObject = [&]( + const QMetaObject *extMetaObject, + QObject *(*extFunc)(QObject *)) { + + if (!extMetaObject) + return; + // XXX - very inefficient - if (extraData.cd->extMetaObject) { - QMetaObjectBuilder builder; - QQmlMetaType::clone(builder, extraData.cd->extMetaObject, extraData.cd->extMetaObject, - extraData.cd->extMetaObject); - builder.setFlags(MetaObjectFlag::DynamicMetaObject); - QMetaObject *mmo = builder.toMetaObject(); - mmo->d.superdata = mo; - QQmlProxyMetaObject::ProxyData data = { mmo, extraData.cd->extFunc, 0, 0 }; - metaObjects << data; - } - } + QMetaObjectBuilder builder; + QQmlMetaType::clone(builder, extMetaObject, extMetaObject, extMetaObject); + builder.setFlags(MetaObjectFlag::DynamicMetaObject); + QMetaObject *mmo = builder.toMetaObject(); + mmo->d.superdata = mo; + QQmlProxyMetaObject::ProxyData data = { mmo, extFunc, 0, 0 }; + metaObjects << data; + }; + + if (regType == QQmlType::SingletonType) + setupExtendedMetaObject(extraData.sd->extMetaObject, extraData.sd->extFunc); + else if (regType == QQmlType::CppType) + setupExtendedMetaObject(extraData.cd->extMetaObject, extraData.cd->extFunc); metaObjects.append(QQmlMetaType::proxyData( mo, baseMetaObject, metaObjects.isEmpty() ? nullptr @@ -477,9 +486,7 @@ QObject *QQmlType::create() const d->extraData.cd->newFunc(rv, d->extraData.cd->userdata); - if (rv && !d->metaObjects.isEmpty()) - (void)new QQmlProxyMetaObject(rv, &d->metaObjects); - + createProxy(rv); return rv; } @@ -493,9 +500,7 @@ void QQmlType::create(QObject **out, void **memory, size_t additionalMemory) con QObject *rv = (QObject *)operator new(d->extraData.cd->allocationSize + additionalMemory); d->extraData.cd->newFunc(rv, d->extraData.cd->userdata); - if (rv && !d->metaObjects.isEmpty()) - (void)new QQmlProxyMetaObject(rv, &d->metaObjects); - + createProxy(rv); *out = rv; *memory = ((char *)rv) + d->extraData.cd->allocationSize; } @@ -546,16 +551,32 @@ bool QQmlType::isCreatable() const QQmlType::ExtensionFunc QQmlType::extensionFunction() const { - if (!d || d->regType != CppType) + if (!d) + return nullptr; + + switch (d->regType) { + case CppType: + return d->extraData.cd->extFunc; + case SingletonType: + return d->extraData.sd->extFunc; + default: return nullptr; - return d->extraData.cd->extFunc; + } } const QMetaObject *QQmlType::extensionMetaObject() const { - if (!d || d->regType != CppType) + if (!d) + return nullptr; + + switch (d->regType) { + case CppType: + return d->extraData.cd->extMetaObject; + case SingletonType: + return d->extraData.sd->extMetaObject; + default: return nullptr; - return d->extraData.cd->extMetaObject; + } } bool QQmlType::isExtendedType() const @@ -976,4 +997,10 @@ QString QQmlType::pendingResolutionName() const return d->extraData.id->inlineComponentName; } +void QQmlType::createProxy(QObject *instance) const +{ + if (!d->metaObjects.isEmpty()) + (void)new QQmlProxyMetaObject(instance, &d->metaObjects); +} + QT_END_NAMESPACE |