summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qproperty.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-08-22 10:39:42 +0200
committerLars Knoll <lars.knoll@qt.io>2020-09-02 22:44:28 +0200
commitee96d705ccfe5c27a24b63100b8352987dbb0ae4 (patch)
tree14a005bcc8b5f6e8813f94e96b3ce70211828c53 /src/corelib/kernel/qproperty.h
parente3ea8768fc3bfed088f70b5d7308e3dd94e93c32 (diff)
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 <ulf.hermann@qt.io>
Diffstat (limited to 'src/corelib/kernel/qproperty.h')
-rw-r--r--src/corelib/kernel/qproperty.h231
1 files changed, 112 insertions, 119 deletions
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<typename Property, typename = typename Property::InheritsQUntypedPropertyData>
+ 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<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(const QPropertyObserver &) = delete;
+ QPropertyObserver &operator=(const QPropertyObserver &) = delete;
+
+ friend struct QPropertyObserverPointer;
+ friend struct QPropertyBindingDataPointer;
+ friend class QPropertyBindingPrivate;
+};
+
+template <typename Functor>
+class QPropertyChangeHandler : public QPropertyObserver
+{
+ Functor m_handler;
+public:
+ QPropertyChangeHandler(Functor handler)
+ : QPropertyObserver([](QPropertyObserver *self, QUntypedPropertyData *) {
+ auto This = static_cast<QPropertyChangeHandler<Functor>*>(self);
+ This->m_handler();
+ })
+ , m_handler(handler)
+ {
+ }
+
+ template<typename Property, typename = typename Property::InheritsQUntypedPropertyData>
+ QPropertyChangeHandler(const Property &property, Functor handler)
+ : QPropertyObserver([](QPropertyObserver *self, QUntypedPropertyData *) {
+ auto This = static_cast<QPropertyChangeHandler<Functor>*>(self);
+ This->m_handler();
+ })
+ , m_handler(handler)
+ {
+ setSource(property);
+ }
+};
+
template <typename T>
class QProperty : public QPropertyData<T>
{
@@ -362,9 +442,19 @@ public:
}
template<typename Functor>
- QPropertyChangeHandler<Functor> onValueChanged(Functor f);
+ QPropertyChangeHandler<Functor> onValueChanged(Functor f)
+ {
+ static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
+ return QPropertyChangeHandler<Functor>(*this, f);
+ }
+
template<typename Functor>
- QPropertyChangeHandler<Functor> subscribe(Functor f);
+ QPropertyChangeHandler<Functor> subscribe(Functor f)
+ {
+ static_assert(std::is_invocable_v<Functor>, "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<typename Property, typename = std::enable_if_t<std::is_same_v<decltype(std::declval<Property>().bindingData()), QtPrivate::QPropertyBindingData &>>>
- void setSource(const Property &property)
- { setSource(property.bindingData()); }
-
-protected:
- using ChangeHandler = void (*)(QPropertyObserver*, QUntypedPropertyData *);
- QPropertyObserver(ChangeHandler changeHandler);
- QPropertyObserver(QUntypedPropertyData *aliasedPropertyPtr);
-
- template<typename PropertyType>
- QProperty<PropertyType> *aliasedProperty() const
- {
- return static_cast<QProperty<PropertyType> *>(aliasedPropertyData);
- }
-
-private:
- void setSource(const QtPrivate::QPropertyBindingData &property);
-
- 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(const QPropertyObserver &) = delete;
- QPropertyObserver &operator=(const QPropertyObserver &) = delete;
-
- friend struct QPropertyObserverPointer;
- friend struct QPropertyBindingDataPointer;
- friend class QPropertyBindingPrivate;
-};
-
-template <typename Functor>
-class QPropertyChangeHandler : public QPropertyObserver
-{
- Functor m_handler;
-public:
- QPropertyChangeHandler(Functor handler)
- : QPropertyObserver([](QPropertyObserver *self, QUntypedPropertyData *) {
- auto This = static_cast<QPropertyChangeHandler<Functor>*>(self);
- This->m_handler();
- })
- , m_handler(handler)
- {
- }
-
- template<typename Property, typename = typename Property::InheritsQUntypedPropertyData>
- QPropertyChangeHandler(const Property &property, Functor handler)
- : QPropertyObserver([](QPropertyObserver *self, QUntypedPropertyData *) {
- auto This = static_cast<QPropertyChangeHandler<Functor>*>(self);
- This->m_handler();
- })
- , m_handler(handler)
- {
- setSource(property);
- }
-};
-
-template <typename T>
-template<typename Functor>
-QPropertyChangeHandler<Functor> QProperty<T>::onValueChanged(Functor f)
-{
-#if defined(__cpp_lib_is_invocable) && (__cpp_lib_is_invocable >= 201703L)
- static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
-#endif
- return QPropertyChangeHandler<Functor>(*this, f);
-}
-
-template <typename T>
-template<typename Functor>
-QPropertyChangeHandler<Functor> QProperty<T>::subscribe(Functor f)
-{
-#if defined(__cpp_lib_is_invocable) && (__cpp_lib_is_invocable >= 201703L)
- static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters");
-#endif
- f();
- return onValueChanged(f);
-}
-
template<typename T>
class QPropertyAlias : public QPropertyObserver
{
Q_DISABLE_COPY_MOVE(QPropertyAlias)
+ QProperty<T> *aliasedProperty() const
+ {
+ return static_cast<QProperty<T> *>(QPropertyObserver::aliasedProperty());
+ }
+
public:
QPropertyAlias(QProperty<T> *property)
: QPropertyObserver(property)
@@ -501,12 +494,12 @@ public:
}
QPropertyAlias(QPropertyAlias<T> *alias)
- : QPropertyAlias(alias->aliasedProperty<T>())
+ : QPropertyAlias(alias->aliasedProperty())
{}
T value() const
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
return p->value();
return T();
}
@@ -515,26 +508,26 @@ public:
void setValue(T &&newValue)
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
p->setValue(std::move(newValue));
}
void setValue(const T &newValue)
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
p->setValue(newValue);
}
QPropertyAlias<T> &operator=(T &&newValue)
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
*p = std::move(newValue);
return *this;
}
QPropertyAlias<T> &operator=(const T &newValue)
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
*p = newValue;
return *this;
}
@@ -553,21 +546,21 @@ public:
QPropertyBinding<T> setBinding(const QPropertyBinding<T> &newBinding)
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
return p->setBinding(newBinding);
return QPropertyBinding<T>();
}
QPropertyBinding<T> setBinding(QPropertyBinding<T> &&newBinding)
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
return p->setBinding(std::move(newBinding));
return QPropertyBinding<T>();
}
bool setBinding(const QUntypedPropertyBinding &newBinding)
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
return p->setBinding(newBinding);
return false;
}
@@ -587,21 +580,21 @@ public:
bool hasBinding() const
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
return p->hasBinding();
return false;
}
QPropertyBinding<T> binding() const
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
return p->binding();
return QPropertyBinding<T>();
}
QPropertyBinding<T> takeBinding()
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
return p->takeBinding();
return QPropertyBinding<T>();
}
@@ -609,7 +602,7 @@ public:
template<typename Functor>
QPropertyChangeHandler<Functor> onValueChanged(Functor f)
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
return p->onValueChanged(f);
return QPropertyChangeHandler<Functor>(f);
}
@@ -617,14 +610,14 @@ public:
template<typename Functor>
QPropertyChangeHandler<Functor> subscribe(Functor f)
{
- if (auto *p = aliasedProperty<T>())
+ if (auto *p = aliasedProperty())
return p->subscribe(f);
return QPropertyChangeHandler<Functor>(f);
}
bool isValid() const
{
- return aliasedProperty<T>() != nullptr;
+ return aliasedProperty() != nullptr;
}
};
QT_END_NAMESPACE