diff options
-rw-r--r-- | src/corelib/kernel/qproperty.h | 12 | ||||
-rw-r--r-- | src/corelib/kernel/qpropertybinding.cpp | 32 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp | 16 |
3 files changed, 31 insertions, 29 deletions
diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index 8f050327d5..e43f59053d 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -117,10 +117,8 @@ private: class Q_CORE_EXPORT QUntypedPropertyBinding { public: - // Returns either a boolean to indicate value change or an error. - using BindingEvaluationResult = std::variant<bool, QPropertyBindingError>; - // returns true if value changed, false if the binding evaluation lead to the same value as the property - // already has. + using BindingEvaluationResult = QPropertyBindingError; + // writes binding result into dataPtr using BindingEvaluationFunction = std::function<BindingEvaluationResult(const QMetaType &metaType, void *dataPtr)>; QUntypedPropertyBinding(); @@ -160,13 +158,11 @@ class QPropertyBinding : public QUntypedPropertyBinding if (auto valuePtr = std::get_if<PropertyType>(&result)) { PropertyType *propertyPtr = reinterpret_cast<PropertyType *>(dataPtr); - if (*propertyPtr == *valuePtr) - return false; *propertyPtr = std::move(*valuePtr); - return true; + return {}; } - return false; + return {}; } }; diff --git a/src/corelib/kernel/qpropertybinding.cpp b/src/corelib/kernel/qpropertybinding.cpp index 358977e63e..29b1a4a69a 100644 --- a/src/corelib/kernel/qpropertybinding.cpp +++ b/src/corelib/kernel/qpropertybinding.cpp @@ -41,6 +41,7 @@ #include "qproperty_p.h" #include <QScopedValueRollback> +#include <QVariant> QT_BEGIN_NAMESPACE @@ -80,25 +81,34 @@ bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged() BindingEvaluationState evaluationFrame(this); + QPropertyBindingError evalError; QUntypedPropertyBinding::BindingEvaluationResult result; bool changed = false; if (metaType.id() == QMetaType::Bool) { auto propertyPtr = reinterpret_cast<QPropertyBase *>(propertyDataPtr); - bool temp = propertyPtr->extraBit(); - result = evaluationFunction(metaType, &temp); - if (auto changedPtr = std::get_if<bool>(&result)) { - changed = *changedPtr; - if (changed) - propertyPtr->setExtraBit(temp); + bool newValue = false; + evalError = evaluationFunction(metaType, &newValue); + if (evalError.type() == QPropertyBindingError::NoError) { + if (propertyPtr->extraBit() != newValue) { + propertyPtr->setExtraBit(newValue); + changed = true; + } } } else { - result = evaluationFunction(metaType, propertyDataPtr); - if (auto changedPtr = std::get_if<bool>(&result)) - changed = *changedPtr; + QVariant resultVariant(metaType.id(), nullptr); + evalError = evaluationFunction(metaType, resultVariant.data()); + if (evalError.type() == QPropertyBindingError::NoError) { + int compareResult = 0; + if (!QMetaType::compare(propertyDataPtr, resultVariant.constData(), metaType.id(), &compareResult) || compareResult != 0) { + changed = true; + metaType.destruct(propertyDataPtr); + metaType.construct(propertyDataPtr, resultVariant.constData()); + } + } } - if (auto errorPtr = std::get_if<QPropertyBindingError>(&result)) - error = std::move(*errorPtr); + if (evalError.type() != QPropertyBindingError::NoError) + error = evalError; dirty = false; return changed; diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp index cc04c2f1b5..488ecacb8d 100644 --- a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp +++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp @@ -617,22 +617,20 @@ void tst_QProperty::genericPropertyBinding() { QUntypedPropertyBinding doubleBinding(QMetaType::fromType<double>(), - [](const QMetaType &, void *) -> bool { + [](const QMetaType &, void *) -> QUntypedPropertyBinding::BindingEvaluationResult { Q_ASSERT(false); - return false; + return QPropertyBindingError::NoError; }, QPropertyBindingSourceLocation()); QVERIFY(!property.setBinding(doubleBinding)); } QUntypedPropertyBinding intBinding(QMetaType::fromType<int>(), - [](const QMetaType &metaType, void *dataPtr) -> bool { + [](const QMetaType &metaType, void *dataPtr) -> QUntypedPropertyBinding::BindingEvaluationResult { Q_ASSERT(metaType.id() == qMetaTypeId<int>()); int *intPtr = reinterpret_cast<int*>(dataPtr); - if (*intPtr == 100) - return false; *intPtr = 100; - return true; + return QPropertyBindingError::NoError; }, QPropertyBindingSourceLocation()); QVERIFY(property.setBinding(intBinding)); @@ -647,12 +645,10 @@ void tst_QProperty::genericPropertyBindingBool() QVERIFY(!property.value()); QUntypedPropertyBinding boolBinding(QMetaType::fromType<bool>(), - [](const QMetaType &, void *dataPtr) -> bool { + [](const QMetaType &, void *dataPtr) -> QUntypedPropertyBinding::BindingEvaluationResult { auto boolPtr = reinterpret_cast<bool *>(dataPtr); - if (*boolPtr) - return false; *boolPtr = true; - return true; + return {}; }, QPropertyBindingSourceLocation()); QVERIFY(property.setBinding(boolBinding)); |