aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlprivate.h
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-09-16 16:41:27 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-09-23 14:54:46 +0200
commit8e222a70d19d5eef616e1d6306415da64fbab4cb (patch)
tree535e4cd02c2dbca0289bc6ec39f2699856554737 /src/qml/qml/qqmlprivate.h
parent90b5d7fa03f9818fa5edc897ee6a109fcc182b9e (diff)
Allow proper registration of value types
You can now have an extension object on a value type that offers additional properties. This is how we model the QtQuick value types. It allows us to retrieve the extension's metaobject without using the virtual functions in the value type provider. As before, this mechanism is still rather dangerous and not fit for public consumption. It relies on the extension object having exactly the same layout as the original value type, and it hides any properties the original value type might expose. Furthermore we enforce now that gadgets should have lowercase names. The ones that didn't before are split up into an anonymous value type and a namespace that contains all the addressable bits. Task-number: QTBUG-82443 Change-Id: Ic93d6764538d6ccc0774b3c5648eee08ba0939c0 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlprivate.h')
-rw-r--r--src/qml/qml/qqmlprivate.h69
1 files changed, 55 insertions, 14 deletions
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index e0de749fb3..91b8eb5283 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -182,23 +182,32 @@ namespace QQmlPrivate
static constexpr CreateSingletonFunction createSingletonInstance = nullptr;
};
- template<typename T, bool IsVoid = std::is_void<T>::value>
+ template<typename T,
+ bool IsObject = std::is_base_of<QObject, T>::value,
+ bool IsGadget = QtPrivate::IsGadgetHelper<T>::IsRealGadget>
struct ExtendedType;
- // void means "not an extended type"
template<typename T>
- struct ExtendedType<T, true>
+ struct ExtendedType<T, false, false>
{
static constexpr const CreateParentFunction createParent = nullptr;
- static constexpr const QMetaObject *staticMetaObject = nullptr;
+ static const QMetaObject *staticMetaObject() { return nullptr; }
};
- // If it's not void, we actually want an error if the ctor or the metaobject is missing.
+ // If it's a QObject, we actually want an error if the ctor or the metaobject is missing.
template<typename T>
- struct ExtendedType<T, false>
+ struct ExtendedType<T, true, false>
{
static constexpr const CreateParentFunction createParent = QQmlPrivate::createParent<T>;
- static constexpr const QMetaObject *staticMetaObject = &T::staticMetaObject;
+ static const QMetaObject *staticMetaObject() { return &T::staticMetaObject; }
+ };
+
+ // If it's a Q_GADGET, we don't want the ctor.
+ template<typename T>
+ struct ExtendedType<T, false, true>
+ {
+ static constexpr const CreateParentFunction createParent = nullptr;
+ static const QMetaObject *staticMetaObject() { return &T::staticMetaObject; }
};
template<class From, class To, int N>
@@ -561,7 +570,7 @@ namespace QQmlPrivate
};
template<class T>
- struct QmlResolved<T, std::void_t<decltype(T::QmlForeignType::staticMetaObject)>>
+ struct QmlResolved<T, std::void_t<typename T::QmlForeignType>>
{
using Type = typename T::QmlForeignType;
};
@@ -590,6 +599,38 @@ namespace QQmlPrivate
static constexpr bool Value = bool(T::QmlIsInterface::yes);
};
+ template<class T, typename = std::void_t<>>
+ struct StaticMetaObject
+ {
+ static const QMetaObject *staticMetaObject() { return nullptr; }
+ };
+
+ template<class T>
+ struct StaticMetaObject<T, std::void_t<decltype(T::staticMetaObject)>>
+ {
+ static const QMetaObject *staticMetaObject() { return &T::staticMetaObject; }
+ };
+
+ template<class T>
+ struct QmlMetaType
+ {
+ static QMetaType self()
+ {
+ if constexpr (std::is_base_of_v<QObject, T>)
+ return QMetaType::fromType<T*>();
+ else
+ return QMetaType::fromType<T>();
+ }
+
+ static QMetaType list()
+ {
+ if constexpr (std::is_base_of_v<QObject, T>)
+ return QMetaType::fromType<QQmlListProperty<T>>();
+ else
+ return QMetaType();
+ }
+ };
+
template<typename T>
void qmlRegisterSingletonAndRevisions(const char *uri, int versionMajor,
const QMetaObject *classInfoMetaObject,
@@ -603,10 +644,10 @@ namespace QQmlPrivate
Constructors<T>::createSingletonInstance,
- &T::staticMetaObject,
+ StaticMetaObject<T>::staticMetaObject(),
classInfoMetaObject,
- QMetaType::fromType<T *>(),
+ QmlMetaType<T>::self(),
qmlTypeIds
};
@@ -620,15 +661,15 @@ namespace QQmlPrivate
{
RegisterTypeAndRevisions type = {
0,
- QMetaType::fromType<T*>(),
- QMetaType::fromType<QQmlListProperty<T>>(),
+ QmlMetaType<T>::self(),
+ QmlMetaType<T>::list(),
int(sizeof(T)),
Constructors<T>::createInto, nullptr,
uri,
QTypeRevision::fromMajorVersion(versionMajor),
- &T::staticMetaObject,
+ StaticMetaObject<T>::staticMetaObject(),
classInfoMetaObject,
attachedPropertiesFunc<T>(),
@@ -639,7 +680,7 @@ namespace QQmlPrivate
StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(),
ExtendedType<E>::createParent,
- ExtendedType<E>::staticMetaObject,
+ ExtendedType<E>::staticMetaObject(),
&qmlCreateCustomParser<T>,
qmlTypeIds