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>bb10
parent
98b4f4bc4d
commit
ba561efa9d
|
|
@ -1005,6 +1005,16 @@ QString QPropertyBindingError::description() const
|
|||
Returns \c true if the underlying property has a binding.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
Loading…
Reference in New Issue