aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlvme.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlvme.cpp')
-rw-r--r--src/qml/qml/qqmlvme.cpp48
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();
}