Skip to content

Commit

Permalink
Improve QDeclarativeIncubator JS API
Browse files Browse the repository at this point in the history
Change-Id: Ic06af88a8be68b41f563bfd6cd7322375cd29224
Task-number: QTBUG-21151
Reviewed-on: http://codereview.qt-project.org/5827
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
  • Loading branch information
Aaron Kennedy authored and Qt by Nokia committed Sep 30, 2011
1 parent f07805f commit d3ecdc4
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 20 deletions.
44 changes: 26 additions & 18 deletions src/declarative/qml/qdeclarativecomponent.cpp
Expand Up @@ -944,6 +944,8 @@ V8_RESOURCE_TYPE(IncubatorType)
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;
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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)
{
Expand All @@ -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
18 changes: 17 additions & 1 deletion src/declarative/qml/qdeclarativeincubator.cpp
Expand Up @@ -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;
Expand All @@ -143,7 +144,6 @@ void QDeclarativeIncubatorPrivate::clear()
nextWaitingFor.remove();
waitingOnMe = 0;
}

}

/*!
Expand Down Expand Up @@ -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;
}

/*!
Expand Down
2 changes: 1 addition & 1 deletion src/declarative/qml/qdeclarativeincubator_p.h
Expand Up @@ -63,7 +63,6 @@ class QDeclarativeCompiledData;
class QDeclarativeIncubator;
class QDeclarativeIncubatorPrivate : public QDeclarativeEnginePrivate::Incubator
{
QIntrusiveListNode nextWaitingFor;
public:
QDeclarativeIncubatorPrivate(QDeclarativeIncubator *q, QDeclarativeIncubator::IncubationMode m);
~QDeclarativeIncubatorPrivate();
Expand All @@ -83,6 +82,7 @@ class QDeclarativeIncubatorPrivate : public QDeclarativeEnginePrivate::Incubator

typedef QDeclarativeIncubatorPrivate QIP;
QIP *waitingOnMe;
QIntrusiveListNode nextWaitingFor;
QIntrusiveList<QIP, &QIP::nextWaitingFor> waitingFor;

void clear();
Expand Down
2 changes: 2 additions & 0 deletions src/declarative/qml/v8/qv8engine.cpp
Expand Up @@ -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));
Expand Down

0 comments on commit d3ecdc4

Please sign in to comment.