QObjectCompatProperty: Emit signal in notfiy
There is no need to write emit and notify at the same time, as not emitting after notify does not make sense. This naturally only applies to properties with a changed signal. Change-Id: I99ff7863a509262ad9d4f7c9c5afbc66fd37001c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
parent
2ffb91ac59
commit
4ceaf22bed
@ -844,7 +844,7 @@ class Q_CORE_EXPORT QBindingStorage
|
|||||||
mutable QBindingStorageData *d = nullptr;
|
mutable QBindingStorageData *d = nullptr;
|
||||||
QBindingStatus *bindingStatus = nullptr;
|
QBindingStatus *bindingStatus = nullptr;
|
||||||
|
|
||||||
template<typename Class, typename T, auto Offset, auto Setter>
|
template<typename Class, typename T, auto Offset, auto Setter, auto Signal>
|
||||||
friend class QObjectCompatProperty;
|
friend class QObjectCompatProperty;
|
||||||
public:
|
public:
|
||||||
QBindingStorage();
|
QBindingStorage();
|
||||||
|
@ -385,10 +385,11 @@ inline QPropertyObserverPointer QPropertyBindingDataPointer::firstObserver() con
|
|||||||
return { reinterpret_cast<QPropertyObserver *>(ptr->d_ptr) };
|
return { reinterpret_cast<QPropertyObserver *>(ptr->d_ptr) };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Class, typename T, auto Offset, auto Setter>
|
template<typename Class, typename T, auto Offset, auto Setter, auto Signal=nullptr>
|
||||||
class QObjectCompatProperty : public QPropertyData<T>
|
class QObjectCompatProperty : public QPropertyData<T>
|
||||||
{
|
{
|
||||||
using ThisType = QObjectCompatProperty<Class, T, Offset, Setter>;
|
using ThisType = QObjectCompatProperty<Class, T, Offset, Setter, Signal>;
|
||||||
|
using SignalTakesValue = std::is_invocable<decltype(Signal), Class, T>;
|
||||||
Class *owner()
|
Class *owner()
|
||||||
{
|
{
|
||||||
char *that = reinterpret_cast<char *>(this);
|
char *that = reinterpret_cast<char *>(this);
|
||||||
@ -523,6 +524,21 @@ public:
|
|||||||
bd->removeBinding();
|
bd->removeBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notify()
|
||||||
|
{
|
||||||
|
QBindingStorage *storage = qGetBindingStorage(owner());
|
||||||
|
auto bd = storage->bindingData(this, false);
|
||||||
|
const bool inWrapper = inBindingWrapper(storage);
|
||||||
|
if (bd && !inWrapper)
|
||||||
|
notify(bd);
|
||||||
|
if constexpr (Signal != nullptr) {
|
||||||
|
if constexpr (SignalTakesValue::value)
|
||||||
|
(owner()->*Signal)(value());
|
||||||
|
else
|
||||||
|
(owner()->*Signal)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QPropertyBinding<T> binding() const
|
QPropertyBinding<T> binding() const
|
||||||
{
|
{
|
||||||
auto *bd = qGetBindingStorage(owner())->bindingData(this);
|
auto *bd = qGetBindingStorage(owner())->bindingData(this);
|
||||||
@ -562,24 +578,45 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define Q_OBJECT_COMPAT_PROPERTY(Class, Type, name, setter) \
|
#define Q_OBJECT_COMPAT_PROPERTY4(Class, Type, name, setter) \
|
||||||
static constexpr size_t _qt_property_##name##_offset() { \
|
static constexpr size_t _qt_property_##name##_offset() { \
|
||||||
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
|
|
||||||
return offsetof(Class, name); \
|
return offsetof(Class, name); \
|
||||||
QT_WARNING_POP \
|
|
||||||
} \
|
} \
|
||||||
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter> name;
|
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter> name;
|
||||||
|
|
||||||
#define Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(Class, Type, name, setter, value) \
|
#define Q_OBJECT_COMPAT_PROPERTY5(Class, Type, name, setter, signal) \
|
||||||
static constexpr size_t _qt_property_##name##_offset() \
|
static constexpr size_t _qt_property_##name##_offset() { \
|
||||||
{ \
|
return offsetof(Class, name); \
|
||||||
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF return offsetof(Class, name); \
|
} \
|
||||||
QT_WARNING_POP \
|
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter, signal> name;
|
||||||
} \
|
|
||||||
|
#define Q_OBJECT_COMPAT_PROPERTY(...) \
|
||||||
|
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
|
||||||
|
QT_OVERLOADED_MACRO(Q_OBJECT_COMPAT_PROPERTY, __VA_ARGS__) \
|
||||||
|
QT_WARNING_POP
|
||||||
|
|
||||||
|
#define Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS5(Class, Type, name, setter, value) \
|
||||||
|
static constexpr size_t _qt_property_##name##_offset() { \
|
||||||
|
return offsetof(Class, name); \
|
||||||
|
} \
|
||||||
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter> name = \
|
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter> name = \
|
||||||
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter>( \
|
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter>( \
|
||||||
value);
|
value);
|
||||||
|
|
||||||
|
#define Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS6(Class, Type, name, setter, signal, value) \
|
||||||
|
static constexpr size_t _qt_property_##name##_offset() { \
|
||||||
|
return offsetof(Class, name); \
|
||||||
|
} \
|
||||||
|
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter> name = \
|
||||||
|
QObjectCompatProperty<Class, Type, Class::_qt_property_##name##_offset, setter>( \
|
||||||
|
value);
|
||||||
|
|
||||||
|
#define Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(...) \
|
||||||
|
QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
|
||||||
|
QT_OVERLOADED_MACRO(Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS, __VA_ARGS__) \
|
||||||
|
QT_WARNING_POP
|
||||||
|
|
||||||
|
|
||||||
namespace QtPrivate {
|
namespace QtPrivate {
|
||||||
Q_CORE_EXPORT BindingEvaluationState *suspendCurrentBindingStatus();
|
Q_CORE_EXPORT BindingEvaluationState *suspendCurrentBindingStatus();
|
||||||
Q_CORE_EXPORT void restoreBindingStatus(BindingEvaluationState *status);
|
Q_CORE_EXPORT void restoreBindingStatus(BindingEvaluationState *status);
|
||||||
|
@ -1422,9 +1422,9 @@ signals:
|
|||||||
void prop3Changed();
|
void prop3Changed();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setProp1(int val) { prop1Data.setValue(val); prop1Data.notify(); emit prop1Changed();}
|
void setProp1(int val) { prop1Data.setValue(val); prop1Data.notify();}
|
||||||
void setProp2(int val) { prop2Data.setValue(val); prop2Data.notify(); emit prop2Changed();}
|
void setProp2(int val) { prop2Data.setValue(val); prop2Data.notify();}
|
||||||
void setProp3(int val) { prop3Data.setValue(val); prop3Data.notify(); emit prop3Changed();}
|
void setProp3(int val) { prop3Data.setValue(val); prop3Data.notify();}
|
||||||
|
|
||||||
int prop1() { return prop1Data; }
|
int prop1() { return prop1Data; }
|
||||||
int prop2() { return prop2Data; }
|
int prop2() { return prop2Data; }
|
||||||
@ -1435,9 +1435,9 @@ public:
|
|||||||
QBindable<int> bindableProp3() { return QBindable<int>(&prop3Data); }
|
QBindable<int> bindableProp3() { return QBindable<int>(&prop3Data); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_OBJECT_COMPAT_PROPERTY(FakeDependencyCreator, int, prop1Data, &FakeDependencyCreator::setProp1);
|
Q_OBJECT_COMPAT_PROPERTY(FakeDependencyCreator, int, prop1Data, &FakeDependencyCreator::setProp1, &FakeDependencyCreator::prop1Changed);
|
||||||
Q_OBJECT_COMPAT_PROPERTY(FakeDependencyCreator, int, prop2Data, &FakeDependencyCreator::setProp2);
|
Q_OBJECT_COMPAT_PROPERTY(FakeDependencyCreator, int, prop2Data, &FakeDependencyCreator::setProp2, &FakeDependencyCreator::prop2Changed);
|
||||||
Q_OBJECT_COMPAT_PROPERTY(FakeDependencyCreator, int, prop3Data, &FakeDependencyCreator::setProp3);
|
Q_OBJECT_COMPAT_PROPERTY(FakeDependencyCreator, int, prop3Data, &FakeDependencyCreator::setProp3, &FakeDependencyCreator::prop3Changed);
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QProperty::noFakeDependencies()
|
void tst_QProperty::noFakeDependencies()
|
||||||
|
Loading…
Reference in New Issue
Block a user