From ee96d705ccfe5c27a24b63100b8352987dbb0ae4 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 22 Aug 2020 10:39:42 +0200 Subject: Move QPropertyObserver further up in the header file Reorder source code to make the follow-up work easier. Also clean up retrieving the pointer to the aliased property. Make setSource(QPropertyBindingData) public, it'll be needed later on. Change-Id: I784fdceac8722c7df756b2d7c35e08c7ab3a2074 Reviewed-by: Ulf Hermann --- src/corelib/kernel/qproperty.cpp | 2 + src/corelib/kernel/qproperty.h | 231 +++++++++++++++++++-------------------- 2 files changed, 114 insertions(+), 119 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index 2028bcf404..e0a1341e20 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -361,6 +361,8 @@ QPropertyObserver::QPropertyObserver(QUntypedPropertyData *aliasedPropertyPtr) d.setAliasedProperty(aliasedPropertyPtr); } +/*! \internal + */ void QPropertyObserver::setSource(const QPropertyBindingData &property) { QPropertyObserverPointer d{this}; diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index 7b63a46665..02d1c1eb94 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -213,6 +213,86 @@ namespace Qt { } } +struct QPropertyObserverPrivate; +struct QPropertyObserverPointer; + +class Q_CORE_EXPORT QPropertyObserver +{ +public: + // Internal + enum ObserverTag { + ObserverNotifiesBinding, + ObserverNotifiesChangeHandler, + ObserverNotifiesAlias, + }; + + QPropertyObserver() = default; + QPropertyObserver(QPropertyObserver &&other); + QPropertyObserver &operator=(QPropertyObserver &&other); + ~QPropertyObserver(); + + template + void setSource(const Property &property) + { setSource(property.bindingData()); } + void setSource(const QtPrivate::QPropertyBindingData &property); + +protected: + using ChangeHandler = void (*)(QPropertyObserver*, QUntypedPropertyData *); + QPropertyObserver(ChangeHandler changeHandler); + QPropertyObserver(QUntypedPropertyData *aliasedPropertyPtr); + + QUntypedPropertyData *aliasedProperty() const + { + return aliasedPropertyData; + } + +private: + + QTaggedPointer 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 prev; + + union { + QPropertyBindingPrivate *bindingToMarkDirty = nullptr; + ChangeHandler changeHandler; + QUntypedPropertyData *aliasedPropertyData; + }; + + QPropertyObserver(const QPropertyObserver &) = delete; + QPropertyObserver &operator=(const QPropertyObserver &) = delete; + + friend struct QPropertyObserverPointer; + friend struct QPropertyBindingDataPointer; + friend class QPropertyBindingPrivate; +}; + +template +class QPropertyChangeHandler : public QPropertyObserver +{ + Functor m_handler; +public: + QPropertyChangeHandler(Functor handler) + : QPropertyObserver([](QPropertyObserver *self, QUntypedPropertyData *) { + auto This = static_cast*>(self); + This->m_handler(); + }) + , m_handler(handler) + { + } + + template + QPropertyChangeHandler(const Property &property, Functor handler) + : QPropertyObserver([](QPropertyObserver *self, QUntypedPropertyData *) { + auto This = static_cast*>(self); + This->m_handler(); + }) + , m_handler(handler) + { + setSource(property); + } +}; + template class QProperty : public QPropertyData { @@ -362,9 +442,19 @@ public: } template - QPropertyChangeHandler onValueChanged(Functor f); + QPropertyChangeHandler onValueChanged(Functor f) + { + static_assert(std::is_invocable_v, "Functor callback must be callable without any parameters"); + return QPropertyChangeHandler(*this, f); + } + template - QPropertyChangeHandler subscribe(Functor f); + QPropertyChangeHandler subscribe(Functor f) + { + static_assert(std::is_invocable_v, "Functor callback must be callable without any parameters"); + f(); + return onValueChanged(f); + } const QtPrivate::QPropertyBindingData &bindingData() const { return d; } private: @@ -386,112 +476,15 @@ namespace Qt { } } -struct QPropertyObserverPrivate; -struct QPropertyObserverPointer; - -class Q_CORE_EXPORT QPropertyObserver -{ -public: - // Internal - enum ObserverTag { - ObserverNotifiesBinding, - ObserverNotifiesChangeHandler, - ObserverNotifiesAlias, - }; - - QPropertyObserver() = default; - QPropertyObserver(QPropertyObserver &&other); - QPropertyObserver &operator=(QPropertyObserver &&other); - ~QPropertyObserver(); - - template().bindingData()), QtPrivate::QPropertyBindingData &>>> - void setSource(const Property &property) - { setSource(property.bindingData()); } - -protected: - using ChangeHandler = void (*)(QPropertyObserver*, QUntypedPropertyData *); - QPropertyObserver(ChangeHandler changeHandler); - QPropertyObserver(QUntypedPropertyData *aliasedPropertyPtr); - - template - QProperty *aliasedProperty() const - { - return static_cast *>(aliasedPropertyData); - } - -private: - void setSource(const QtPrivate::QPropertyBindingData &property); - - QTaggedPointer 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 prev; - - union { - QPropertyBindingPrivate *bindingToMarkDirty = nullptr; - ChangeHandler changeHandler; - QUntypedPropertyData *aliasedPropertyData; - }; - - QPropertyObserver(const QPropertyObserver &) = delete; - QPropertyObserver &operator=(const QPropertyObserver &) = delete; - - friend struct QPropertyObserverPointer; - friend struct QPropertyBindingDataPointer; - friend class QPropertyBindingPrivate; -}; - -template -class QPropertyChangeHandler : public QPropertyObserver -{ - Functor m_handler; -public: - QPropertyChangeHandler(Functor handler) - : QPropertyObserver([](QPropertyObserver *self, QUntypedPropertyData *) { - auto This = static_cast*>(self); - This->m_handler(); - }) - , m_handler(handler) - { - } - - template - QPropertyChangeHandler(const Property &property, Functor handler) - : QPropertyObserver([](QPropertyObserver *self, QUntypedPropertyData *) { - auto This = static_cast*>(self); - This->m_handler(); - }) - , m_handler(handler) - { - setSource(property); - } -}; - -template -template -QPropertyChangeHandler QProperty::onValueChanged(Functor f) -{ -#if defined(__cpp_lib_is_invocable) && (__cpp_lib_is_invocable >= 201703L) - static_assert(std::is_invocable_v, "Functor callback must be callable without any parameters"); -#endif - return QPropertyChangeHandler(*this, f); -} - -template -template -QPropertyChangeHandler QProperty::subscribe(Functor f) -{ -#if defined(__cpp_lib_is_invocable) && (__cpp_lib_is_invocable >= 201703L) - static_assert(std::is_invocable_v, "Functor callback must be callable without any parameters"); -#endif - f(); - return onValueChanged(f); -} - template class QPropertyAlias : public QPropertyObserver { Q_DISABLE_COPY_MOVE(QPropertyAlias) + QProperty *aliasedProperty() const + { + return static_cast *>(QPropertyObserver::aliasedProperty()); + } + public: QPropertyAlias(QProperty *property) : QPropertyObserver(property) @@ -501,12 +494,12 @@ public: } QPropertyAlias(QPropertyAlias *alias) - : QPropertyAlias(alias->aliasedProperty()) + : QPropertyAlias(alias->aliasedProperty()) {} T value() const { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) return p->value(); return T(); } @@ -515,26 +508,26 @@ public: void setValue(T &&newValue) { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) p->setValue(std::move(newValue)); } void setValue(const T &newValue) { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) p->setValue(newValue); } QPropertyAlias &operator=(T &&newValue) { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) *p = std::move(newValue); return *this; } QPropertyAlias &operator=(const T &newValue) { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) *p = newValue; return *this; } @@ -553,21 +546,21 @@ public: QPropertyBinding setBinding(const QPropertyBinding &newBinding) { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) return p->setBinding(newBinding); return QPropertyBinding(); } QPropertyBinding setBinding(QPropertyBinding &&newBinding) { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) return p->setBinding(std::move(newBinding)); return QPropertyBinding(); } bool setBinding(const QUntypedPropertyBinding &newBinding) { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) return p->setBinding(newBinding); return false; } @@ -587,21 +580,21 @@ public: bool hasBinding() const { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) return p->hasBinding(); return false; } QPropertyBinding binding() const { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) return p->binding(); return QPropertyBinding(); } QPropertyBinding takeBinding() { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) return p->takeBinding(); return QPropertyBinding(); } @@ -609,7 +602,7 @@ public: template QPropertyChangeHandler onValueChanged(Functor f) { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) return p->onValueChanged(f); return QPropertyChangeHandler(f); } @@ -617,14 +610,14 @@ public: template QPropertyChangeHandler subscribe(Functor f) { - if (auto *p = aliasedProperty()) + if (auto *p = aliasedProperty()) return p->subscribe(f); return QPropertyChangeHandler(f); } bool isValid() const { - return aliasedProperty() != nullptr; + return aliasedProperty() != nullptr; } }; QT_END_NAMESPACE -- cgit v1.2.3