summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qmlbasicscript.cpp2
-rw-r--r--src/declarative/qml/qmlcompiler.cpp6
-rw-r--r--src/declarative/qml/qmlcontext.cpp68
-rw-r--r--src/declarative/qml/qmlcontext.h3
-rw-r--r--src/declarative/qml/qmlcontext_p.h18
-rw-r--r--src/declarative/qml/qmlengine.cpp62
-rw-r--r--src/declarative/qml/qmlinstruction_p.h2
-rw-r--r--src/declarative/qml/qmlvme.cpp8
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;