summaryrefslogtreecommitdiff
path: root/src/declarative/qml/qdeclarativecontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qdeclarativecontext.cpp')
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp112
1 files changed, 89 insertions, 23 deletions
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index d4662cf43a..1723603d29 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -381,8 +381,8 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const
QByteArray utf8Name = name.toUtf8();
if (data->contextObject) {
QObject *obj = data->contextObject;
- QDeclarativePropertyCache::Data local;
- QDeclarativePropertyCache::Data *property =
+ QDeclarativePropertyData local;
+ QDeclarativePropertyData *property =
QDeclarativePropertyCache::property(data->engine, obj, name, local);
if (property) value = obj->metaObject()->property(property->coreIndex).read(obj);
@@ -511,18 +511,18 @@ QObject *QDeclarativeContextPrivate::context_at(QDeclarativeListProperty<QObject
QDeclarativeContextData::QDeclarativeContextData()
: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
- isPragmaLibraryContext(false), publicContext(0), activeVME(0), propertyNames(0), contextObject(0),
- imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0),
- contextGuards(0), idValues(0), idValueCount(0), linkedContext(0), componentAttached(0),
- v4bindings(0), v8bindings(0)
+ isPragmaLibraryContext(false), unresolvedNames(false), publicContext(0), activeVMEData(0),
+ propertyNames(0), contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0),
+ expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
+ componentAttached(0), v4bindings(0), v8bindings(0)
{
}
QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt)
: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
- isPragmaLibraryContext(false), publicContext(ctxt), activeVME(0), propertyNames(0),
- contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0),
- contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
+ isPragmaLibraryContext(false), unresolvedNames(false), publicContext(ctxt), activeVMEData(0),
+ propertyNames(0), contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0),
+ expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
componentAttached(0), v4bindings(0), v8bindings(0)
{
}
@@ -653,23 +653,89 @@ void QDeclarativeContextData::setParent(QDeclarativeContextData *p, bool parentT
}
}
-/*
-Refreshes all expressions that could possibly depend on this context. Refreshing flushes all
-context-tree dependent caches in the expressions, and should occur every time the context tree
- *structure* (not values) changes.
-*/
-void QDeclarativeContextData::refreshExpressions()
+void QDeclarativeContextData::refreshExpressionsRecursive(QDeclarativeAbstractExpression *expression)
{
- QDeclarativeContextData *child = childContexts;
- while (child) {
- child->refreshExpressions();
- child = child->nextChild;
- }
+ QDeleteWatcher w(expression);
- QDeclarativeAbstractExpression *expression = expressions;
- while (expression) {
+ if (expression->m_nextExpression)
+ refreshExpressionsRecursive(expression->m_nextExpression);
+
+ if (!w.wasDeleted())
expression->refresh();
- expression = expression->m_nextExpression;
+}
+
+static inline bool expressions_to_run(QDeclarativeContextData *ctxt, bool isGlobalRefresh)
+{
+ return ctxt->expressions && (!isGlobalRefresh || ctxt->unresolvedNames);
+}
+
+void QDeclarativeContextData::refreshExpressionsRecursive(bool isGlobal)
+{
+ // For efficiency, we try and minimize the number of guards we have to create
+ if (expressions_to_run(this, isGlobal) && (nextChild || childContexts)) {
+ QDeclarativeGuardedContextData guard(this);
+
+ if (childContexts)
+ childContexts->refreshExpressionsRecursive(isGlobal);
+
+ if (guard.isNull()) return;
+
+ if (nextChild)
+ nextChild->refreshExpressionsRecursive(isGlobal);
+
+ if (guard.isNull()) return;
+
+ if (expressions_to_run(this, isGlobal))
+ refreshExpressionsRecursive(expressions);
+
+ } else if (expressions_to_run(this, isGlobal)) {
+
+ refreshExpressionsRecursive(expressions);
+
+ } else if (nextChild && childContexts) {
+
+ QDeclarativeGuardedContextData guard(this);
+
+ childContexts->refreshExpressionsRecursive(isGlobal);
+
+ if (!guard.isNull() && nextChild)
+ nextChild->refreshExpressionsRecursive(isGlobal);
+
+ } else if (nextChild) {
+
+ nextChild->refreshExpressionsRecursive(isGlobal);
+
+ } else if (childContexts) {
+
+ childContexts->refreshExpressionsRecursive(isGlobal);
+
+ }
+}
+
+// Refreshes all expressions that could possibly depend on this context. Refreshing flushes all
+// context-tree dependent caches in the expressions, and should occur every time the context tree
+// *structure* (not values) changes.
+void QDeclarativeContextData::refreshExpressions()
+{
+ bool isGlobal = (parent == 0);
+
+ // For efficiency, we try and minimize the number of guards we have to create
+ if (expressions_to_run(this, isGlobal) && childContexts) {
+ QDeclarativeGuardedContextData guard(this);
+
+ childContexts->refreshExpressionsRecursive(isGlobal);
+
+ if (!guard.isNull() && expressions_to_run(this, isGlobal))
+ refreshExpressionsRecursive(expressions);
+
+ } else if (expressions_to_run(this, isGlobal)) {
+
+ refreshExpressionsRecursive(expressions);
+
+ } else if (childContexts) {
+
+ childContexts->refreshExpressionsRecursive(isGlobal);
+
}
}