aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/qqmlcomponent.cpp36
-rw-r--r--src/qml/qml/qqmlcomponent_p.h13
-rw-r--r--src/qml/qml/qqmldata_p.h5
-rw-r--r--src/qml/qml/qqmlengine.cpp27
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp8
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h2
6 files changed, 60 insertions, 31 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index ce35846c88..7f1121c1e1 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -878,19 +878,33 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
}
void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv,
- QObject *object, ConstructionState *state)
+ QObject *object, DeferredState *deferredState)
{
- enginePriv->inProgressCreations++;
- state->errors.clear();
- state->completePending = true;
-
QQmlData *ddata = QQmlData::get(object);
- Q_ASSERT(ddata->deferredData);
- QQmlData::DeferredData *deferredData = ddata->deferredData;
- QQmlContextData *creationContext = 0;
- state->creator.reset(new QQmlObjectCreator(deferredData->context->parent, deferredData->compilationUnit, creationContext));
- if (!state->creator->populateDeferredProperties(object))
- state->errors << state->creator->errors;
+ Q_ASSERT(!ddata->deferredData.isEmpty());
+
+ deferredState->constructionStates.reserve(ddata->deferredData.size());
+
+ for (QQmlData::DeferredData *deferredData : qAsConst(ddata->deferredData)) {
+ enginePriv->inProgressCreations++;
+
+ ConstructionState *state = new ConstructionState;
+ state->completePending = true;
+
+ QQmlContextData *creationContext = nullptr;
+ state->creator.reset(new QQmlObjectCreator(deferredData->context->parent, deferredData->compilationUnit, creationContext));
+
+ if (!state->creator->populateDeferredProperties(object, deferredData))
+ state->errors << state->creator->errors;
+
+ deferredState->constructionStates += state;
+ }
+}
+
+void QQmlComponentPrivate::completeDeferred(QQmlEnginePrivate *enginePriv, QQmlComponentPrivate::DeferredState *deferredState)
+{
+ for (ConstructionState *state : qAsConst(deferredState->constructionStates))
+ complete(enginePriv, state);
}
void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionState *state)
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index d01a987acc..2a57f7b247 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -114,8 +114,17 @@ public:
};
ConstructionState state;
- static void beginDeferred(QQmlEnginePrivate *enginePriv, QObject *object,
- ConstructionState *state);
+ struct DeferredState {
+ ~DeferredState() {
+ qDeleteAll(constructionStates);
+ constructionStates.clear();
+ }
+ QVector<ConstructionState *> constructionStates;
+ };
+
+ static void beginDeferred(QQmlEnginePrivate *enginePriv, QObject *object, DeferredState* deferredState);
+ static void completeDeferred(QQmlEnginePrivate *enginePriv, DeferredState *deferredState);
+
static void complete(QQmlEnginePrivate *enginePriv, ConstructionState *state);
QQmlEngine *engine;
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index 75ea720358..d692feb975 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -57,6 +57,7 @@
#include <private/qv4value_p.h>
#include <private/qv4persistent_p.h>
#include <qjsengine.h>
+#include <qvector.h>
QT_BEGIN_NAMESPACE
@@ -219,7 +220,9 @@ public:
QQmlContextData *context;//Could be either context or outerContext
};
QV4::CompiledData::CompilationUnit *compilationUnit;
- DeferredData *deferredData;
+ QVector<DeferredData *> deferredData;
+
+ void releaseDeferredData();
QV4::WeakValue jsWrapper;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 13b17e6946..5a52224208 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -739,7 +739,7 @@ QQmlData::QQmlData()
hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false),
bindingBitsSize(MaxInlineBits), bindingBitsValue(0), notifyList(0),
bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0),
- lineNumber(0), columnNumber(0), jsEngineId(0), compilationUnit(0), deferredData(0),
+ lineNumber(0), columnNumber(0), jsEngineId(0), compilationUnit(0),
propertyCache(0), guards(0), extendedData(0)
{
init();
@@ -1469,18 +1469,16 @@ void qmlExecuteDeferred(QObject *object)
{
QQmlData *data = QQmlData::get(object);
- if (data && data->deferredData && !data->wasDeleted(object)) {
+ if (data && !data->deferredData.isEmpty() && !data->wasDeleted(object)) {
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine);
- QQmlComponentPrivate::ConstructionState state;
+ QQmlComponentPrivate::DeferredState state;
QQmlComponentPrivate::beginDeferred(ep, object, &state);
// Release the reference for the deferral action (we still have one from construction)
- data->deferredData->compilationUnit->release();
- delete data->deferredData;
- data->deferredData = 0;
+ data->releaseDeferredData();
- QQmlComponentPrivate::complete(ep, &state);
+ QQmlComponentPrivate::completeDeferred(ep, &state);
}
}
@@ -1638,6 +1636,15 @@ void QQmlData::NotifyList::layout()
todo = 0;
}
+void QQmlData::releaseDeferredData()
+{
+ for (DeferredData *deferData : qAsConst(deferredData)) {
+ deferData->compilationUnit->release();
+ delete deferData;
+ }
+ deferredData.clear();
+}
+
void QQmlData::addNotify(int index, QQmlNotifierEndpoint *endpoint)
{
if (!notifyList) {
@@ -1712,11 +1719,7 @@ void QQmlData::destroyed(QObject *object)
compilationUnit = 0;
}
- if (deferredData) {
- deferredData->compilationUnit->release();
- delete deferredData;
- deferredData = 0;
- }
+ releaseDeferredData();
QQmlBoundSignal *signalHandler = signalHandlers;
while (signalHandler) {
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 07a90d4d63..b2f1421bcb 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -233,10 +233,10 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
return instance;
}
-bool QQmlObjectCreator::populateDeferredProperties(QObject *instance)
+bool QQmlObjectCreator::populateDeferredProperties(QObject *instance, QQmlData::DeferredData *deferredData)
{
QQmlData *declarativeData = QQmlData::get(instance);
- context = declarativeData->deferredData->context;
+ context = deferredData->context;
sharedState->rootContext = context;
QObject *bindingTarget = instance;
@@ -260,7 +260,7 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance)
qSwap(_propertyCache, cache);
qSwap(_qobject, instance);
- int objectIndex = declarativeData->deferredData->deferredIdx;
+ int objectIndex = deferredData->deferredIdx;
qSwap(_compiledObjectIndex, objectIndex);
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(_compiledObjectIndex);
@@ -1347,7 +1347,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
deferData->compilationUnit = compilationUnit;
deferData->compilationUnit->addref();
deferData->context = context;
- _ddata->deferredData = deferData;
+ _ddata->deferredData.append(deferData);
}
if (_compiledObject->nFunctions > 0)
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index a62825e19e..0c2d427c58 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -89,7 +89,7 @@ public:
~QQmlObjectCreator();
QObject *create(int subComponentIndex = -1, QObject *parent = 0, QQmlInstantiationInterrupt *interrupt = 0);
- bool populateDeferredProperties(QObject *instance);
+ bool populateDeferredProperties(QObject *instance, QQmlData::DeferredData *deferredData);
QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
void cancel(QObject *object);
void clear();