diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-09-23 01:25:23 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-09-23 01:25:23 (GMT) |
commit | 1206562c6be4098de8a9fdda5c7ff5c8fdd6bc01 (patch) | |
tree | 4805291611955bf1e18c36c028bf6b32061a4129 | |
parent | 30379e098ef31a8a1f670bdeab212ed419e80b5b (diff) | |
download | Qt-1206562c6be4098de8a9fdda5c7ff5c8fdd6bc01.zip Qt-1206562c6be4098de8a9fdda5c7ff5c8fdd6bc01.tar.gz Qt-1206562c6be4098de8a9fdda5c7ff5c8fdd6bc01.tar.bz2 |
Use a bitmask to track bound properties
-rw-r--r-- | src/declarative/qml/qmlbinding.cpp | 29 | ||||
-rw-r--r-- | src/declarative/qml/qmlbinding.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qmldeclarativedata_p.h | 6 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 41 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetaproperty.cpp | 37 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetaproperty.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetaproperty_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlvme.cpp | 3 |
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; |