diff options
Diffstat (limited to 'src/qml/qml/qqmlvme.cpp')
-rw-r--r-- | src/qml/qml/qqmlvme.cpp | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 21f07d9688..5534583dfa 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -79,8 +79,16 @@ #include <QtCore/qvarlengtharray.h> #include <QtQml/qjsvalue.h> +#include <utility> + QT_BEGIN_NAMESPACE +template <typename T1, typename T2> +uint qHash(const std::pair<T1, T2> &p) +{ + return qHash(p.first) ^ qHash(p.second); +} + using namespace QQmlVMETypes; #define VME_EXCEPTION(desc, line) \ @@ -1216,18 +1224,40 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt) { QQmlTrace trace("VME Binding Enable"); trace.event("begin binding eval"); - while (!bindValues.isEmpty()) { - QQmlAbstractBinding *b = bindValues.pop(); - if(b) { - b->m_mePtr = 0; - b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor | - QQmlPropertyPrivate::DontRemoveBinding); - } + size_t bindValuesRemaining = bindValues.count(); + if (bindValuesRemaining > 0) { + typedef std::pair<QObject *, int> TargetProperty; - if (watcher.hasRecursed() || interrupt.shouldInterrupt()) - return 0; + QSet<TargetProperty> boundProperties; + boundProperties.reserve(bindValuesRemaining - 1); + + while (bindValuesRemaining > 0) { + QQmlAbstractBinding *b = bindValues.pop(); + --bindValuesRemaining; + + if (b) { + b->m_mePtr = 0; + + TargetProperty property(std::make_pair(b->object(), b->propertyIndex())); + if (!boundProperties.contains(property)) { + // We have not assigned a binding to this property yet + b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor | + QQmlPropertyPrivate::DontRemoveBinding); + + if (bindValuesRemaining > 0) { + boundProperties.insert(property); + } + } else { + b->destroy(); + } + } + + if (watcher.hasRecursed() || interrupt.shouldInterrupt()) + return 0; + } } + bindValues.deallocate(); } |