From d3ecdc4ba41bb099c5bab380304386e1a4bfdd31 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 30 Sep 2011 14:26:28 +1000 Subject: [PATCH] Improve QDeclarativeIncubator JS API Change-Id: Ic06af88a8be68b41f563bfd6cd7322375cd29224 Task-number: QTBUG-21151 Reviewed-on: http://codereview.qt-project.org/5827 Reviewed-by: Aaron Kennedy --- src/declarative/qml/qdeclarativecomponent.cpp | 44 ++++++++++++++---------- src/declarative/qml/qdeclarativeincubator.cpp | 18 +++++++++- src/declarative/qml/qdeclarativeincubator_p.h | 2 +- src/declarative/qml/v8/qv8engine.cpp | 2 + 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 2f1ad82..0bcfd5a 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -944,6 +944,8 @@ public: static void StatusChangedSetter(v8::Local, v8::Local value, const v8::AccessorInfo& info); + void dispose(); + v8::Persistent me; QDeclarativeGuard parent; v8::Persistent 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 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 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 f = v8::Local::Cast(callback); v8::Handle 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 diff --git a/src/declarative/qml/qdeclarativeincubator.cpp b/src/declarative/qml/qdeclarativeincubator.cpp index a468dc5..053a026 100644 --- a/src/declarative/qml/qdeclarativeincubator.cpp +++ b/src/declarative/qml/qdeclarativeincubator.cpp @@ -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; } /*! diff --git a/src/declarative/qml/qdeclarativeincubator_p.h b/src/declarative/qml/qdeclarativeincubator_p.h index 8210f6d..57c54d3 100644 --- a/src/declarative/qml/qdeclarativeincubator_p.h +++ b/src/declarative/qml/qdeclarativeincubator_p.h @@ -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 waitingFor; void clear(); diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp index 4bbea93..2108480 100644 --- a/src/declarative/qml/v8/qv8engine.cpp +++ b/src/declarative/qml/v8/qv8engine.cpp @@ -502,6 +502,8 @@ void QV8Engine::initializeGlobal(v8::Handle 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)); -- 1.7.2.5