diff options
Diffstat (limited to 'src/qml/qml/qqmlobjectcreator.cpp')
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 207 |
1 files changed, 128 insertions, 79 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index d009536767..36e56a01f8 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -82,13 +82,13 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::Compil { init(parentContext); - sharedState->componentAttached = 0; + sharedState->componentAttached = nullptr; sharedState->allCreatedBindings.allocate(compilationUnit->totalBindingsCount); sharedState->allParserStatusCallbacks.allocate(compilationUnit->totalParserStatusCount); sharedState->allCreatedObjects.allocate(compilationUnit->totalObjectCount); - sharedState->allJavaScriptObjects = 0; + sharedState->allJavaScriptObjects = nullptr; sharedState->creationContext = creationContext; - sharedState->rootContext = 0; + sharedState->rootContext = nullptr; if (auto profiler = QQmlEnginePrivate::get(engine)->profiler) { Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler, @@ -105,7 +105,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::Compil , propertyCaches(&compilationUnit->propertyCaches) , sharedState(inheritedSharedState) , topLevelCreator(false) - , incubator(0) + , incubator(nullptr) { init(parentContext); } @@ -114,23 +114,23 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext) { parentContext = providedParentContext; engine = parentContext->engine; - v4 = QV8Engine::getV4(engine); + v4 = engine->handle(); if (compilationUnit && !compilationUnit->engine) compilationUnit->linkToEngine(v4); qmlUnit = compilationUnit->data; - context = 0; - _qobject = 0; - _scopeObject = 0; - _bindingTarget = 0; - _valueTypeProperty = 0; - _compiledObject = 0; + context = nullptr; + _qobject = nullptr; + _scopeObject = nullptr; + _bindingTarget = nullptr; + _valueTypeProperty = nullptr; + _compiledObject = nullptr; _compiledObjectIndex = -1; - _ddata = 0; - _propertyCache = 0; - _vmeMetaObject = 0; - _qmlContext = 0; + _ddata = nullptr; + _propertyCache = nullptr; + _vmeMetaObject = nullptr; + _qmlContext = nullptr; } QQmlObjectCreator::~QQmlObjectCreator() @@ -142,7 +142,7 @@ QQmlObjectCreator::~QQmlObjectCreator() for (int i = 0; i < sharedState->allParserStatusCallbacks.count(); ++i) { QQmlParserStatus *ps = sharedState->allParserStatusCallbacks.at(i); if (ps) - ps->d = 0; + ps->d = nullptr; } while (sharedState->componentAttached) { QQmlComponentAttached *a = sharedState->componentAttached; @@ -203,19 +203,16 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI if (instance) { QQmlData *ddata = QQmlData::get(instance); Q_ASSERT(ddata); - if (ddata->compilationUnit) - ddata->compilationUnit->release(); ddata->compilationUnit = compilationUnit; - ddata->compilationUnit->addref(); } if (topLevelCreator) - sharedState->allJavaScriptObjects = 0; + sharedState->allJavaScriptObjects = nullptr; phase = CreatingObjectsPhase2; if (interrupt && interrupt->shouldInterrupt()) - return 0; + return nullptr; phase = ObjectsCreated; @@ -233,6 +230,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI return instance; } +// ### unify or keep in sync with populateDeferredBinding() bool QQmlObjectCreator::populateDeferredProperties(QObject *instance, QQmlData::DeferredData *deferredData) { QQmlData *declarativeData = QQmlData::get(instance); @@ -283,6 +281,80 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance, QQmlData:: qSwap(_qmlContext, qmlContext); qSwap(_scopeObject, scopeObject); + deferredData->bindings.clear(); + phase = ObjectsCreated; + + return errors.isEmpty(); +} + +// ### unify or keep in sync with populateDeferredProperties() +bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty, QQmlData::DeferredData *deferredData, const QV4::CompiledData::Binding *binding) +{ + Q_ASSERT(binding->flags & QV4::CompiledData::Binding::IsDeferredBinding); + + QObject *instance = qmlProperty.object(); + QQmlData *declarativeData = QQmlData::get(instance); + context = deferredData->context; + sharedState->rootContext = context; + + QObject *bindingTarget = instance; + + QQmlRefPointer<QQmlPropertyCache> cache = declarativeData->propertyCache; + QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(instance); + + QObject *scopeObject = instance; + qSwap(_scopeObject, scopeObject); + + QV4::Scope valueScope(v4); + + Q_ASSERT(topLevelCreator); + if (!sharedState->allJavaScriptObjects) + sharedState->allJavaScriptObjects = valueScope.alloc(compilationUnit->totalObjectCount); + + QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc(1)); + + qSwap(_qmlContext, qmlContext); + + qSwap(_propertyCache, cache); + qSwap(_qobject, instance); + + int objectIndex = deferredData->deferredIdx; + qSwap(_compiledObjectIndex, objectIndex); + + const QV4::CompiledData::Object *obj = qmlUnit->objectAt(_compiledObjectIndex); + qSwap(_compiledObject, obj); + + qSwap(_ddata, declarativeData); + qSwap(_bindingTarget, bindingTarget); + qSwap(_vmeMetaObject, vmeMetaObject); + + QQmlListProperty<void> savedList; + qSwap(_currentList, savedList); + + const QQmlPropertyData &property = QQmlPropertyPrivate::get(qmlProperty)->core; + + if (property.isQList()) { + void *argv[1] = { (void*)&_currentList }; + QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property.coreIndex(), argv); + } else if (_currentList.object) { + _currentList = QQmlListProperty<void>(); + } + + setPropertyBinding(&property, binding); + + qSwap(_currentList, savedList); + + qSwap(_vmeMetaObject, vmeMetaObject); + qSwap(_bindingTarget, bindingTarget); + qSwap(_ddata, declarativeData); + qSwap(_compiledObject, obj); + qSwap(_compiledObjectIndex, objectIndex); + qSwap(_qobject, instance); + qSwap(_propertyCache, cache); + + qSwap(_qmlContext, qmlContext); + qSwap(_scopeObject, scopeObject); + phase = ObjectsCreated; return errors.isEmpty(); @@ -370,7 +442,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const QString string = binding->valueAsString(qmlUnit); // Encoded dir-separators defeat QUrl processing - decode them first string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive); - QUrl value = string.isEmpty() ? QUrl() : compilationUnit->url().resolved(QUrl(string)); + QUrl value = string.isEmpty() ? QUrl() : compilationUnit->finalUrl().resolved(QUrl(string)); // Apply URL interceptor if (engine->urlInterceptor()) value = engine->urlInterceptor()->intercept(value, QQmlAbstractUrlInterceptor::UrlString); @@ -568,7 +640,8 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const } else if (property->propType() == qMetaTypeId<QList<QUrl> >()) { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String); QString urlString = binding->valueAsString(qmlUnit); - QUrl u = urlString.isEmpty() ? QUrl() : compilationUnit->url().resolved(QUrl(urlString)); + QUrl u = urlString.isEmpty() ? QUrl() + : compilationUnit->finalUrl().resolved(QUrl(urlString)); QList<QUrl> value; value.append(u); property->writeProperty(_qobject, &value, propertyWriteFlags); @@ -723,7 +796,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con } const int id = attachedType.attachedPropertiesId(QQmlEnginePrivate::get(engine)); QObject *qmlObject = qmlAttachedPropertiesObjectById(id, _qobject); - if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject, /*value type property*/0)) + if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject, /*value type property*/nullptr)) return false; return true; } @@ -741,12 +814,12 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite; int propertyWriteStatus = -1; - void *argv[] = { &ss, 0, &propertyWriteStatus, &propertyWriteFlags }; + void *argv[] = { &ss, nullptr, &propertyWriteStatus, &propertyWriteFlags }; QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex(), argv); return true; } - QObject *createdSubObject = 0; + QObject *createdSubObject = nullptr; if (binding->type == QV4::CompiledData::Binding::Type_Object) { createdSubObject = createInstance(binding->value.objectIndex, _bindingTarget); if (!createdSubObject) @@ -760,9 +833,9 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con const QV4::CompiledData::Object *obj = qmlUnit->objectAt(binding->value.objectIndex); if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) { - QObject *groupObject = 0; - QQmlValueType *valueType = 0; - const QQmlPropertyData *valueTypeProperty = 0; + QObject *groupObject = nullptr; + QQmlValueType *valueType = nullptr; + const QQmlPropertyData *valueTypeProperty = nullptr; QObject *bindingTarget = _bindingTarget; if (QQmlValueTypeFactory::isValueType(property->propType())) { @@ -935,7 +1008,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite; int propertyWriteStatus = -1; - void *argv[] = { 0, 0, &propertyWriteStatus, &propertyWriteFlags }; + void *argv[] = { nullptr, nullptr, &propertyWriteStatus, &propertyWriteFlags }; if (const char *iid = QQmlMetaType::interfaceIId(property->propType())) { void *ptr = createdSubObject->qt_metacast(iid); @@ -949,7 +1022,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con } else if (property->propType() == QMetaType::QVariant) { if (property->isVarProperty()) { QV4::Scope scope(v4); - QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), createdSubObject)); + QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(engine->handle(), createdSubObject)); _vmeMetaObject->setVMEProperty(property->coreIndex(), wrappedObject); } else { QVariant value = QVariant::fromValue(createdSubObject); @@ -961,7 +1034,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con void *itemToAdd = createdSubObject; - const char *iid = 0; + const char *iid = nullptr; int listItemType = QQmlEnginePrivate::get(engine)->listType(property->propType()); if (listItemType != -1) iid = QQmlMetaType::interfaceIId(listItemType); @@ -1028,12 +1101,9 @@ void QQmlObjectCreator::registerObjectWithContextById(const QV4::CompiledData::O context->setIdProperty(object->id, instance); } -QV4::QmlContext *QQmlObjectCreator::currentQmlContext() +void QQmlObjectCreator::createQmlContext() { - if (!_qmlContext->isManaged()) - _qmlContext->setM(QV4::QmlContext::create(v4->rootContext(), context, _scopeObject)); - - return _qmlContext; + _qmlContext->setM(QV4::QmlContext::create(v4->rootContext(), context, _scopeObject)); } QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject) @@ -1044,10 +1114,10 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine)); bool isComponent = false; - QObject *instance = 0; - QQmlData *ddata = 0; - QQmlCustomParser *customParser = 0; - QQmlParserStatus *parserStatus = 0; + QObject *instance = nullptr; + QQmlData *ddata = nullptr; + QQmlCustomParser *customParser = nullptr; + QQmlParserStatus *parserStatus = nullptr; bool installPropertyCache = true; if (obj->flags & QV4::CompiledData::Object::IsComponent) { @@ -1067,11 +1137,11 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo Q_QML_OC_PROFILE(sharedState->profiler, profiler.update( compilationUnit, obj, type.qmlTypeName(), context->url())); - void *ddataMemory = 0; + void *ddataMemory = nullptr; type.create(&instance, &ddataMemory, sizeof(QQmlData)); if (!instance) { recordError(obj->location, tr("Unable to create object of type %1").arg(stringAt(obj->inheritedTypeNameIndex))); - return 0; + return nullptr; } { @@ -1103,14 +1173,14 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (typeRef->compilationUnit->data->isSingleton()) { recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex))); - return 0; + return nullptr; } QQmlObjectCreator subCreator(context, typeRef->compilationUnit, sharedState.data()); instance = subCreator.create(); if (!instance) { errors += subCreator.errors; - return 0; + return nullptr; } } if (instance->isWidgetType()) { @@ -1174,8 +1244,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo } customParser->applyBindings(instance, compilationUnit, bindings); - customParser->engine = 0; - customParser->imports = (QQmlTypeNameCache*)0; + customParser->engine = nullptr; + customParser->imports = (QQmlTypeNameCache*)nullptr; } if (isComponent) { @@ -1204,12 +1274,12 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo qSwap(_qmlContext, qmlContext); - bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/0); + bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/nullptr); qSwap(_qmlContext, qmlContext); qSwap(_scopeObject, scopeObject); - return result ? instance : 0; + return result ? instance : nullptr; } QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt) @@ -1233,7 +1303,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru QQmlPropertyData::DontRemoveBinding); if (watcher.hasRecursed() || interrupt.shouldInterrupt()) - return 0; + return nullptr; } if (QQmlVME::componentCompleteEnabled()) { // the qml designer does the component complete later @@ -1242,12 +1312,12 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru QQmlParserStatus *status = sharedState->allParserStatusCallbacks.pop(); if (status && status->d) { - status->d = 0; + status->d = nullptr; status->componentComplete(); } if (watcher.hasRecursed() || interrupt.shouldInterrupt()) - return 0; + return nullptr; } } @@ -1255,11 +1325,11 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru QQmlEnginePrivate::FinalizeCallback callback = sharedState->finalizeCallbacks.at(ii); QObject *obj = callback.first; if (obj) { - void *args[] = { 0 }; + void *args[] = { nullptr }; QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, callback.second, args); } if (watcher.hasRecursed()) - return 0; + return nullptr; } sharedState->finalizeCallbacks.clear(); @@ -1274,7 +1344,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru emit a->completed(); if (watcher.hasRecursed() || interrupt.shouldInterrupt()) - return 0; + return nullptr; } phase = Done; @@ -1282,21 +1352,6 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru return sharedState->rootContext; } -void QQmlObjectCreator::cancel(QObject *object) -{ - int last = sharedState->allCreatedObjects.count() - 1; - int i = last; - while (i >= 0) { - if (sharedState->allCreatedObjects.at(i) == object) { - if (i < last) - qSwap(sharedState->allCreatedObjects[i], sharedState->allCreatedObjects[last]); - sharedState->allCreatedObjects.pop(); - break; - } - --i; - } -} - void QQmlObjectCreator::clear() { if (phase == Done || phase == Finalizing || phase == Startup) @@ -1331,7 +1386,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches->at(_compiledObjectIndex); - QQmlVMEMetaObject *vmeMetaObject = 0; + QQmlVMEMetaObject *vmeMetaObject = nullptr; if (propertyCaches->needsVMEMetaObject(_compiledObjectIndex)) { Q_ASSERT(!cache.isNull()); // install on _object @@ -1350,14 +1405,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * qSwap(_propertyCache, cache); qSwap(_vmeMetaObject, vmeMetaObject); - if (_compiledObject->flags & QV4::CompiledData::Object::HasDeferredBindings) { - QQmlData::DeferredData *deferData = new QQmlData::DeferredData; - deferData->deferredIdx = _compiledObjectIndex; - deferData->compilationUnit = compilationUnit; - deferData->compilationUnit->addref(); - deferData->context = context; - _ddata->deferredData.append(deferData); - } + if (_compiledObject->flags & QV4::CompiledData::Object::HasDeferredBindings) + _ddata->deferData(_compiledObjectIndex, compilationUnit, context); if (_compiledObject->nFunctions > 0) setupFunctions(); |