diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-11-25 13:13:37 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-11-30 23:02:31 +0000 |
commit | 1f1a3223734c42447ad527056dad47feeaf64b8f (patch) | |
tree | 7167f4288032d9c6d2288399c3b68a69eb74185a /src/corelib/kernel/qproperty.h | |
parent | d555425ff8503a793d9d42372ce78fa0530a670d (diff) |
Simplify the safeguarding logic in notify()
The logic in notify() was doing quite a bit more work than
it needed to. By inserting a dummy node after the current one instead of
replacing it, we can avoid half of the data shuffling that has been
happening and also don't need a back pointer when executing the
notification.
Also avoid calling a semi expensive destructor of QPropertyObserver.
Reduces the overhead of notify() by ~30%.
Change-Id: I7ce16bcf9cd9c4368c18bf875fc959223452fd4f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit e8ef871e3522f340b4efe32382af7e35ef908665)
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/corelib/kernel/qproperty.h')
-rw-r--r-- | src/corelib/kernel/qproperty.h | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index 858724c0b7..e9e0e37f3c 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -205,8 +205,9 @@ namespace Qt { struct QPropertyObserverPrivate; struct QPropertyObserverPointer; +class QPropertyObserver; -class Q_CORE_EXPORT QPropertyObserver +class QPropertyObserverBase { public: // Internal @@ -214,10 +215,33 @@ public: ObserverNotifiesBinding, // observer was installed to notify bindings that obsverved property changed ObserverNotifiesChangeHandler, // observer is a change handler, which runs on every change ObserverNotifiesAlias, // used for QPropertyAlias - ActivelyExecuting // the observer is currently evaluated in QPropertyObserver::notifyObservers or its - // placeholder. We only can store 4 different values, therefore those two conflate + ObserverIsPlaceholder // the observer before this one is currently evaluated in QPropertyObserver::notifyObservers. }; +protected: + using ChangeHandler = void (*)(QPropertyObserver*, QUntypedPropertyData *); + +private: + friend struct QPropertyObserverNodeProtector; + friend class QPropertyObserver; + friend struct QPropertyObserverPointer; + friend struct QPropertyBindingDataPointer; + friend class QPropertyBindingPrivate; + + QTaggedPointer<QPropertyObserver, ObserverTag> next; + // prev is a pointer to the "next" element within the previous node, or to the "firstObserverPtr" if it is the + // first node. + QtPrivate::QTagPreservingPointerToPointer<QPropertyObserver, ObserverTag> prev; + + union { + QPropertyBindingPrivate *bindingToMarkDirty = nullptr; + ChangeHandler changeHandler; + QUntypedPropertyData *aliasedPropertyData; + }; +}; +class Q_CORE_EXPORT QPropertyObserver : public QPropertyObserverBase +{ +public: constexpr QPropertyObserver() = default; QPropertyObserver(QPropertyObserver &&other) noexcept; QPropertyObserver &operator=(QPropertyObserver &&other) noexcept; @@ -229,7 +253,6 @@ public: void setSource(const QtPrivate::QPropertyBindingData &property); protected: - using ChangeHandler = void (*)(QPropertyObserver*, QUntypedPropertyData *); QPropertyObserver(ChangeHandler changeHandler); QPropertyObserver(QUntypedPropertyData *aliasedPropertyPtr); @@ -240,26 +263,9 @@ protected: private: - QTaggedPointer<QPropertyObserver, ObserverTag> next; - // prev is a pointer to the "next" element within the previous node, or to the "firstObserverPtr" if it is the - // first node. - QtPrivate::QTagPreservingPointerToPointer<QPropertyObserver, ObserverTag> prev; - - union { - QPropertyBindingPrivate *bindingToMarkDirty = nullptr; - ChangeHandler changeHandler; - QUntypedPropertyData *aliasedPropertyData; - QPropertyObserver **nodeState; - }; - QPropertyObserver(const QPropertyObserver &) = delete; QPropertyObserver &operator=(const QPropertyObserver &) = delete; - friend struct QPropertyObserverPointer; - friend struct QPropertyBindingDataPointer; - friend class QPropertyBindingPrivate; - template<ObserverTag> - friend struct QPropertyObserverNodeProtector; }; template <typename Functor> |