diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 36 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent_p.h | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmldata_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 27 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 2 |
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(); |