summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qproperty.cpp4
-rw-r--r--src/corelib/kernel/qproperty_p.h23
2 files changed, 25 insertions, 2 deletions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp
index d2fd572b69..e2c5c7bff3 100644
--- a/src/corelib/kernel/qproperty.cpp
+++ b/src/corelib/kernel/qproperty.cpp
@@ -105,6 +105,8 @@ void QPropertyBindingPrivate::markDirtyAndNotifyObservers()
dirty = true;
if (eagerlyUpdating) {
error = QPropertyBindingError(QPropertyBindingError::BindingLoop);
+ if (isQQmlPropertyBinding)
+ errorCallBack(this);
return;
}
@@ -129,6 +131,8 @@ bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged_helper(
if (updating) {
error = QPropertyBindingError(QPropertyBindingError::BindingLoop);
+ if (isQQmlPropertyBinding)
+ errorCallBack(this);
return false;
}
diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h
index e88547569e..d5feef1008 100644
--- a/src/corelib/kernel/qproperty_p.h
+++ b/src/corelib/kernel/qproperty_p.h
@@ -176,6 +176,7 @@ private:
bool hasBindingWrapper:1;
// used to detect binding loops for eagerly evaluated properties
bool eagerlyUpdating:1;
+ bool isQQmlPropertyBinding:1;
const QtPrivate::BindingFunctionVTable *vtable;
@@ -190,7 +191,24 @@ private:
QUntypedPropertyData *propertyDataPtr = nullptr;
- QPropertyBindingSourceLocation location;
+ /* For bindings set up from C++, location stores where the binding was created in the C++ source
+ For QQmlPropertyBinding that information does not make sense, and the location in the QML file
+ is stored somewhere else. To make efficient use of the space, we instead provide a scratch space
+ for QQmlPropertyBinding (which stores further binding information there).
+ Anything stored in the union must be trivially destructible.
+ */
+ static_assert(std::is_trivially_destructible_v<QPropertyBindingSourceLocation>);
+ static_assert(std::is_trivially_destructible_v<std::byte[sizeof(QPropertyBindingSourceLocation)]>);
+protected:
+ using DeclarativeErrorCallback = void(*)(QPropertyBindingPrivate *);
+ union {
+ QPropertyBindingSourceLocation location;
+ struct {
+ std::byte declarativeExtraData[sizeof(QPropertyBindingSourceLocation) - sizeof(DeclarativeErrorCallback)];
+ DeclarativeErrorCallback errorCallBack;
+ };
+ };
+private:
QPropertyBindingError error;
QMetaType metaType;
@@ -209,9 +227,10 @@ public:
size_t dependencyObserverCount = 0;
QPropertyBindingPrivate(QMetaType metaType, const QtPrivate::BindingFunctionVTable *vtable,
- const QPropertyBindingSourceLocation &location)
+ const QPropertyBindingSourceLocation &location, bool isQQmlPropertyBinding=false)
: hasBindingWrapper(false)
, eagerlyUpdating(false)
+ , isQQmlPropertyBinding(isQQmlPropertyBinding)
, vtable(vtable)
, inlineDependencyObservers() // Explicit initialization required because of union
, location(location)