summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qproperty.h12
-rw-r--r--src/corelib/kernel/qpropertybinding.cpp32
-rw-r--r--tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp16
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));