aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/types/qqmlinstantiator.cpp38
-rw-r--r--src/qml/types/qqmlinstantiator_p_p.h2
-rw-r--r--tests/auto/qml/qqmlinstantiator/data/createMultipleAsync.qml10
-rw-r--r--tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp43
4 files changed, 86 insertions, 7 deletions
diff --git a/src/qml/types/qqmlinstantiator.cpp b/src/qml/types/qqmlinstantiator.cpp
index 8b59b0633d..0137a2796d 100644
--- a/src/qml/types/qqmlinstantiator.cpp
+++ b/src/qml/types/qqmlinstantiator.cpp
@@ -48,6 +48,7 @@ QQmlInstantiatorPrivate::QQmlInstantiatorPrivate()
, active(true)
, async(false)
, ownModel(false)
+ , requestedIndex(-1)
, model(QVariant(1))
, instanceModel(0)
, delegate(0)
@@ -75,6 +76,15 @@ void QQmlInstantiatorPrivate::clear()
q->objectChanged();
}
+QObject *QQmlInstantiatorPrivate::modelObject(int index, bool async)
+{
+ requestedIndex = index;
+ QObject *o = instanceModel->object(index, async);
+ requestedIndex = -1;
+ return o;
+}
+
+
void QQmlInstantiatorPrivate::regenerate()
{
Q_Q(QQmlInstantiator);
@@ -92,7 +102,7 @@ void QQmlInstantiatorPrivate::regenerate()
}
for (int i = 0; i < instanceModel->count(); i++) {
- QObject *object = instanceModel->object(i, async);
+ QObject *object = modelObject(i, async);
// If the item was already created we won't get a createdItem
if (object)
_q_createdItem(i, object);
@@ -106,8 +116,18 @@ void QQmlInstantiatorPrivate::_q_createdItem(int idx, QObject* item)
Q_Q(QQmlInstantiator);
if (objects.contains(item)) //Case when it was created synchronously in regenerate
return;
+ if (requestedIndex != idx) // Asynchronous creation, reference the object
+ (void)instanceModel->object(idx, false);
item->setParent(q);
- objects.insert(idx, item);
+ if (objects.size() < idx + 1) {
+ int modelCount = instanceModel->count();
+ if (objects.capacity() < modelCount)
+ objects.reserve(modelCount);
+ objects.resize(idx + 1);
+ }
+ if (QObject *o = objects.at(idx))
+ instanceModel->release(o);
+ objects.replace(idx, item);
if (objects.count() == 1)
q->objectChanged();
q->objectAdded(idx, item);
@@ -153,11 +173,15 @@ void QQmlInstantiatorPrivate::_q_modelUpdated(const QQmlChangeSet &changeSet, bo
if (insert.isMove()) {
QVector<QPointer<QObject> > movedObjects = moved.value(insert.moveId);
objects = objects.mid(0, index) + movedObjects + objects.mid(index);
- } else for (int i = 0; i < insert.count; ++i) {
- int modelIndex = index + i;
- QObject* obj = instanceModel->object(modelIndex, async);
- if (obj)
- _q_createdItem(modelIndex, obj);
+ } else {
+ if (insert.index <= objects.size())
+ objects.insert(insert.index, insert.count, 0);
+ for (int i = 0; i < insert.count; ++i) {
+ int modelIndex = index + i;
+ QObject* obj = modelObject(modelIndex, async);
+ if (obj)
+ _q_createdItem(modelIndex, obj);
+ }
}
difference += insert.count;
}
diff --git a/src/qml/types/qqmlinstantiator_p_p.h b/src/qml/types/qqmlinstantiator_p_p.h
index 6e936d8580..db8c469039 100644
--- a/src/qml/types/qqmlinstantiator_p_p.h
+++ b/src/qml/types/qqmlinstantiator_p_p.h
@@ -66,12 +66,14 @@ public:
void makeModel();
void _q_createdItem(int, QObject *);
void _q_modelUpdated(const QQmlChangeSet &, bool);
+ QObject *modelObject(int index, bool async);
bool componentComplete:1;
bool effectiveReset:1;
bool active:1;
bool async:1;
bool ownModel:1;
+ int requestedIndex;
QVariant model;
QQmlInstanceModel *instanceModel;
QQmlComponent *delegate;
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 <QtQml/qqmlcomponent.h>
#include <QtQml/private/qqmlinstantiator_p.h>
#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlincubator.h>
#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<bool>("asyncIncubator");
+ QTest::addColumn<QString>("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<QQmlInstantiator *>(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"