From 04774bb14c81688f86a2b31b8624bde8ebf59062 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 30 May 2012 10:16:13 +0100 Subject: Evaluate bindings more intelligently during construction Instead of just evaluating bindings in a fixed order, and possibly having to evaluate a single binding multiple times, prior to reading a property, we check if there are any bindings "pending" on it and evaluate them then. A pending binding is one that has been assigned to the property, but not yet evaluated. To minimize side effects we only do this for "safe" bindings. A safe binding is one that has no side effects, which we currently define as not calling functions or otherwise assigning values during its evaluation. This isn't an entirely foolproof way to ensure that the evaluation has no side effects, but it should be good enough. Change-Id: I98aa76a95719e5d182e8941738d64f8d409f404a Reviewed-by: Michael Brasser --- src/qml/qml/qqmldata_p.h | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'src/qml/qml/qqmldata_p.h') diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 5f5dafa1f9..27038251b4 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -161,10 +161,15 @@ public: int bindingBitsSize; quint32 *bindingBits; - bool hasBindingBit(int) const; + + inline bool hasBindingBit(int) const; void clearBindingBit(int); void setBindingBit(QObject *obj, int); + inline bool hasPendingBindingBit(int) const; + void setPendingBindingBit(QObject *obj, int); + void clearPendingBindingBit(int); + quint16 lineNumber; quint16 columnNumber; @@ -201,9 +206,13 @@ public: static void markAsDeleted(QObject *); static void setQueuedForDeletion(QObject *); + static inline void flushPendingBinding(QObject *, int coreIndex); + private: // For attachedProperties mutable QQmlDataExtended *extendedData; + + void flushPendingBindingImpl(int coreIndex); }; bool QQmlData::wasDeleted(QObject *object) @@ -238,6 +247,31 @@ QQmlNotifierEndpoint *QQmlData::notify(int index) } } +bool QQmlData::hasBindingBit(int coreIndex) const +{ + int bit = coreIndex * 2; + if (bindingBitsSize > bit) + return bindingBits[bit / 32] & (1 << (bit % 32)); + else + return false; +} + +bool QQmlData::hasPendingBindingBit(int coreIndex) const +{ + int bit = coreIndex * 2 + 1; + if (bindingBitsSize > bit) + return bindingBits[bit / 32] & (1 << (bit % 32)); + else + return false; +} + +void QQmlData::flushPendingBinding(QObject *o, int coreIndex) +{ + QQmlData *data = QQmlData::get(o, false); + if (data && data->hasPendingBindingBit(coreIndex)) + data->flushPendingBindingImpl(coreIndex); +} + QT_END_NAMESPACE #endif // QQMLDATA_P_H -- cgit v1.2.3