From 8018c4b6e7743c576a3548f6e73e588f19f632a9 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 23 Apr 2015 11:12:08 +0200 Subject: Instantiator: Make asynchronous mode work This patch proceeds in two steps. First, and the most trivial, we make sure not to offend the Instantiator's objects container since asynchronous creation also means the objects can be created in any order. We do so by ensuring the objects container has always the necessary size. The second step is to make sure the objects don't get destroyed by the delegate model when their incubation tasks are asynchronous. We force to keep an extra reference calling the object() function on the instance model, but only if the creation was asynchronous. However, it's not enough to check for the Instantiatior async value since the incubation tasks in QQmlDelegateModel are async-if-nested. Therefore, we need to keep track of the object index requested to the model and see if it matches when the createdItem() signal gets emitted. Task-number: QTBUG-36410 Change-Id: I180b03b6a7468d6521827a9631755577e9e6d357 Reviewed-by: Andrew den Exter --- .../qqmlinstantiator/data/createMultipleAsync.qml | 10 +++++ .../qml/qqmlinstantiator/tst_qqmlinstantiator.cpp | 43 ++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/auto/qml/qqmlinstantiator/data/createMultipleAsync.qml (limited to 'tests/auto/qml/qqmlinstantiator') diff --git a/tests/auto/qml/qqmlinstantiator/data/createMultipleAsync.qml b/tests/auto/qml/qqmlinstantiator/data/createMultipleAsync.qml new file mode 100644 index 0000000000..8d1ab0ed6a --- /dev/null +++ b/tests/auto/qml/qqmlinstantiator/data/createMultipleAsync.qml @@ -0,0 +1,10 @@ +import QtQml 2.1 + +Instantiator { + model: 10 + asynchronous: true + delegate: QtObject { + property bool success: true + property int idx: index + } +} diff --git a/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp b/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp index b6ca50cc78..7ee33b1e58 100644 --- a/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp +++ b/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include "../../shared/util.h" #include "stringmodel.h" @@ -53,6 +54,9 @@ private slots: void activeProperty(); void intModelChange(); void createAndRemove(); + + void asynchronous_data(); + void asynchronous(); }; void tst_qqmlinstantiator::createNone() @@ -209,6 +213,45 @@ void tst_qqmlinstantiator::createAndRemove() QCOMPARE(object->property("datum").toString(), names[i]); } } + +void tst_qqmlinstantiator::asynchronous_data() +{ + QTest::addColumn("asyncIncubator"); + QTest::addColumn("fileName"); + + QTest::newRow("Asynchronous Instantiator") << false << "createMultipleAsync.qml"; + QTest::newRow("Nested-asynchronous Instantiator") << true << "createMultiple.qml"; +} + +void tst_qqmlinstantiator::asynchronous() +{ + QFETCH(bool, asyncIncubator); + QFETCH(QString, fileName); + + QQmlEngine engine; + QQmlIncubationController incubationController; + engine.setIncubationController(&incubationController); + QQmlComponent component(&engine, testFileUrl(fileName)); + QQmlIncubator incubator(asyncIncubator ? QQmlIncubator::Asynchronous : QQmlIncubator::Synchronous); + component.create(incubator); + while (!incubator.isReady()) + incubationController.incubateFor(10); + QQmlInstantiator *instantiator = qobject_cast(incubator.object()); + while (incubationController.incubatingObjectCount() > 0) + incubationController.incubateFor(10); + QVERIFY(instantiator != 0); + QCOMPARE(instantiator->isActive(), true); + QCOMPARE(instantiator->count(), 10); + + for (int i=0; i<10; i++) { + QObject *object = instantiator->objectAt(i); + QVERIFY(object); + QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->property("success").toBool(), true); + QCOMPARE(object->property("idx").toInt(), i); + } +} + QTEST_MAIN(tst_qqmlinstantiator) #include "tst_qqmlinstantiator.moc" -- cgit v1.2.3