aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2012-03-19 17:37:02 +1000
committerQt by Nokia <qt-info@nokia.com>2012-03-19 10:49:39 +0100
commitaf3a8708b46e8ae6e177dcee028364bd9fd285cd (patch)
tree1ae7bf29edb1e7f92a2b8bf4048c0acd1b7312bc
parent6deb3ceffa209d710570ffeb361e95c988e6e7cd (diff)
When clearing an incubator also clear incubators it is waiting for.
If an incubator is cleared while waiting for other incubators to complete also clear the incubators it is waiting for. Change-Id: I83470920c0fd8a23d0098849192555f7478bb492 Reviewed-by: Andrew den Exter <andrew.den-exter@nokia.com>
-rw-r--r--src/qml/qml/qqmlincubator.cpp4
-rw-r--r--tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp117
2 files changed, 121 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index c8413f70ca..aa9777d89e 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -542,6 +542,10 @@ void QQmlIncubator::clear()
d->clear();
+ // if we're waiting on any incubators then they should be cleared too.
+ while (d->waitingFor.first())
+ static_cast<QQmlIncubatorPrivate*>(d->waitingFor.first())->q->clear();
+
d->vme.reset();
d->vmeGuard.clear();
diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
index fc54f715c9..54a31aef1d 100644
--- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
+++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
@@ -76,6 +76,7 @@ private slots:
void nestedComponent();
void chainedAsynchronousIfNested();
void chainedAsynchronousIfNestedOnCompleted();
+ void chainedAsynchronousClear();
void selfDelete();
void contextDelete();
@@ -934,6 +935,122 @@ void tst_qqmlincubator::chainedAsynchronousIfNestedOnCompleted()
QVERIFY(incubator3.isReady());
}
+// Checks that new AsynchronousIfNested incubators can be correctly cleared if started in
+// componentCompleted().
+void tst_qqmlincubator::chainedAsynchronousClear()
+{
+ SelfRegisteringType::clearMe();
+
+ QQmlComponent component(&engine, testFileUrl("chainInCompletion.qml"));
+ QVERIFY(component.isReady());
+
+ QQmlComponent c1(&engine, testFileUrl("chainedAsynchronousIfNested.qml"));
+ QVERIFY(c1.isReady());
+
+ struct MyIncubator : public QQmlIncubator {
+ MyIncubator(MyIncubator *next, QQmlComponent *component, QQmlContext *ctxt)
+ : QQmlIncubator(AsynchronousIfNested), next(next), component(component), ctxt(ctxt) {}
+
+ protected:
+ virtual void statusChanged(Status s) {
+ if (s == Ready && next) {
+ component->create(*next, 0, ctxt);
+ }
+ }
+
+ private:
+ MyIncubator *next;
+ QQmlComponent *component;
+ QQmlContext *ctxt;
+ };
+
+ struct CallbackData {
+ CallbackData(QQmlComponent *c, MyIncubator *i, QQmlContext *ct)
+ : component(c), incubator(i), ctxt(ct) {}
+ QQmlComponent *component;
+ MyIncubator *incubator;
+ QQmlContext *ctxt;
+ static void callback(CompletionCallbackType *, void *data) {
+ CallbackData *d = (CallbackData *)data;
+ d->component->create(*d->incubator, 0, d->ctxt);
+ }
+ };
+
+ QQmlIncubator incubator(QQmlIncubator::Asynchronous);
+ component.create(incubator);
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(SelfRegisteringType::me() == 0);
+
+ while (SelfRegisteringType::me() == 0 && incubator.isLoading()) {
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(SelfRegisteringType::me() != 0);
+ QVERIFY(incubator.isLoading());
+
+ MyIncubator incubator3(0, &c1, qmlContext(SelfRegisteringType::me()));
+ MyIncubator incubator2(&incubator3, &c1, qmlContext(SelfRegisteringType::me()));
+ MyIncubator incubator1(&incubator2, &c1, qmlContext(SelfRegisteringType::me()));
+
+ // start incubator1 in componentComplete
+ CallbackData cd(&c1, &incubator1, qmlContext(SelfRegisteringType::me()));
+ CompletionCallbackType::registerCallback(&CallbackData::callback, &cd);
+
+ while (!incubator1.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator2.isNull());
+ QVERIFY(incubator3.isNull());
+
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isLoading());
+ QVERIFY(incubator2.isNull());
+ QVERIFY(incubator3.isNull());
+
+ while (incubator1.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isLoading());
+ QVERIFY(incubator2.isNull());
+ QVERIFY(incubator3.isNull());
+
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isLoading());
+ QVERIFY(incubator3.isNull());
+
+ while (incubator2.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isLoading());
+ QVERIFY(incubator3.isNull());
+
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isReady());
+ QVERIFY(incubator3.isLoading());
+
+ // Any in loading state will become null when cleared.
+ incubator.clear();
+
+ QVERIFY(incubator.isNull());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isReady());
+ QVERIFY(incubator3.isNull());
+}
+
void tst_qqmlincubator::selfDelete()
{
struct MyIncubator : public QQmlIncubator {