diff options
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 13 | ||||
-rw-r--r-- | tests/auto/qml/qqmlcomponent/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/auto/qml/qqmlcomponent/lifecyclewatcher.h | 24 | ||||
-rw-r--r-- | tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp | 31 |
4 files changed, 69 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 1b6bac5d0e..73e523fec6 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1092,8 +1092,15 @@ QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer<QQmlContextData> conte state.appendCreatorErrors(); enginePriv->dereferenceScarceResources(); } else { + // TODO: extract into function rv = loadedType.createWithQQmlData(); QQmlPropertyCache::ConstPtr propertyCache = QQmlData::ensurePropertyCache(rv); + QQmlParserStatus *parserStatus = nullptr; + const int parserStatusCast = loadedType.parserStatusCast(); + if (parserStatusCast != -1) { + parserStatus = reinterpret_cast<QQmlParserStatus*>(reinterpret_cast<char *>(rv) + parserStatusCast); + parserStatus->classBegin(); + } for (int i = 0, propertyCount = propertyCache->propertyCount(); i < propertyCount; ++i) { if (const QQmlPropertyData *propertyData = propertyCache->property(i); propertyData->isRequired()) { state.ensureRequiredPropertyStorage(); @@ -1102,6 +1109,12 @@ QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer<QQmlContextData> conte state.addPendingRequiredProperty(rv, propertyData, info); } } + if (parserStatus) + parserStatus->componentComplete(); + if (const int finalizerCast = loadedType.finalizerCast(); finalizerCast != -1) { + auto* hook = reinterpret_cast<QQmlFinalizerHook *>(reinterpret_cast<char *>(rv) + finalizerCast); + hook->componentFinalized(); + } } if (rv) { diff --git a/tests/auto/qml/qqmlcomponent/CMakeLists.txt b/tests/auto/qml/qqmlcomponent/CMakeLists.txt index 771d81709d..874c7f0cc3 100644 --- a/tests/auto/qml/qqmlcomponent/CMakeLists.txt +++ b/tests/auto/qml/qqmlcomponent/CMakeLists.txt @@ -46,6 +46,8 @@ qt_policy(SET QTP0001 NEW) qt_add_qml_module( tst_qqmlcomponent + SOURCES + lifecyclewatcher.h URI test QML_FILES "data/TestComponentWithIC.qml" diff --git a/tests/auto/qml/qqmlcomponent/lifecyclewatcher.h b/tests/auto/qml/qqmlcomponent/lifecyclewatcher.h new file mode 100644 index 0000000000..738fd86942 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/lifecyclewatcher.h @@ -0,0 +1,24 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef LIFECYCLEWATCHER_H +#define LIFECYCLEWATCHER_H + +#include <QtQml/qqmlparserstatus.h> +#include <private/qqmlfinalizer_p.h> +#include <QtCore/qobject.h> +#include <QtQml/qqml.h> + +class LifeCycleWatcher : public QObject, public QQmlParserStatus, public QQmlFinalizerHook +{ + Q_OBJECT + QML_ELEMENT + Q_INTERFACES(QQmlParserStatus) + Q_INTERFACES(QQmlFinalizerHook) +public: + void classBegin() override {states.push_back(1); } + void componentComplete() override {states.push_back(2);}; + void componentFinalized() override { states.push_back(3); } + QList<int> states; +}; +#endif diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index d8dbf0ede7..31dcea25b7 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -21,7 +21,7 @@ #include <private/qv4executablecompilationunit_p.h> #include <qcolor.h> #include <qsignalspy.h> - +#include "lifecyclewatcher.h" #include <algorithm> using namespace Qt::StringLiterals; @@ -133,6 +133,7 @@ private slots: void boundComponent(); void loadFromModule_data(); void loadFromModule(); + void loadFromModuleLifecycle(); void loadFromModuleThenCreateWithIncubator(); void loadFromModuleFailures_data(); void loadFromModuleFailures(); @@ -1345,6 +1346,34 @@ void tst_qqmlcomponent::loadFromModule() name); } +void tst_qqmlcomponent::loadFromModuleLifecycle() +{ + QQmlEngine engine; + QList<int> loadFromModuleOrder; + QList<int> plainLoadOrder; + const QList<int> expected {1, 2, 3}; + { + QQmlComponent component(&engine); + component.loadFromModule("test", "LifeCycleWatcher"); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + std::unique_ptr<QObject> root{ component.create() }; + LifeCycleWatcher *watcher = qobject_cast<LifeCycleWatcher *>(root.get()); + QVERIFY(watcher); + loadFromModuleOrder = watcher->states; + QCOMPARE(loadFromModuleOrder, expected); + } + { + QQmlComponent component(&engine); + component.setData("import test; LifeCycleWatcher {}", {}); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + std::unique_ptr<QObject> root{ component.create() }; + LifeCycleWatcher *watcher = qobject_cast<LifeCycleWatcher *>(root.get()); + QVERIFY(watcher); + plainLoadOrder = watcher->states; + } + QCOMPARE(loadFromModuleOrder, plainLoadOrder); +} + struct CallVerifyingIncubtor : QQmlIncubator { void setInitialState(QObject *) override { setInitialStateCalled = true; } |