Improve QDeclarativeIncubator JS API
authorAaron Kennedy <aaron.kennedy@nokia.com>
Fri, 30 Sep 2011 04:26:28 +0000 (14:26 +1000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 30 Sep 2011 08:37:05 +0000 (10:37 +0200)
Change-Id: Ic06af88a8be68b41f563bfd6cd7322375cd29224
Task-number: QTBUG-21151
Reviewed-on: http://codereview.qt-project.org/5827
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>

src/declarative/qml/qdeclarativecomponent.cpp
src/declarative/qml/qdeclarativeincubator.cpp
src/declarative/qml/qdeclarativeincubator_p.h
src/declarative/qml/v8/qv8engine.cpp

index 2f1ad82..0bcfd5a 100644 (file)
@@ -944,6 +944,8 @@ public:
     static void StatusChangedSetter(v8::Local<v8::String>, v8::Local<v8::Value> value, 
                                     const v8::AccessorInfo& info);
 
+    void dispose();
+
     v8::Persistent<v8::Object> me;
     QDeclarativeGuard<QObject> parent;
     v8::Persistent<v8::Value> valuemap;
@@ -1098,35 +1100,31 @@ void QDeclarativeComponent::incubateObject(QDeclarativeV8Function *args)
 
     if (args->Length() >= 3) {
         quint32 v = (*args)[2]->Uint32Value();
-        if (v == QDeclarativeIncubator::Asynchronous) 
+        if (v == 0)
             mode = QDeclarativeIncubator::Asynchronous;
-        else if (v == QDeclarativeIncubator::AsynchronousIfNested) 
+        else if (v == 1)
             mode = QDeclarativeIncubator::AsynchronousIfNested;
-        else if (v == QDeclarativeIncubator::Synchronous) 
-            mode = QDeclarativeIncubator::Synchronous;
     }
 
     QDeclarativeComponentExtension *e = componentExtension(args->engine());
     
     QV8IncubatorResource *r = new QV8IncubatorResource(args->engine(), mode);
+    v8::Local<v8::Object> o = e->incubationConstructor->NewInstance();
+    o->SetExternalResource(r);
+
     if (!valuemap.IsEmpty()) {
         r->valuemap = qPersistentNew(valuemap);
         r->qmlGlobal = qPersistentNew(args->qmlGlobal());
     }
     r->parent = parent;
+    r->me = qPersistentNew(o);
 
     create(*r, creationContext());
 
     if (r->status() == QDeclarativeIncubator::Null) {
-        delete r;
+        r->dispose();
         args->returnValue(v8::Null());
     } else {
-        v8::Local<v8::Object> o = e->incubationConstructor->NewInstance();
-        o->SetExternalResource(r);
-
-        if (r->status() == QDeclarativeIncubator::Loading) 
-            r->me = qPersistentNew(o);
-
         args->returnValue(o);
     }
 }
@@ -1275,6 +1273,14 @@ void QV8IncubatorResource::setInitialState(QObject *o)
         qPersistentDispose(qmlGlobal);
     }
 }
+    
+void QV8IncubatorResource::dispose()
+{
+    qPersistentDispose(valuemap);
+    qPersistentDispose(qmlGlobal);
+    // No further status changes are forthcoming, so we no long need a self reference
+    qPersistentDispose(me);
+}
 
 void QV8IncubatorResource::statusChanged(Status s)
 {
@@ -1293,18 +1299,20 @@ void QV8IncubatorResource::statusChanged(Status s)
                 v8::Context::Scope context_scope(engine->context());
                 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(callback);
                 v8::Handle<v8::Value> args[] = { v8::Integer::NewFromUnsigned(s) };
-                // XXX TryCatch
+                v8::TryCatch tc;
                 f->Call(me, 1, args);
+                if (tc.HasCaught()) {
+                    QDeclarativeError error;
+                    QDeclarativeExpressionPrivate::exceptionToError(tc.Message(), error);
+                    QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate::get(engine->engine()),
+                                                       error);
+                }
             }
         }
     }
 
-    if (s == Ready || s == Error) {
-        qPersistentDispose(valuemap);
-        qPersistentDispose(qmlGlobal);
-        // No further status changes are forthcoming, so we no long need a self reference
-        qPersistentDispose(me);
-    }
+    if (s == Ready || s == Error) 
+        dispose();
 }
 
 QT_END_NAMESPACE
index a468dc5..053a026 100644 (file)
@@ -131,6 +131,7 @@ void QDeclarativeIncubatorPrivate::clear()
         Q_ASSERT(component);
         QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(component->engine);
         component->release();
+        component = 0;
 
         enginePriv->incubatorCount--;
         QDeclarativeIncubationController *controller = enginePriv->incubationController;
@@ -143,7 +144,6 @@ void QDeclarativeIncubatorPrivate::clear()
         nextWaitingFor.remove();
         waitingOnMe = 0;
     }
-
 }
 
 /*!
@@ -454,6 +454,22 @@ Ready state, the created object is \b not deleted.
 */
 void QDeclarativeIncubator::clear()
 {
+    Status s = status();
+
+    if (s == Loading)
+        qFatal("QDeclarativeIncubator::clear(): Clear not implemented for loading incubator");
+
+    if (s == Null)
+        return;
+
+    Q_ASSERT(d->component == 0);
+    Q_ASSERT(d->waitingOnMe == 0);
+    Q_ASSERT(d->waitingFor.isEmpty());
+    Q_ASSERT(!d->nextWaitingFor.isInList());
+
+    d->errors.clear();
+    d->progress = QDeclarativeIncubatorPrivate::Execute;
+    d->result = 0;
 }
 
 /*!
index 8210f6d..57c54d3 100644 (file)
@@ -63,7 +63,6 @@ class QDeclarativeCompiledData;
 class QDeclarativeIncubator;
 class QDeclarativeIncubatorPrivate : public QDeclarativeEnginePrivate::Incubator
 {
-    QIntrusiveListNode nextWaitingFor;
 public:
     QDeclarativeIncubatorPrivate(QDeclarativeIncubator *q, QDeclarativeIncubator::IncubationMode m);
     ~QDeclarativeIncubatorPrivate();
@@ -83,6 +82,7 @@ public:
 
     typedef QDeclarativeIncubatorPrivate QIP;
     QIP *waitingOnMe;
+    QIntrusiveListNode nextWaitingFor;
     QIntrusiveList<QIP, &QIP::nextWaitingFor> waitingFor;
 
     void clear();
index 4bbea93..2108480 100644 (file)
@@ -502,6 +502,8 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
             qt->Set(v8::String::New(enumerator.key(jj)), v8::Integer::New(enumerator.value(jj)));
         }
     }
+    qt->Set(v8::String::New("Asynchronous"), v8::Integer::New(0));
+    qt->Set(v8::String::New("Synchronous"), v8::Integer::New(1));
 
     qt->Set(v8::String::New("include"), V8FUNCTION(QV8Include::include, this));
     qt->Set(v8::String::New("isQtObject"), V8FUNCTION(isQtObject, this));