QProperty: optimize non-recursive notification logic
Previously, we were storing all binding-observers in a list, so that we can later revisit them during the notification loop. However, there is no point in doing that when the binding did not actually change. Pick-to: 6.4 Change-Id: I0b3343cc442eca2586c7c6a10c31d780f04730e6 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>bb10
parent
61806a058a
commit
3410b1dc9c
|
|
@ -276,7 +276,7 @@ void QPropertyBindingPrivate::unlinkAndDeref()
|
|||
destroyAndFreeMemory(this);
|
||||
}
|
||||
|
||||
void QPropertyBindingPrivate::evaluateRecursive(PendingBindingObserverList &bindingObservers, QBindingStatus *status)
|
||||
bool QPropertyBindingPrivate::evaluateRecursive(PendingBindingObserverList &bindingObservers, QBindingStatus *status)
|
||||
{
|
||||
if (!status)
|
||||
status = &bindingStatus;
|
||||
|
|
@ -769,10 +769,11 @@ void QPropertyObserverPointer::evaluateBindings(PendingBindingObserverList &bind
|
|||
QPropertyObserver *next = observer->next.data();
|
||||
|
||||
if (QPropertyObserver::ObserverTag(observer->next.tag()) == QPropertyObserver::ObserverNotifiesBinding) {
|
||||
bindingObservers.push_back(observer);
|
||||
auto bindingToEvaluate = observer->binding;
|
||||
QPropertyObserverNodeProtector protector(observer);
|
||||
bindingToEvaluate->evaluateRecursive_inline(bindingObservers, status);
|
||||
QBindingObserverPtr bindingObserver(observer); // binding must not be gone after evaluateRecursive_inline
|
||||
if (bindingToEvaluate->evaluateRecursive_inline(bindingObservers, status))
|
||||
bindingObservers.push_back(std::move(bindingObserver));
|
||||
next = protector.next();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ public:
|
|||
|
||||
void unlinkAndDeref();
|
||||
|
||||
void evaluateRecursive(PendingBindingObserverList &bindingObservers, QBindingStatus *status = nullptr);
|
||||
bool evaluateRecursive(PendingBindingObserverList &bindingObservers, QBindingStatus *status = nullptr);
|
||||
|
||||
// ### TODO: remove as soon as declarative no longer needs this overload
|
||||
void evaluateRecursive()
|
||||
|
|
@ -369,7 +369,7 @@ public:
|
|||
evaluateRecursive(bindingObservers);
|
||||
}
|
||||
|
||||
void Q_ALWAYS_INLINE evaluateRecursive_inline(PendingBindingObserverList &bindingObservers, QBindingStatus *status);
|
||||
bool Q_ALWAYS_INLINE evaluateRecursive_inline(PendingBindingObserverList &bindingObservers, QBindingStatus *status);
|
||||
|
||||
void notifyRecursive();
|
||||
void notifyNonRecursive(const PendingBindingObserverList &bindingObservers);
|
||||
|
|
@ -780,13 +780,13 @@ struct QUntypedBindablePrivate
|
|||
}
|
||||
};
|
||||
|
||||
inline void QPropertyBindingPrivate::evaluateRecursive_inline(PendingBindingObserverList &bindingObservers, QBindingStatus *status)
|
||||
inline bool QPropertyBindingPrivate::evaluateRecursive_inline(PendingBindingObserverList &bindingObservers, QBindingStatus *status)
|
||||
{
|
||||
if (updating) {
|
||||
error = QPropertyBindingError(QPropertyBindingError::BindingLoop);
|
||||
if (isQQmlPropertyBinding)
|
||||
errorCallBack(this);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -816,10 +816,11 @@ inline void QPropertyBindingPrivate::evaluateRecursive_inline(PendingBindingObse
|
|||
// If there was not, we must not clear it, as that only should happen in notifyRecursive
|
||||
pendingNotify = pendingNotify || changed;
|
||||
if (!changed || !firstObserver)
|
||||
return;
|
||||
return changed;
|
||||
|
||||
firstObserver.noSelfDependencies(this);
|
||||
firstObserver.evaluateBindings(bindingObservers, status);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<QPropertyObserverPointer::Notify notifyPolicy>
|
||||
|
|
|
|||
Loading…
Reference in New Issue