aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlobjectcreator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlobjectcreator.cpp')
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp207
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();