diff options
| author | Andrei Golubev <[email protected]> | 2022-04-28 11:03:09 +0200 |
|---|---|---|
| committer | Andrei Golubev <[email protected]> | 2022-06-02 10:07:39 +0200 |
| commit | 26179e693717535eeff2e7b2a6ee99dc02dcd8f9 (patch) | |
| tree | d546e470e6047165bff96209e5a8d913bc3abf75 /src/qml/qmltc | |
| parent | b85ac05e4ab3ef356ef59f6c57f44855edf15c5c (diff) | |
Address extension types in qmltc
Whenever working with properties (reading, writing, aliasing, etc.)
of the type that has extensions, prefer the same-named properties
from extension objects over type-owned properties (this is the internal
QML mechanism)
To achieve that, we need to query the extension object:
* for Q_GADGETs use a dummy model of assuming we can cast the object
to the extension type and use that
* for Q_OBJECTs use a qmlExtendedObject() with additional logic of
figuring out which extension should be picked in each specific case
Create QQmlProxyMetaObject via a custom dynamic meta object API for
qmltc-compiled objects that are derived from base types with
extensions
Task-number: QTBUG-91956
Change-Id: I5e783768ae2abdb9dddf894de7e79960244352bd
Reviewed-by: Ulf Hermann <[email protected]>
Diffstat (limited to 'src/qml/qmltc')
| -rw-r--r-- | src/qml/qmltc/qqmltcobjectcreationhelper.cpp | 98 | ||||
| -rw-r--r-- | src/qml/qmltc/qqmltcobjectcreationhelper_p.h | 23 |
2 files changed, 120 insertions, 1 deletions
diff --git a/src/qml/qmltc/qqmltcobjectcreationhelper.cpp b/src/qml/qmltc/qqmltcobjectcreationhelper.cpp new file mode 100644 index 0000000000..b88b43d7be --- /dev/null +++ b/src/qml/qmltc/qqmltcobjectcreationhelper.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqmltcobjectcreationhelper_p.h" + +#include <private/qqmlmetatype_p.h> +#include <private/qmetaobjectbuilder_p.h> +#include <private/qobject_p.h> +#include <private/qqmltype_p_p.h> + +QT_BEGIN_NAMESPACE + +void qmltcCreateDynamicMetaObject(QObject *object, const QMetaObject *staticMetaObject, + const QmltcTypeData &data) +{ + // TODO: when/if qmltc-compiled types would be registered via + // qmltyperegistrar, instead of creating a dummy QQmlTypePrivate, fetch the + // good QQmlType via QQmlMetaType::qmlType(). to do it correctly, one needs, + // along with the meta object, module name and revision. all that should be + // available ahead-of-time to qmltc. + auto qmlTypePrivate = new QQmlTypePrivate(data.regType); + // place the newly created QQmlTypePrivate into the qml meta data storage so + // that it is properly deleted + QQmlMetaType::registerMetaObjectForType(staticMetaObject, qmlTypePrivate); + + // initialize QQmlType::QQmlCppTypeData + Q_ASSERT(data.regType == QQmlType::CppType); + qmlTypePrivate->extraData.cd->allocationSize = data.allocationSize; + qmlTypePrivate->extraData.cd->newFunc = nullptr; + qmlTypePrivate->extraData.cd->userdata = nullptr; + qmlTypePrivate->extraData.cd->noCreationReason = + QStringLiteral("Qmltc-compiled type is not creatable via QQmlType"); + qmlTypePrivate->extraData.cd->createValueTypeFunc = nullptr; + qmlTypePrivate->extraData.cd->parserStatusCast = -1; + qmlTypePrivate->extraData.cd->extFunc = nullptr; + qmlTypePrivate->extraData.cd->extMetaObject = nullptr; + qmlTypePrivate->extraData.cd->customParser = nullptr; + qmlTypePrivate->extraData.cd->attachedPropertiesFunc = nullptr; + qmlTypePrivate->extraData.cd->attachedPropertiesType = nullptr; + qmlTypePrivate->extraData.cd->propertyValueSourceCast = -1; + qmlTypePrivate->extraData.cd->propertyValueInterceptorCast = -1; + qmlTypePrivate->extraData.cd->finalizerCast = -1; + qmlTypePrivate->extraData.cd->registerEnumClassesUnscoped = false; + qmlTypePrivate->extraData.cd->registerEnumsFromRelatedTypes = false; + + qmlTypePrivate->baseMetaObject = data.metaObject; + qmlTypePrivate->init(); + + QQmlType qmlType(qmlTypePrivate); + Q_ASSERT(qmlType.isValid()); + + QObjectPrivate *op = QObjectPrivate::get(object); + // ### inefficient - rather, call this function only once for the leaf type + if (op->metaObject) { + delete op->metaObject; + op->metaObject = nullptr; + } + + qmlType.createProxy(object); +} + +QT_END_NAMESPACE diff --git a/src/qml/qmltc/qqmltcobjectcreationhelper_p.h b/src/qml/qmltc/qqmltcobjectcreationhelper_p.h index 6aa37b1e53..56b89925da 100644 --- a/src/qml/qmltc/qqmltcobjectcreationhelper_p.h +++ b/src/qml/qmltc/qqmltcobjectcreationhelper_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQml module of the Qt Toolkit. @@ -53,6 +53,9 @@ #include <QtQml/qqml.h> #include <QtCore/private/qglobal_p.h> +#include <QtCore/qversionnumber.h> +#include <private/qtqmlglobal_p.h> +#include <private/qqmltype_p.h> #include <array> @@ -137,6 +140,24 @@ public: } }; +struct QmltcTypeData +{ + QQmlType::RegistrationType regType = QQmlType::CppType; + int allocationSize = 0; + const QMetaObject *metaObject = nullptr; + + template<typename QmltcGeneratedType> + QmltcTypeData(QmltcGeneratedType *) + : allocationSize(sizeof(QmltcGeneratedType)), + metaObject(&QmltcGeneratedType::staticMetaObject) + { + } +}; + +Q_QML_PRIVATE_EXPORT void qmltcCreateDynamicMetaObject(QObject *object, + const QMetaObject *staticMetaObject, + const QmltcTypeData &data); + QT_END_NAMESPACE #endif // QQMLTCOBJECTCREATIONHELPER_P_H |
