aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-09-14 14:41:18 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-20 14:26:20 +0200
commit269e29fdf36dd700d8c985dc7f11dbb5c8746c51 (patch)
treedde17b25e0111dcf3e6783f1ab07982a247b35e7 /src
parentb4b4a646800fabbb31b4b261ea4b802d78d6501f (diff)
[new compiler] Add support for finalization callbacks
This is needed for Component.onCompleted (the signal emission) as well as the private finalization callback API in QQmlEngine, used by QtQuick. The creator - similar to the VME - tracks the attached properties object of QQmlComponent through a linked list. Change-Id: I8ada94009a7ce2078feefd359485657626c300fb Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/qqmlcomponent.cpp8
-rw-r--r--src/qml/qml/qqmlengine.cpp3
-rw-r--r--src/qml/qml/qqmlengine_p.h5
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp41
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h5
5 files changed, 58 insertions, 4 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 2063c5bb25..649cb6ccc8 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -973,7 +973,7 @@ void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionS
{
if (state->completePending) {
if (enginePriv->useNewCompiler) {
- // ###
+ state->creator->finalize();
} else {
state->vme.complete();
}
@@ -1049,9 +1049,11 @@ QQmlComponentAttached *QQmlComponent::qmlAttachedProperties(QObject *obj)
if (!engine)
return a;
- if (QQmlEnginePrivate::get(engine)->activeVME) { // XXX should only be allowed during begin
- QQmlEnginePrivate *p = QQmlEnginePrivate::get(engine);
+ QQmlEnginePrivate *p = QQmlEnginePrivate::get(engine);
+ if (p->activeVME) { // XXX should only be allowed during begin
a->add(&p->activeVME->componentAttached);
+ } else if (p->activeObjectCreator) {
+ a->add(&p->activeObjectCreator->componentAttached);
} else {
QQmlData *d = QQmlData::get(obj);
Q_ASSERT(d);
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index a2c190d0e6..afb993499d 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -554,6 +554,7 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
outputWarningsToStdErr(true),
cleanup(0), erroredBindings(0), inProgressCreations(0),
workerScriptEngine(0), activeVME(0),
+ activeObjectCreator(0),
networkAccessManager(0), networkAccessManagerFactory(0), urlInterceptor(0),
scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
incubatorCount(0), incubationController(0), mutex(QMutex::Recursive)
@@ -1030,6 +1031,8 @@ void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index)
{
if (activeVME) {
activeVME->finalizeCallbacks.append(qMakePair(QPointer<QObject>(obj), index));
+ } else if (activeObjectCreator) {
+ activeObjectCreator->finalizeCallbacks.append(qMakePair(QPointer<QObject>(obj), index));
} else {
void *args[] = { 0 };
QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, index, args);
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index b57c84ceae..c67e45a833 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -99,6 +99,7 @@ class QQmlCleanup;
class QQmlDelayedError;
class QQuickWorkerScriptEngine;
class QQmlVME;
+class QmlObjectCreator;
class QDir;
class QQmlIncubator;
@@ -166,7 +167,11 @@ public:
typedef QPair<QPointer<QObject>,int> FinalizeCallback;
void registerFinalizeCallback(QObject *obj, int index);
+ // --- old compiler:
QQmlVME *activeVME;
+ // --- new compiler:
+ QmlObjectCreator *activeObjectCreator;
+ // ---
QNetworkAccessManager *createNetworkAccessManager(QObject *parent) const;
QNetworkAccessManager *getNetworkAccessManager() const;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 8ed3a13b77..2272977128 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -50,9 +50,23 @@
#include <private/qqmlbinding_p.h>
#include <private/qqmlstringconverters_p.h>
#include <private/qqmlboundsignal_p.h>
+#include <private/qqmltrace_p.h>
+#include <private/qqmlcomponentattached_p.h>
QT_USE_NAMESPACE
+namespace {
+struct ActiveOCRestorer
+{
+ ActiveOCRestorer(QmlObjectCreator *creator, QQmlEnginePrivate *ep)
+ : ep(ep), oldCreator(ep->activeObjectCreator) { ep->activeObjectCreator = creator; }
+ ~ActiveOCRestorer() { ep->activeObjectCreator = oldCreator; }
+
+ QQmlEnginePrivate *ep;
+ QmlObjectCreator *oldCreator;
+};
+}
+
#define COMPILE_EXCEPTION(token, desc) \
{ \
recordError((token)->location, desc); \
@@ -448,7 +462,8 @@ QmlObjectCreator::QmlObjectCreator(QQmlContextData *contextData, const QV4::Comp
const QHash<int, QQmlCompiledData::TypeReference> &resolvedTypes,
const QList<QQmlPropertyCache*> &propertyCaches,
const QList<QByteArray> &vmeMetaObjectData, const QHash<int, int> &objectIndexToId)
- : engine(contextData->engine)
+ : componentAttached(0)
+ , engine(contextData->engine)
, unit(qmlUnit)
, jsUnit(jsUnit)
, context(contextData)
@@ -585,6 +600,8 @@ void QmlObjectCreator::setupFunctions(QV4::ExecutionContext *qmlContext)
QObject *QmlObjectCreator::create(int index, QObject *parent)
{
+ ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
+
const QV4::CompiledData::Object *obj = unit->objectAt(index);
QQmlType *type = resolvedTypes.value(obj->inheritedTypeNameIndex).type;
@@ -609,6 +626,28 @@ QObject *QmlObjectCreator::create(int index, QObject *parent)
return instance;
}
+void QmlObjectCreator::finalize()
+{
+ {
+ QQmlTrace trace("VME Component.onCompleted Callbacks");
+ while (componentAttached) {
+ QQmlComponentAttached *a = componentAttached;
+ a->rem();
+ QQmlData *d = QQmlData::get(a->parent());
+ Q_ASSERT(d);
+ Q_ASSERT(d->context);
+ a->add(&d->context->componentAttached);
+ // ### designer if (componentCompleteEnabled())
+ emit a->completed();
+
+#if 0 // ###
+ if (watcher.hasRecursed() || interrupt.shouldInterrupt())
+ return 0;
+#endif
+ }
+ }
+}
+
void QmlObjectCreator::populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache)
{
const QV4::CompiledData::Object *obj = unit->objectAt(index);
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 8aa037755f..3a3ea9251d 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -85,8 +85,13 @@ public:
{ return create(unit->indexOfRootObject, parent); }
QObject *create(int index, QObject *parent = 0);
+ void finalize();
+
QList<QQmlError> errors;
+ QQmlComponentAttached *componentAttached;
+ QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
+
private:
void populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache);