diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/declarative/qml/qmlbasicscript.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 6 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext.cpp | 68 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext_p.h | 18 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 62 | ||||
-rw-r--r-- | src/declarative/qml/qmlinstruction_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlvme.cpp | 8 |
8 files changed, 78 insertions, 91 deletions
diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp index b940d61..ca137c7 100644 --- a/src/declarative/qml/qmlbasicscript.cpp +++ b/src/declarative/qml/qmlbasicscript.cpp @@ -668,7 +668,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c switch(instr.type) { case ScriptInstruction::LoadIdObject: { - stack.push(contextPrivate->propertyValues.at(instr.fetch.idx)); + stack.push(QVariant::fromValue(contextPrivate->idValues[instr.fetch.idx].data())); enginePrivate->capturedProperties << QmlEnginePrivate::CapturedProperty(context, -1, contextPrivate->notifyIndex + instr.fetch.idx); state = Reset; diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 091b7bb..197bd44 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -603,6 +603,7 @@ void QmlCompiler::compileTree(Object *tree) init.line = 0; init.init.bindingsSize = compileState.bindings.count(); init.init.parserStatusSize = compileState.parserStatusCount; + init.init.idSize = compileState.ids.count(); output->bytecode << init; genObject(tree); @@ -774,6 +775,7 @@ void QmlCompiler::genObject(QmlParser::Object *obj) id.type = QmlInstruction::SetId; id.line = -1; id.setId.value = output->indexForString(obj->id); + id.setId.index = obj->idIndex; output->bytecode << id; } @@ -917,6 +919,7 @@ void QmlCompiler::genComponent(QmlParser::Object *obj) init.type = QmlInstruction::Init; init.init.bindingsSize = compileState.bindings.count(); init.init.parserStatusSize = compileState.parserStatusCount; + init.init.idSize = compileState.ids.count(); init.line = obj->location.start.line; output->bytecode << init; @@ -936,7 +939,8 @@ void QmlCompiler::genComponent(QmlParser::Object *obj) QmlInstruction id; id.type = QmlInstruction::SetId; id.line = -1; - id.setId.value = output->indexForString(obj->id);; + id.setId.value = output->indexForString(obj->id); + id.setId.index = obj->idIndex; output->bytecode << id; } } diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index f347cf3..fd64a95 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -55,7 +55,8 @@ QT_BEGIN_NAMESPACE QmlContextPrivate::QmlContextPrivate() : parent(0), engine(0), isInternal(false), notifyIndex(-1), - highPriorityCount(0), startLine(-1), endLine(-1) + highPriorityCount(0), startLine(-1), endLine(-1), idValues(0), + idValueCount(0) { } @@ -71,29 +72,21 @@ void QmlContextPrivate::dump(int depth) parent->d_func()->dump(depth + 1); } -void QmlContextPrivate::destroyed(QObject *obj) +void QmlContextPrivate::destroyed(ContextGuard *guard) { Q_Q(QmlContext); - defaultObjects.removeAll(obj); - - QVariant variantObject = QVariant::fromValue(obj); - QVarLengthArray<int> notifies; - for (int ii = 0; ii < propertyValues.count(); ++ii) { - if (propertyValues.at(ii) == variantObject) { - propertyValues[ii] = QVariant(); - notifies.append(ii); - } - } - - // There is no need to emit these notifications if our parent is in the // process of being deleted (which is *probably* why obj has been destroyed // anyway), as we're about to get deleted which will invalidate all the // expressions that could depend on us QObject *parent = q->parent(); - if (!parent || !QObjectPrivate::get(parent)->wasDeleted) { - for (int ii = 0; ii < notifies.count(); ++ii) { - QMetaObject::activate(q, notifies[ii] + notifyIndex, 0); + if (parent && QObjectPrivate::get(parent)->wasDeleted) + return; + + for (int ii = 0; ii < idValueCount; ++ii) { + if (&idValues[ii] == guard) { + QMetaObject::activate(q, ii + notifyIndex, 0); + return; } } } @@ -131,8 +124,6 @@ void QmlContextPrivate::addDefaultObject(QObject *object, Priority priority) } else { defaultObjects.append(object); } - QObject::connect(object, SIGNAL(destroyed(QObject*)), - q_ptr, SLOT(objectDestroyed(QObject*))); } @@ -306,6 +297,8 @@ QmlContext::~QmlContext() } } d->contextObjects.clear(); + + delete [] d->idValues; } void QmlContextPrivate::invalidateEngines() @@ -365,7 +358,7 @@ void QmlContext::setContextProperty(const QString &name, const QVariant &value) } else { QHash<QString, int>::ConstIterator iter = d->propertyNames.find(name); if(iter == d->propertyNames.end()) { - d->propertyNames.insert(name, d->propertyValues.count()); + d->propertyNames.insert(name, d->idValueCount + d->propertyValues.count()); d->propertyValues.append(value); } else { d->propertyValues[*iter] = value; @@ -374,6 +367,25 @@ void QmlContext::setContextProperty(const QString &name, const QVariant &value) } } +void QmlContextPrivate::setIdProperty(const QString &name, int idx, + QObject *obj) +{ + if (notifyIndex == -1) { + Q_Q(QmlContext); + notifyIndex = q->metaObject()->methodCount(); + } + + propertyNames.insert(name, idx); + idValues[idx].priv = this; + idValues[idx] = obj; +} + +void QmlContextPrivate::setIdPropertyCount(int count) +{ + idValues = new ContextGuard[count]; + idValueCount = count; +} + /*! Set a the \a value of the \a name property on this context. @@ -385,20 +397,12 @@ void QmlContext::setContextProperty(const QString &name, QObject *value) if (d->notifyIndex == -1) d->notifyIndex = this->metaObject()->methodCount(); - QObject::connect(value, SIGNAL(destroyed(QObject*)), - this, SLOT(objectDestroyed(QObject*))); - QHash<QString, int>::ConstIterator iter = d->propertyNames.find(name); if(iter == d->propertyNames.end()) { - d->propertyNames.insert(name, d->propertyValues.count()); + d->propertyNames.insert(name, d->idValueCount + d->propertyValues.count()); d->propertyValues.append(QVariant::fromValue(value)); } else { int idx = *iter; - if (QmlMetaType::isObject(d->propertyValues.at(idx).userType())) { - QObject *old = QmlMetaType::toQObject(d->propertyValues.at(idx)); - QObject::disconnect(old, SIGNAL(destroyed(QObject*)), - this, SLOT(objectDestroyed(QObject*))); - } d->propertyValues[*iter] = QVariant::fromValue(value); QMetaObject::activate(this, *iter + d->notifyIndex, 0); } @@ -445,10 +449,4 @@ void QmlContext::setBaseUrl(const QUrl &baseUrl) d_func()->url = baseUrl; } -void QmlContext::objectDestroyed(QObject *object) -{ - Q_D(QmlContext); - d->destroyed(object); -} - QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlcontext.h b/src/declarative/qml/qmlcontext.h index 877ff0f..1f29ca2 100644 --- a/src/declarative/qml/qmlcontext.h +++ b/src/declarative/qml/qmlcontext.h @@ -77,9 +77,6 @@ public: void setBaseUrl(const QUrl &); -private Q_SLOTS: - void objectDestroyed(QObject *); - private: friend class QmlVME; friend class QmlEngine; diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h index fc615b6..5bb3aaf 100644 --- a/src/declarative/qml/qmlcontext_p.h +++ b/src/declarative/qml/qmlcontext_p.h @@ -59,6 +59,7 @@ #include <QtCore/qhash.h> #include <QtScript/qscriptvalue.h> #include <QtCore/qset.h> +#include <private/qguard_p.h> QT_BEGIN_NAMESPACE @@ -96,8 +97,6 @@ public: void dump(); void dump(int depth); - void destroyed(QObject *); - enum Priority { HighPriority, NormalPriority @@ -111,6 +110,21 @@ public: QmlSimpleDeclarativeData contextData; QObjectList contextObjects; + + struct ContextGuard : public QGuard<QObject> + { + QmlContextPrivate *priv; + ContextGuard &operator=(QObject *obj) { + (QGuard<QObject>&)*this = obj; return *this; + } + void objectDestroyed(QObject *o) { priv->destroyed(this); } + }; + ContextGuard *idValues; + int idValueCount; + void setIdProperty(const QString &, int, QObject *); + void setIdPropertyCount(int); + void destroyed(ContextGuard *); + // Only used for debugging QList<QPointer<QObject> > instances; }; diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index f6d70e0..68ad655 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -747,10 +747,6 @@ QmlContextScriptClass::queryProperty(const QScriptValue &object, QString propName = name.toString(); -#ifdef PROPERTY_DEBUG - qWarning() << "Query Context:" << propName << bindContext; -#endif - *id = InvalidId; if (bindContext->d_func()->propertyNames.contains(propName)) { rv |= HandlesReadAccess; @@ -767,17 +763,12 @@ QmlContextScriptClass::queryProperty(const QScriptValue &object, } QScriptValue QmlContextScriptClass::property(const QScriptValue &object, - const QScriptString &name, - uint id) + const QScriptString &name, + uint id) { QmlContext *bindContext = static_cast<QmlContext*>(object.data().toQObject()); -#ifdef PROPERTY_DEBUG - QString propName = name.toString(); - qWarning() << "Context Property:" << propName << bindContext; -#endif - uint basicId = id & QmlScriptClass::ClassIdMask; QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); @@ -786,18 +777,20 @@ QScriptValue QmlContextScriptClass::property(const QScriptValue &object, switch (basicId) { case VariantPropertyId: { + QmlContextPrivate *contextPrivate = bindContext->d_func(); QString propName = name.toString(); - int index = bindContext->d_func()->propertyNames.value(propName); - QVariant value = bindContext->d_func()->propertyValues.at(index); -#ifdef PROPERTY_DEBUG - qWarning() << "Context Property: Resolved property" << propName - << "to context variant property list" << bindContext <<". Value:" << rv.toVariant(); -#endif + int index = contextPrivate->propertyNames.value(propName); + QScriptValue rv; - if (QmlMetaType::isObject(value.userType())) { - rv = scriptEngine->newObject(ep->objectClass, scriptEngine->newVariant(value)); + if (index < contextPrivate->idValueCount) { + rv = scriptEngine->newObject(ep->objectClass, scriptEngine->newVariant(QVariant::fromValue(contextPrivate->idValues[index].data()))); } else { - rv = scriptEngine->newVariant(value); + QVariant value = contextPrivate->propertyValues.at(index); + if (QmlMetaType::isObject(value.userType())) { + rv = scriptEngine->newObject(ep->objectClass, scriptEngine->newVariant(value)); + } else { + rv = scriptEngine->newVariant(value); + } } ep->capturedProperties << QmlEnginePrivate::CapturedProperty(bindContext, -1, index + bindContext->d_func()->notifyIndex); return rv; @@ -809,10 +802,6 @@ QScriptValue QmlContextScriptClass::property(const QScriptValue &object, QScriptValue rv = ep->propertyObject(name, obj, id & ~QmlScriptClass::ClassIdSelectorMask); if (rv.isValid()) { -#ifdef PROPERTY_DEBUG - qWarning() << "~Property: Resolved property" << propName - << "to context default object" << bindContext << obj <<". Value:" << rv.toVariant(); -#endif return rv; } break; @@ -832,10 +821,6 @@ void QmlContextScriptClass::setProperty(QScriptValue &object, QmlContext *bindContext = static_cast<QmlContext*>(object.data().toQObject()); -#ifdef PROPERTY_DEBUG - QString propName = name.toString(); - qWarning() << "Set QmlObject Property" << name.toString() << value.toVariant(); -#endif int objIdx = (id & QmlScriptClass::ClassIdSelectorMask) >> 24; QObject *obj = bindContext->d_func()->defaultObjects.at(objIdx); @@ -975,10 +960,6 @@ QScriptClass::QueryFlags QmlObjectScriptClass::queryProperty(const QScriptValue QueryFlags rv = 0; QString propName = name.toString(); -#ifdef PROPERTY_DEBUG - qWarning() << "Query QmlObject:" << propName << obj; -#endif - if (obj) rv = QmlEnginePrivate::get(engine)->queryObject(propName, id, obj); @@ -991,20 +972,10 @@ QScriptValue QmlObjectScriptClass::property(const QScriptValue &object, { QObject *obj = object.data().toQObject(); -#ifdef PROPERTY_DEBUG - QString propName = name.toString(); - qWarning() << "QmlObject Property:" << propName << obj; -#endif - QScriptValue rv = QmlEnginePrivate::get(engine)->propertyObject(name, obj, id); - if (rv.isValid()) { -#ifdef PROPERTY_DEBUG - qWarning() << "~Property: Resolved property" << propName - << "to object" << obj <<". Value:" << rv.toVariant(); -#endif + if (rv.isValid()) return rv; - } return QScriptValue(); } @@ -1018,11 +989,6 @@ void QmlObjectScriptClass::setProperty(QScriptValue &object, QObject *obj = object.data().toQObject(); -#ifdef PROPERTY_DEBUG - QString propName = name.toString(); - qWarning() << "Set QmlObject Property" << name.toString() << value.toVariant(); -#endif - QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); QScriptValue oldact = scriptEngine->currentContext()->activationObject(); scriptEngine->currentContext()->setActivationObject(scriptEngine->globalObject()); diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h index d4fe68c..c3d676f 100644 --- a/src/declarative/qml/qmlinstruction_p.h +++ b/src/declarative/qml/qmlinstruction_p.h @@ -163,6 +163,7 @@ public: struct { int bindingsSize; int parserStatusSize; + int idSize; } init; struct { int type; @@ -175,6 +176,7 @@ public: } storeMeta; struct { int value; + int index; } setId; struct { int property; diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index ee41fe4..7c02548 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -64,6 +64,7 @@ #include <QtCore/qdebug.h> #include <QtCore/qvarlengtharray.h> #include <private/qmlbinding_p.h> +#include <private/qmlcontext_p.h> QT_BEGIN_NAMESPACE @@ -144,6 +145,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData vmeErrors.clear(); QmlEnginePrivate *ep = QmlEnginePrivate::get(ctxt->engine()); + QmlContextPrivate *cp = (QmlContextPrivate *)QObjectPrivate::get(ctxt); for (int ii = start; !isError() && ii < (start + count); ++ii) { QmlInstruction &instr = comp->bytecode[ii]; @@ -155,6 +157,9 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData bindValues = QmlEnginePrivate::SimpleList<QmlBinding>(instr.init.bindingsSize); if (instr.init.parserStatusSize) parserStatus = QmlEnginePrivate::SimpleList<QmlParserStatus>(instr.init.parserStatusSize); + + if (instr.init.idSize) + cp->setIdPropertyCount(instr.init.idSize); } break; @@ -194,7 +199,8 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData case QmlInstruction::SetId: { QObject *target = stack.top(); - ctxt->setContextProperty(primitives.at(instr.setId.value), target); +// ctxt->setContextProperty(primitives.at(instr.setId.value), target); + cp->setIdProperty(primitives.at(instr.setId.value), instr.setId.index, target); } break; |