Remove QPropertyMemberChangeHandler again
Adding support for a static notifier within QProperty itself - through a QProperty "sister" class - is more efficient in terms of memory consumption and run-time performance. The MemberChangeHandler permanently takes up at least three pointers, while the notified properties only cost one pointer in the binding. Change-Id: Ia1a8c2b66f1f3c2fe13ae0ad9f12cdb6bdcc35ef Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
parent
e18a060c03
commit
b20c7df63a
@ -731,28 +731,6 @@ QPropertyChangeHandler<Functor> QNotifiedProperty<T, Callback, ValueGuard>::subs
|
|||||||
return onValueChanged(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)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class QPropertyAlias : public QPropertyObserver
|
class QPropertyAlias : public QPropertyObserver
|
||||||
{
|
{
|
||||||
@ -892,7 +870,6 @@ public:
|
|||||||
return aliasedProperty<T>() != nullptr;
|
return aliasedProperty<T>() != nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // QPROPERTY_H
|
#endif // QPROPERTY_H
|
||||||
|
@ -67,7 +67,6 @@ private slots:
|
|||||||
void settingPropertyValueDoesRemoveBinding();
|
void settingPropertyValueDoesRemoveBinding();
|
||||||
void genericPropertyBinding();
|
void genericPropertyBinding();
|
||||||
void genericPropertyBindingBool();
|
void genericPropertyBindingBool();
|
||||||
void staticChangeHandler();
|
|
||||||
void setBindingFunctor();
|
void setBindingFunctor();
|
||||||
void multipleObservers();
|
void multipleObservers();
|
||||||
void propertyAlias();
|
void propertyAlias();
|
||||||
@ -661,25 +660,6 @@ void tst_QProperty::genericPropertyBindingBool()
|
|||||||
QVERIFY(property.value());
|
QVERIFY(property.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ItemType
|
|
||||||
{
|
|
||||||
QProperty<int> x;
|
|
||||||
QVector<int> observedValues;
|
|
||||||
void xChanged() {
|
|
||||||
observedValues << x.value();
|
|
||||||
}
|
|
||||||
QPropertyMemberChangeHandler<&ItemType::x, &ItemType::xChanged> test{this};
|
|
||||||
};
|
|
||||||
|
|
||||||
void tst_QProperty::staticChangeHandler()
|
|
||||||
{
|
|
||||||
ItemType t;
|
|
||||||
t.x = 42;
|
|
||||||
t.x = 100;
|
|
||||||
QVector<int> values{42, 100};
|
|
||||||
QCOMPARE(t.observedValues, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QProperty::setBindingFunctor()
|
void tst_QProperty::setBindingFunctor()
|
||||||
{
|
{
|
||||||
QProperty<int> property;
|
QProperty<int> property;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user