Behave correctly when AsynchronousIfNested is nested
authorAaron Kennedy <aaron.kennedy@nokia.com>
Tue, 18 Oct 2011 03:34:20 +0000 (13:34 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 20 Oct 2011 11:25:31 +0000 (13:25 +0200)
When AIN is nested within a synchronous AIN, it should behave
synchronously.

Change-Id: Ib3f8281667118d7787967f25e27797f67e581006
Reviewed-by: Martin Jones <martin.jones@nokia.com>

src/declarative/qml/qdeclarativeincubator.cpp
src/declarative/qml/qdeclarativeincubator_p.h
tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.3.qml [new file with mode: 0644]
tests/auto/declarative/qdeclarativeincubator/testtypes.cpp
tests/auto/declarative/qdeclarativeincubator/testtypes.h
tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp

index 1417ed4..abd759d 100644 (file)
@@ -72,13 +72,15 @@ void QDeclarativeEnginePrivate::incubate(QDeclarativeIncubator &i, QDeclarativeC
             cctxt = cctxt->parent;
         }
 
-        if (parentIncubator && parentIncubator->mode != QDeclarativeIncubator::Synchronous) {
+        if (parentIncubator && parentIncubator->isAsynchronous) {
             mode = QDeclarativeIncubator::Asynchronous;
             p->waitingOnMe = parentIncubator;
             parentIncubator->waitingFor.insert(p);
         }
     }
 
+    p->isAsynchronous = (mode != QDeclarativeIncubator::Synchronous);
+
     inProgressCreations++;
 
     p->changeStatus(QDeclarativeIncubator::Loading);
@@ -121,8 +123,8 @@ QDeclarativeIncubationController *QDeclarativeEngine::incubationController() con
 
 QDeclarativeIncubatorPrivate::QDeclarativeIncubatorPrivate(QDeclarativeIncubator *q, 
                                                            QDeclarativeIncubator::IncubationMode m)
-: q(q), status(QDeclarativeIncubator::Null), mode(m), progress(Execute), result(0), component(0), 
-  vme(this), waitingOnMe(0)
+: q(q), status(QDeclarativeIncubator::Null), mode(m), isAsynchronous(false), progress(Execute),
+  result(0), component(0), vme(this), waitingOnMe(0)
 {
 }
 
index b17dbe8..eaa4ce5 100644 (file)
@@ -75,6 +75,7 @@ public:
     QDeclarativeIncubator::Status status;
 
     QDeclarativeIncubator::IncubationMode mode;
+    bool isAsynchronous;
 
     QList<QDeclarativeError> errors;
 
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.3.qml b/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.3.qml
new file mode 100644 (file)
index 0000000..7e5ee7c
--- /dev/null
@@ -0,0 +1,5 @@
+import Qt.test 1.0
+
+CallbackRegistering {
+    value: 19
+}
index 3ff15a7..99d2cb1 100644 (file)
@@ -82,8 +82,28 @@ void CompletionRegisteringType::clearMe()
     m_me = 0;
 }
 
+CallbackRegisteringType::callback CallbackRegisteringType::m_callback = 0;
+void *CallbackRegisteringType::m_data = 0;
+CallbackRegisteringType::CallbackRegisteringType()
+: m_v(0)
+{
+}
+
+void CallbackRegisteringType::clearCallback()
+{
+    m_callback = 0;
+    m_data = 0;
+}
+
+void CallbackRegisteringType::registerCallback(callback c, void *d)
+{
+    m_callback = c;
+    m_data = d;
+}
+
 void registerTypes()
 {
     qmlRegisterType<SelfRegisteringType>("Qt.test", 1,0, "SelfRegistering");
     qmlRegisterType<CompletionRegisteringType>("Qt.test", 1,0, "CompletionRegistering");
+    qmlRegisterType<CallbackRegisteringType>("Qt.test", 1,0, "CallbackRegistering");
 }
index 85ee4a6..6e73254 100644 (file)
@@ -63,6 +63,27 @@ private:
     int m_v;
 };
 
+class CallbackRegisteringType : public QObject
+{
+Q_OBJECT
+Q_PROPERTY(int value READ value WRITE setValue)
+public:
+    CallbackRegisteringType();
+
+    int value() const { return m_v; }
+    void setValue(int v) { if (m_callback) m_callback(this, m_data); m_v = v; }
+
+    typedef void (*callback)(CallbackRegisteringType *, void *);
+    static void clearCallback();
+    static void registerCallback(callback, void *);
+
+private:
+    static callback m_callback;
+    static void *m_data;
+
+    int m_v;
+};
+
 class CompletionRegisteringType : public QObject, public QDeclarativeParserStatus
 {
 Q_OBJECT
index 672387e..3582548 100644 (file)
@@ -614,6 +614,46 @@ void tst_qdeclarativeincubator::asynchronousIfNested()
     delete nested.object();
     delete incubator.object();
     }
+
+    // AsynchronousIfNested within a synchronous AsynchronousIfNested behaves synchronously
+    {
+    SelfRegisteringType::clearMe();
+
+    QDeclarativeComponent component(&engine, TEST_FILE("asynchronousIfNested.3.qml"));
+    QVERIFY(component.isReady());
+
+    struct CallbackData {
+        CallbackData(QDeclarativeEngine *e) : engine(e), pass(false) {}
+        QDeclarativeEngine *engine;
+        bool pass;
+        static void callback(CallbackRegisteringType *o, void *data) {
+            CallbackData *d = (CallbackData *)data;
+
+            QDeclarativeComponent c(d->engine, TEST_FILE("asynchronousIfNested.1.qml"));
+            if (!c.isReady()) return;
+
+            QDeclarativeIncubator incubator(QDeclarativeIncubator::AsynchronousIfNested);
+            c.create(incubator, 0, qmlContext(o));
+
+            if (!incubator.isReady()) return;
+
+            if (incubator.object()->property("a").toInt() != 10) return;
+
+            d->pass = true;
+        }
+    };
+
+    CallbackData cd(&engine);
+    CallbackRegisteringType::registerCallback(&CallbackData::callback, &cd);
+
+    QDeclarativeIncubator incubator(QDeclarativeIncubator::AsynchronousIfNested);
+    component.create(incubator);
+
+    QVERIFY(incubator.isReady());
+    QCOMPARE(cd.pass, true);
+
+    delete incubator.object();
+    }
 }
 
 void tst_qdeclarativeincubator::nestedComponent()