diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qproperty.cpp | 12 | ||||
-rw-r--r-- | src/corelib/kernel/qproperty.h | 33 | ||||
-rw-r--r-- | src/corelib/kernel/qproperty_p.h | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qpropertybinding.cpp | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qpropertyprivate.h | 2 |
5 files changed, 38 insertions, 15 deletions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index 18580fa756..0e51226b34 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -226,11 +226,11 @@ void QPropertyBase::registerWithCurrentlyEvaluatingBinding() const dependencyObserver.observeProperty(d); } -void QPropertyBase::notifyObservers() +void QPropertyBase::notifyObservers(void *propertyDataPtr) { QPropertyBasePointer d{this}; if (QPropertyObserverPointer observer = d.firstObserver()) - observer.notify(d.bindingPtr()); + observer.notify(d.bindingPtr(), propertyDataPtr); } int QPropertyBasePointer::observerCount() const @@ -241,7 +241,7 @@ int QPropertyBasePointer::observerCount() const return count; } -QPropertyObserver::QPropertyObserver(void (*callback)(QPropertyObserver*)) +QPropertyObserver::QPropertyObserver(void (*callback)(QPropertyObserver *, void *)) { QPropertyObserverPointer d{this}; d.setChangeHandler(callback); @@ -304,7 +304,7 @@ void QPropertyObserverPointer::unlink() ptr->prev.clear(); } -void QPropertyObserverPointer::setChangeHandler(void (*changeHandler)(QPropertyObserver *)) +void QPropertyObserverPointer::setChangeHandler(void (*changeHandler)(QPropertyObserver *, void *)) { ptr->changeHandler = changeHandler; ptr->next.setTag(QPropertyObserver::ObserverNotifiesChangeHandler); @@ -316,7 +316,7 @@ void QPropertyObserverPointer::setBindingToMarkDirty(QPropertyBindingPrivate *bi ptr->next.setTag(QPropertyObserver::ObserverNotifiesBinding); } -void QPropertyObserverPointer::notify(QPropertyBindingPrivate *triggeringBinding) +void QPropertyObserverPointer::notify(QPropertyBindingPrivate *triggeringBinding, void *propertyDataPtr) { bool knownIfPropertyChanged = false; bool propertyChanged =true; @@ -334,7 +334,7 @@ void QPropertyObserverPointer::notify(QPropertyBindingPrivate *triggeringBinding return; if (auto handlerToCall = std::exchange(observer->changeHandler, nullptr)) { - handlerToCall(observer); + handlerToCall(observer, propertyDataPtr); observer->changeHandler = handlerToCall; } } else { diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index 338c7bbeec..609bb85221 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -348,7 +348,7 @@ public: private: void notify() { - d.priv.notifyObservers(); + d.priv.notifyObservers(&d); } Q_DISABLE_COPY(QProperty) @@ -403,7 +403,7 @@ public: { setSource(property.d.priv); } protected: - QPropertyObserver(void (*callback)(QPropertyObserver*)); + QPropertyObserver(void (*callback)(QPropertyObserver*, void *)); private: void setSource(QtPrivate::QPropertyBase &property); @@ -415,7 +415,7 @@ private: union { QPropertyBindingPrivate *bindingToMarkDirty = nullptr; - void (*changeHandler)(QPropertyObserver*); + void (*changeHandler)(QPropertyObserver*, void *); }; QPropertyObserver(const QPropertyObserver &) = delete; @@ -434,7 +434,7 @@ class QPropertyChangeHandler : public QPropertyObserver Functor m_handler; public: QPropertyChangeHandler(Functor handler) - : QPropertyObserver([](QPropertyObserver *self) { + : QPropertyObserver([](QPropertyObserver *self, void *) { auto This = static_cast<QPropertyChangeHandler<Functor>*>(self); This->m_handler(); }) @@ -444,7 +444,7 @@ public: template <typename PropertyType> QPropertyChangeHandler(const QProperty<PropertyType> &property, Functor handler) - : QPropertyObserver([](QPropertyObserver *self) { + : QPropertyObserver([](QPropertyObserver *self, void *) { auto This = static_cast<QPropertyChangeHandler<Functor>*>(self); This->m_handler(); }) @@ -475,6 +475,29 @@ QPropertyChangeHandler<Functor> QProperty<T>::subscribe(Functor f) return onValueChanged(f); } +template <auto propertyMember, auto callbackMember> +struct QPropertyMemberChangeHandler; + +template<typename Class, typename PropertyType, PropertyType Class::* PropertyMember, void(Class::*Callback)()> +struct QPropertyMemberChangeHandler<PropertyMember, Callback> : public QPropertyObserver +{ + QPropertyMemberChangeHandler(Class *obj) + : QPropertyObserver(notify) + { + setSource(obj->*PropertyMember); + } + + static void notify(QPropertyObserver *, void *propertyDataPtr) + { + // memberOffset is the offset of the QProperty<> member within the class. We get the absolute address + // of that member and subtracting the relative offset gives us the address of the class instance. + const size_t memberOffset = reinterpret_cast<size_t>(&(static_cast<Class *>(nullptr)->*PropertyMember)); + Class *obj = reinterpret_cast<Class *>(reinterpret_cast<char *>(propertyDataPtr) - memberOffset); + (obj->*Callback)(); + } +}; + + QT_END_NAMESPACE #endif // QPROPERTY_H diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h index a50ae0dee1..13cdb311c1 100644 --- a/src/corelib/kernel/qproperty_p.h +++ b/src/corelib/kernel/qproperty_p.h @@ -86,9 +86,9 @@ struct QPropertyObserverPointer void unlink(); void setBindingToMarkDirty(QPropertyBindingPrivate *binding); - void setChangeHandler(void (*changeHandler)(QPropertyObserver*)); + void setChangeHandler(void (*changeHandler)(QPropertyObserver *, void *)); - void notify(QPropertyBindingPrivate *triggeringBinding); + void notify(QPropertyBindingPrivate *triggeringBinding, void *propertyDataPtr); void observeProperty(QPropertyBasePointer property); explicit operator bool() const { return ptr != nullptr; } diff --git a/src/corelib/kernel/qpropertybinding.cpp b/src/corelib/kernel/qpropertybinding.cpp index aa7bf1d022..8fdf770d18 100644 --- a/src/corelib/kernel/qpropertybinding.cpp +++ b/src/corelib/kernel/qpropertybinding.cpp @@ -63,7 +63,7 @@ void QPropertyBindingPrivate::markDirtyAndNotifyObservers() { dirty = true; if (firstObserver) - firstObserver.notify(this); + firstObserver.notify(this, propertyDataPtr); } bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged() diff --git a/src/corelib/kernel/qpropertyprivate.h b/src/corelib/kernel/qpropertyprivate.h index b4f2cd5154..1329ec6682 100644 --- a/src/corelib/kernel/qpropertyprivate.h +++ b/src/corelib/kernel/qpropertyprivate.h @@ -89,7 +89,7 @@ public: void removeBinding(); void registerWithCurrentlyEvaluatingBinding() const; - void notifyObservers(); + void notifyObservers(void *propertyDataPtr); void setExtraBit(bool b) { |