summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qproperty.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-11-25 13:13:37 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2020-11-30 23:02:31 +0000
commit1f1a3223734c42447ad527056dad47feeaf64b8f (patch)
tree7167f4288032d9c6d2288399c3b68a69eb74185a /src/corelib/kernel/qproperty.h
parentd555425ff8503a793d9d42372ce78fa0530a670d (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.h48
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>