summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2021-04-23 14:51:40 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2021-05-03 20:32:42 +0200
commitba561efa9d4e94032e7b546e92a3dc66c06bec52 (patch)
treec6e1e1f06a43d18b845d492ae6af5117fec25bbe /src
parent98b4f4bc4d87aa2f2c30adbcb8fd42abcc88d6fb (diff)
Add QUntypedBindable::metaType function
This enables checking the metaType of a QUntypedBindable in the public interface. In addition, work around an oversight that can only be fully addressed in Qt 7: The metatype function pointer does not take a QUntypedPropertyData * parameter. However, we need this functionality for an efficient QBindable proxy implementation in declarative (which is needed to implement interceptors there). To work-aronud this in Qt 6, reuse the value getter and turn it into a metatype getter if the value pointer is flagged. Change-Id: Ia3cce08ea761fce57bce59e02212525b996f2fee Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qproperty.cpp10
-rw-r--r--src/corelib/kernel/qproperty.h25
2 files changed, 31 insertions, 4 deletions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp
index 607048d94b..a1b2f83c5b 100644
--- a/src/corelib/kernel/qproperty.cpp
+++ b/src/corelib/kernel/qproperty.cpp
@@ -1006,6 +1006,16 @@ QString QPropertyBindingError::description() const
*/
/*!
+ \fn QMetaType QUntypedBindable::metaType() const
+ \since 6.2
+
+ Returns the metatype of the property from which the QUntypedBindable was created.
+ If the bindable is invalid, an invalid metatype will be returned.
+
+ \sa isValid(), QUntypedPropertyBinding::valueMetaType()
+*/
+
+/*!
\class QBindable
\inmodule QtCore
\brief QBindable is a wrapper class around binding-enabled properties. It allows type-safe
diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h
index 9be10c0a31..7924049698 100644
--- a/src/corelib/kernel/qproperty.h
+++ b/src/corelib/kernel/qproperty.h
@@ -484,6 +484,8 @@ struct QBindableInterface
MakeBinding makeBinding;
SetObserver setObserver;
GetMetaType metaType;
+
+ static constexpr quintptr MetaTypeAccessorFlag = 0x1;
};
template<typename Property, typename = void>
@@ -650,9 +652,9 @@ public:
#endif
return false;
}
- if (!binding.isNull() && binding.valueMetaType() != iface->metaType()) {
+ if (!binding.isNull() && binding.valueMetaType() != metaType()) {
#ifndef QT_NO_DEBUG
- QtPrivate::BindableWarnings::printMetaTypeMismatch(iface->metaType(), binding.valueMetaType());
+ QtPrivate::BindableWarnings::printMetaTypeMismatch(metaType(), binding.valueMetaType());
#endif
return false;
}
@@ -664,6 +666,21 @@ public:
return !binding().isNull();
}
+ QMetaType metaType() const
+ {
+ if (!(iface && data))
+ return QMetaType();
+ if (iface->metaType)
+ return iface->metaType();
+ // ### Qt 7: Change the metatype function to take data as its argument
+ // special casing for QML's proxy bindable: allow multiplexing in the getter
+ // function to retrieve the metatype from data
+ Q_ASSERT(iface->getter);
+ QMetaType result;
+ iface->getter(data, reinterpret_cast<void *>(quintptr(&result) | QtPrivate::QBindableInterface::MetaTypeAccessorFlag));
+ return result;
+ }
+
};
template<typename T>
@@ -678,7 +695,7 @@ public:
using QUntypedBindable::QUntypedBindable;
explicit QBindable(const QUntypedBindable &b) : QUntypedBindable(b)
{
- if (iface && iface->metaType() != QMetaType::fromType<T>()) {
+ if (iface && metaType() != QMetaType::fromType<T>()) {
data = nullptr;
iface = nullptr;
}
@@ -701,7 +718,7 @@ public:
using QUntypedBindable::setBinding;
QPropertyBinding<T> setBinding(const QPropertyBinding<T> &binding)
{
- Q_ASSERT(!iface || binding.isNull() || binding.valueMetaType() == iface->metaType());
+ Q_ASSERT(!iface || binding.isNull() || binding.valueMetaType() == metaType());
if (iface && iface->setBinding)
return static_cast<QPropertyBinding<T> &&>(iface->setBinding(data, binding));