diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-10-08 03:25:56 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-10-08 03:25:56 (GMT) |
commit | 41ec742f6713f5b3b4da853f514d685c35c3f31f (patch) | |
tree | 6088d2e80f64c80d2168a603fea28ab9ffb4efe3 /src/declarative/qml/qmlbinding.cpp | |
parent | 60a5afb67efcefa74cf452379dcef46b83daa265 (diff) | |
download | Qt-41ec742f6713f5b3b4da853f514d685c35c3f31f.zip Qt-41ec742f6713f5b3b4da853f514d685c35c3f31f.tar.gz Qt-41ec742f6713f5b3b4da853f514d685c35c3f31f.tar.bz2 |
Make qmlecmascript:selfDeletingBinding pass
Expressions and bindings must not reference data following their
evalutation incase their object has been deleted. To solve this, the
needed data is separated into a reference counted QmlExpressionData
and QmlBindingData object.
Diffstat (limited to 'src/declarative/qml/qmlbinding.cpp')
-rw-r--r-- | src/declarative/qml/qmlbinding.cpp | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp index 454369b..3a34f46 100644 --- a/src/declarative/qml/qmlbinding.cpp +++ b/src/declarative/qml/qmlbinding.cpp @@ -57,11 +57,16 @@ QT_BEGIN_NAMESPACE QML_DEFINE_NOCREATE_TYPE(QmlBinding); -QmlBindingPrivate::QmlBindingPrivate() +QmlBindingData::QmlBindingData() : updating(false), enabled(false) { } +QmlBindingPrivate::QmlBindingPrivate() +: QmlExpressionPrivate(new QmlBindingData) +{ +} + QmlBinding::QmlBinding(void *data, QmlRefCount *rc, QObject *obj, QmlContext *ctxt, QObject *parent) : QmlExpression(ctxt, data, rc, obj, *new QmlBindingPrivate) { @@ -81,7 +86,7 @@ QmlBinding::~QmlBinding() void QmlBinding::setTarget(const QmlMetaProperty &prop) { Q_D(QmlBinding); - d->property = prop; + d->bindingData()->property = prop; update(); } @@ -89,7 +94,7 @@ void QmlBinding::setTarget(const QmlMetaProperty &prop) QmlMetaProperty QmlBinding::property() const { Q_D(const QmlBinding); - return d->property; + return d->bindingData()->property; } void QmlBinding::update() @@ -99,45 +104,41 @@ void QmlBinding::update() #ifdef Q_ENABLE_PERFORMANCE_LOG QFxPerfTimer<QFxPerf::BindableValueUpdate> bu; #endif - if (!d->enabled) + QmlBindingData *data = d->bindingData(); + + if (!data->enabled) return; - if (!d->updating) { - d->updating = true; + data->addref(); - if (d->property.propertyCategory() == QmlMetaProperty::Bindable) { + if (!data->updating) { + data->updating = true; - int idx = d->property.coreIndex(); + if (data->property.propertyCategory() == QmlMetaProperty::Bindable) { + + int idx = data->property.coreIndex(); Q_ASSERT(idx != -1); void *a[1]; QmlBinding *t = this; a[0] = (void *)&t; - QMetaObject::metacall(d->property.object(), + QMetaObject::metacall(data->property.object(), QMetaObject::WriteProperty, idx, a); } else { QVariant value = this->value(); - if (value.type() == QVariant::String) { - QmlMetaType::StringConverter con = QmlMetaType::customStringConverter(d->property.propertyType()); - if (con) - value = con(value.toString()); - } - - if (d->property.propertyType() == QVariant::Vector3D && - value.type() == QVariant::String) { - value = qVariantFromValue(QmlStringConverters::vector3DFromString(value.toString())); - } - - d->property.write(value, QmlMetaProperty::Binding); + data->property.write(value, QmlMetaProperty::Binding); } - d->updating = false; + data->updating = false; } else { - qmlInfo(d->property.object()) << "Binding loop detected for property" << d->property.name(); + qmlInfo(data->property.object()) << "Binding loop detected for property" + << data->property.name(); } + + data->release(); } void QmlBinding::valueChanged() @@ -148,30 +149,30 @@ void QmlBinding::valueChanged() void QmlBinding::setEnabled(bool e) { Q_D(QmlBinding); - d->enabled = e; + d->bindingData()->enabled = e; setTrackChange(e); + QmlAbstractBinding::setEnabled(e); + if (e) { - addToObject(d->property.object()); + addToObject(d->bindingData()->property.object()); update(); } else { removeFromObject(); } - - QmlAbstractBinding::setEnabled(e); } int QmlBinding::propertyIndex() { Q_D(QmlBinding); - return d->property.coreIndex(); + return d->bindingData()->property.coreIndex(); } bool QmlBinding::enabled() const { Q_D(const QmlBinding); - return d->enabled; + return d->bindingData()->enabled; } QString QmlBinding::expression() const |