aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmltype.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-11-02 12:15:40 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-11-02 14:00:29 +0100
commit50ba4ffdf48461d38f4dd2137a0fbbc916c9eb0a (patch)
tree6caac8e7a67d27f0a9025523ec6e6a418196740a /src/qml/qml/qqmltype.cpp
parente826636a0bebd0d73e6c17038b24ee2a42d92ead (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.cpp73
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