summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qproperty.cpp12
-rw-r--r--src/corelib/kernel/qproperty.h33
-rw-r--r--src/corelib/kernel/qproperty_p.h4
-rw-r--r--src/corelib/kernel/qpropertybinding.cpp2
-rw-r--r--src/corelib/kernel/qpropertyprivate.h2
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)
{