summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qmlbinding.cpp29
-rw-r--r--src/declarative/qml/qmlbinding.h1
-rw-r--r--src/declarative/qml/qmldeclarativedata_p.h6
-rw-r--r--src/declarative/qml/qmlengine.cpp41
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp37
-rw-r--r--src/declarative/qml/qmlmetaproperty.h2
-rw-r--r--src/declarative/qml/qmlmetaproperty_p.h2
-rw-r--r--src/declarative/qml/qmlvme.cpp3
8 files changed, 95 insertions, 26 deletions
diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp
index f9c9561..454369b 100644
--- a/src/declarative/qml/qmlbinding.cpp
+++ b/src/declarative/qml/qmlbinding.cpp
@@ -131,7 +131,7 @@ void QmlBinding::update()
value = qVariantFromValue(QmlStringConverters::vector3DFromString(value.toString()));
}
- d->property.write(value);
+ d->property.write(value, QmlMetaProperty::Binding);
}
d->updating = false;
@@ -180,7 +180,7 @@ QString QmlBinding::expression() const
}
QmlAbstractBinding::QmlAbstractBinding()
-: m_mePtr(0), m_prevBinding(0), m_nextBinding(0)
+: m_object(0), m_mePtr(0), m_prevBinding(0), m_nextBinding(0)
{
}
@@ -193,24 +193,35 @@ QmlAbstractBinding::~QmlAbstractBinding()
void QmlAbstractBinding::addToObject(QObject *object)
{
+ Q_ASSERT(object);
+
removeFromObject();
- if (object) {
- QmlDeclarativeData *data = QmlDeclarativeData::get(object, true);
- m_nextBinding = data->bindings;
- if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
- m_prevBinding = &data->bindings;
- data->bindings = this;
- }
+ Q_ASSERT(!m_prevBinding);
+
+ QmlDeclarativeData *data = QmlDeclarativeData::get(object, true);
+ m_nextBinding = data->bindings;
+ if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
+ m_prevBinding = &data->bindings;
+ data->bindings = this;
+ m_object = object;
+
+ data->setBindingBit(m_object, propertyIndex());
}
void QmlAbstractBinding::removeFromObject()
{
if (m_prevBinding) {
+ Q_ASSERT(m_object);
+
*m_prevBinding = m_nextBinding;
if (m_nextBinding) m_nextBinding->m_prevBinding = m_prevBinding;
m_prevBinding = 0;
m_nextBinding = 0;
+
+ QmlDeclarativeData *data = QmlDeclarativeData::get(m_object, false);
+ if (data) data->clearBindingBit(propertyIndex());
+ m_object = 0;
}
}
diff --git a/src/declarative/qml/qmlbinding.h b/src/declarative/qml/qmlbinding.h
index 63b8a15..675917d 100644
--- a/src/declarative/qml/qmlbinding.h
+++ b/src/declarative/qml/qmlbinding.h
@@ -75,6 +75,7 @@ private:
friend class QmlMetaProperty;
friend class QmlVME;
+ QObject *m_object;
QmlAbstractBinding **m_mePtr;
QmlAbstractBinding **m_prevBinding;
QmlAbstractBinding *m_nextBinding;
diff --git a/src/declarative/qml/qmldeclarativedata_p.h b/src/declarative/qml/qmldeclarativedata_p.h
index a316c0c..ade961f 100644
--- a/src/declarative/qml/qmldeclarativedata_p.h
+++ b/src/declarative/qml/qmldeclarativedata_p.h
@@ -70,6 +70,12 @@ public:
QmlContext *context;
QmlAbstractBinding *bindings;
+ int bindingBitsSize;
+ quint32 *bindingBits;
+ bool hasBindingBit(int) const;
+ void clearBindingBit(int);
+ void setBindingBit(QObject *obj, int);
+
QmlContext *outerContext; // Can't this be found from context?
ushort lineNumber;
ushort columnNumber;
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 4be5230..2ea1bee 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -700,7 +700,8 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre
}
QmlDeclarativeData::QmlDeclarativeData(QmlContext *ctxt)
-: context(ctxt), bindings(0), outerContext(0), lineNumber(0), columnNumber(0), deferredComponent(0),
+: context(ctxt), bindings(0), bindingBitsSize(0), bindingBits(0),
+ outerContext(0), lineNumber(0), columnNumber(0), deferredComponent(0),
deferredIdx(0), attachedProperties(0)
{
}
@@ -723,9 +724,47 @@ void QmlDeclarativeData::destroyed(QObject *object)
binding = next;
}
+ if (bindingBits)
+ free(bindingBits);
+
delete this;
}
+bool QmlDeclarativeData::hasBindingBit(int bit) const
+{
+ if (bindingBitsSize >= bit)
+ return bindingBits[bit / 32] & (1 << (bit % 32));
+ else
+ return false;
+}
+
+void QmlDeclarativeData::clearBindingBit(int bit)
+{
+ if (bindingBitsSize >= bit)
+ bindingBits[bit / 32] &= ~(1 << (bit % 32));
+}
+
+void QmlDeclarativeData::setBindingBit(QObject *obj, int bit)
+{
+ if (bindingBitsSize < bit) {
+ int props = obj->metaObject()->propertyCount();
+ Q_ASSERT(bit < props);
+
+ int arraySize = (props + 31) / 32;
+ int oldArraySize = bindingBitsSize / 32;
+
+ bindingBits = (quint32 *)realloc(bindingBits,
+ arraySize * sizeof(quint32));
+ memset(bindingBits + oldArraySize,
+ sizeof(quint32) * (arraySize - oldArraySize),
+ 0x00);
+
+ bindingBitsSize = arraySize * 32;
+ }
+
+ bindingBits[bit / 32] |= (1 << (bit % 32));
+}
+
/*!
Creates a QScriptValue allowing you to use \a object in QML script.
\a engine is the QmlEngine it is to be created in.
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index 8f76240..91769d3 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -531,6 +531,9 @@ QmlAbstractBinding *QmlMetaProperty::binding() const
if (!data)
return 0;
+ if (!data->hasBindingBit(d->coreIdx))
+ return 0;
+
QmlAbstractBinding *binding = data->bindings;
while (binding) {
// ### This wont work for value types
@@ -559,20 +562,22 @@ QmlMetaProperty::setBinding(QmlAbstractBinding *newBinding) const
QmlDeclarativeData *data = QmlDeclarativeData::get(d->object, true);
- QmlAbstractBinding *binding = data->bindings;
- while (binding) {
- // ### This wont work for value types
- if (binding->propertyIndex() == d->coreIdx) {
- binding->setEnabled(false);
+ if (data->hasBindingBit(d->coreIdx)) {
+ QmlAbstractBinding *binding = data->bindings;
+ while (binding) {
+ // ### This wont work for value types
+ if (binding->propertyIndex() == d->coreIdx) {
+ binding->setEnabled(false);
- if (newBinding)
- newBinding->setEnabled(true);
+ if (newBinding)
+ newBinding->setEnabled(true);
- return binding; // ### QmlAbstractBinding;
- }
+ return binding; // ### QmlAbstractBinding;
+ }
- binding = binding->m_nextBinding;
- }
+ binding = binding->m_nextBinding;
+ }
+ }
if (newBinding)
newBinding->setEnabled(true);
@@ -727,7 +732,8 @@ void QmlMetaPropertyPrivate::writeSignalProperty(const QVariant &value)
}
}
-void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value)
+void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
+ QmlMetaProperty::WriteSource source)
{
QObject *object = this->object;
int coreIdx = this->coreIdx;
@@ -987,6 +993,11 @@ void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value)
*/
void QmlMetaProperty::write(const QVariant &value) const
{
+ write(value, Other);
+}
+
+void QmlMetaProperty::write(const QVariant &value, WriteSource source) const
+{
if (!d->object)
return;
@@ -996,7 +1007,7 @@ void QmlMetaProperty::write(const QVariant &value) const
} else if (d->coreIdx != -1) {
- d->writeValueProperty(value);
+ d->writeValueProperty(value, source);
}
}
diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h
index 62e93c4..8c34ece 100644
--- a/src/declarative/qml/qmlmetaproperty.h
+++ b/src/declarative/qml/qmlmetaproperty.h
@@ -88,6 +88,8 @@ public:
QVariant read() const;
void write(const QVariant &) const;
+ enum WriteSource { Animation, Binding, Other };
+ void write(const QVariant &, WriteSource) const;
bool hasChangedNotifier() const;
bool needsChangedNotifier() const;
diff --git a/src/declarative/qml/qmlmetaproperty_p.h b/src/declarative/qml/qmlmetaproperty_p.h
index 8e8966e..f2d0039 100644
--- a/src/declarative/qml/qmlmetaproperty_p.h
+++ b/src/declarative/qml/qmlmetaproperty_p.h
@@ -118,7 +118,7 @@ public:
QmlMetaProperty::PropertyCategory propertyCategory() const;
void writeSignalProperty(const QVariant &);
- void writeValueProperty(const QVariant &);
+ void writeValueProperty(const QVariant &, QmlMetaProperty::WriteSource);
static quint32 saveValueType(int, int);
static quint32 saveProperty(int);
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index d377cc3..606a732 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -565,9 +565,8 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
QmlBinding *bind = new QmlBinding((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, 0);
bindValues.append(bind);
bind->m_mePtr = &bindValues.values[bindValues.count - 1];
- bind->addToObject(target);
-
bind->setTarget(mp);
+ bind->addToObject(target);
}
break;