summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-05-11 02:13:04 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-05-11 02:13:04 (GMT)
commitb9f263eb1e5871ed724452e7454b8414e554ead6 (patch)
treece75abbd158d74f7152126ca9311ee268c370942
parent5c69031b23f349d199ed43e484a608a2b691bb95 (diff)
downloadQt-b9f263eb1e5871ed724452e7454b8414e554ead6.zip
Qt-b9f263eb1e5871ed724452e7454b8414e554ead6.tar.gz
Qt-b9f263eb1e5871ed724452e7454b8414e554ead6.tar.bz2
Clean up QmlContext's and QmlExpression's when a context gets deleted
-rw-r--r--src/declarative/qml/qmlcontext.cpp34
-rw-r--r--src/declarative/qml/qmlcontext_p.h5
-rw-r--r--src/declarative/qml/qmlengine.cpp12
-rw-r--r--src/declarative/qml/qmlexpression.h1
4 files changed, 49 insertions, 3 deletions
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index 16399bc..df5f90e 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -86,6 +86,10 @@ void QmlContextPrivate::destroyed(QObject *obj)
void QmlContextPrivate::init()
{
Q_Q(QmlContext);
+
+ if (parent)
+ parent->d_func()->childContexts.insert(q);
+
//set scope chain
QScriptEngine *scriptEngine = engine->scriptEngine();
QScriptValue scopeObj =
@@ -232,7 +236,24 @@ QmlContext::QmlContext(QmlContext *parentContext, QObject *parent)
QmlContext::~QmlContext()
{
Q_D(QmlContext);
- for(int ii = 0; ii < d->contextObjects.count(); ++ii) {
+ if (d->parent)
+ d->parent->d_func()->childContexts.remove(this);
+
+ for (QSet<QmlContext *>::ConstIterator iter = d->childContexts.begin();
+ iter != d->childContexts.end();
+ ++iter) {
+ (*iter)->d_func()->invalidateEngines();
+ (*iter)->d_func()->parent = 0;
+ }
+
+ for (QSet<QmlExpression *>::ConstIterator iter =
+ d->childExpressions.begin();
+ iter != d->childExpressions.end();
+ ++iter) {
+ (*iter)->d->ctxt = 0;
+ }
+
+ for (int ii = 0; ii < d->contextObjects.count(); ++ii) {
QObjectPrivate *p = QObjectPrivate::get(d->contextObjects.at(ii));
QmlSimpleDeclarativeData *data =
static_cast<QmlSimpleDeclarativeData *>(p->declarativeData);
@@ -245,6 +266,17 @@ QmlContext::~QmlContext()
d->contextObjects.clear();
}
+void QmlContextPrivate::invalidateEngines()
+{
+ if (!engine)
+ return;
+ engine = 0;
+ for (QSet<QmlContext *>::ConstIterator iter = childContexts.begin();
+ iter != childContexts.end();
+ ++iter) {
+ (*iter)->d_func()->invalidateEngines();
+ }
+}
/*!
Return the context's QmlEngine, or 0 if the context has no QmlEngine or the
diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h
index 9faa7b7..c265474 100644
--- a/src/declarative/qml/qmlcontext_p.h
+++ b/src/declarative/qml/qmlcontext_p.h
@@ -47,6 +47,7 @@
#include <private/qmldeclarativedata_p.h>
#include <qhash.h>
#include <qscriptvalue.h>
+#include <QtCore/qset.h>
QT_BEGIN_NAMESPACE
class QmlContext;
@@ -87,6 +88,10 @@ public:
};
void addDefaultObject(QObject *, Priority);
+ void invalidateEngines();
+ QSet<QmlContext *> childContexts;
+ QSet<QmlExpression *> childExpressions;
+
QmlSimpleDeclarativeData contextData;
QObjectList contextObjects;
};
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index fc209c6..c39a0d5 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -805,6 +805,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, void *expr,
d->ctxt = ctxt;
if(ctxt && ctxt->engine())
d->id = ctxt->engine()->d_func()->getUniqueId();
+ if(ctxt)
+ ctxt->d_func()->childExpressions.insert(this);
d->me = me;
}
@@ -816,6 +818,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expr,
d->ctxt = ctxt;
if(ctxt && ctxt->engine())
d->id = ctxt->engine()->d_func()->getUniqueId();
+ if(ctxt)
+ ctxt->d_func()->childExpressions.insert(this);
d->me = me;
}
@@ -833,6 +837,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expression,
d->ctxt = ctxt;
if(ctxt && ctxt->engine())
d->id = ctxt->engine()->d_func()->getUniqueId();
+ if(ctxt)
+ ctxt->d_func()->childExpressions.insert(this);
d->me = scope;
}
@@ -841,6 +847,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expression,
*/
QmlExpression::~QmlExpression()
{
+ if (d->ctxt)
+ d->ctxt->d_func()->childExpressions.remove(this);
delete d; d = 0;
}
@@ -850,7 +858,7 @@ QmlExpression::~QmlExpression()
*/
QmlEngine *QmlExpression::engine() const
{
- return d->ctxt->engine();
+ return d->ctxt?d->ctxt->engine():0;
}
/*!
@@ -927,7 +935,7 @@ void BindExpressionProxy::changed()
QVariant QmlExpression::value()
{
QVariant rv;
- if (!d->ctxt || (!d->sse.isValid() && d->expression.isEmpty()))
+ if (!d->ctxt || !engine() || (!d->sse.isValid() && d->expression.isEmpty()))
return rv;
#ifdef Q_ENABLE_PERFORMANCE_LOG
diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h
index bb6980a..2c6b1ad 100644
--- a/src/declarative/qml/qmlexpression.h
+++ b/src/declarative/qml/qmlexpression.h
@@ -87,6 +87,7 @@ protected:
private:
friend class BindExpressionProxy;
friend class QmlDebugger;
+ friend class QmlContext;
QmlExpressionPrivate *d;
};