diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-05-24 13:00:20 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-06-22 20:49:20 +0200 |
commit | b48bb41681f561b59a4ce9c9d0ac95b23d5ccb1e (patch) | |
tree | fd7ab379417d79e9190544723e462813c6a3db9f /src/qml/jsruntime/qv4executablecompilationunit_p.h | |
parent | 4a1e5d8e74e59da3191c27a732ca1a50bd2f0045 (diff) |
QML: Use QQmlType as container for composite types (inline or not)
This gives us a unified interface to all kinds of QML types at run time
and reduces the effort of finding corresponding type attributes.
QQmlType is much larger than CompositeMetaTypeIds. Most composite types,
however, are initially referenced by URL, and we call typeForUrl anyway.
typeForUrl already creates a mostly functional QQmlType; we only need to
add the dynamic metatypes. The same type can be retrieved later and
associated with the actual CU using the compositeTypes hash. That way,
we don't need any extra type. We do, however, incur the cost of creating
the QMetaTypePrivate instances when first referencing a type. This could
be optimized, like many things in this area, by using thread safe lazy
initialization.
Now some QQmlTypes implicitly depend on the CUs they were created for.
This creates problems if the CUs are removed but the types still
persist. Such a situation can arise if you create and delete engines. In
order to avoid it, we:
1. Make the compositeTypes hold a strong reference to the CUs
2. When unlinking, avoid dropping the property caches (as those are used
to hold the metaobjects)
Now, however we got a cyclic reference between the CU and its
QQmlType(s). To resolve this, we clear the QQmlTypes on unlinking.
Finally, to avoid deletion recursion when clearing the last CUs on
destruction of the QQmlMetaTypeData, we move the compilation units out
of the way first.
All of this still doesn't work if multiple CUs hold the same QQmlType,
since compositeTypes can only hold one CU per type and that may be the
one that gets removed first. Therefore, we cannot allow such a situation
to happen and have to create a new QQmlType if it arises. It can only
arise if you have multiple engines loading the same QML components,
which should be fairly rare.
For inline components, we apply a similar trick: You can either find an
inline component by Url, and receive any type that matches, no matter
what CU it belongs to. Or you can request an inline component type that
belongs to a specific CU. It turns out we don't have to store the
containing type of an IC at all. Also, we slightly change the naming of
internal components' "class names" since we want to use the inline
components' element names for them.
Change-Id: I0ef89bd4b0a02cc927aed2525e72f6bff56df626
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4executablecompilationunit_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit_p.h | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index b110ea3fd1..b9ff76eab8 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -34,15 +34,17 @@ class QQmlEnginePrivate; struct InlineComponentData { InlineComponentData() = default; - InlineComponentData(const CompositeMetaTypeIds &typeIds, int objectIndex, int nameIndex, int totalObjectCount, int totalBindingCount, int totalParserStatusCount) - : typeIds(typeIds) - , objectIndex(objectIndex) - , nameIndex(nameIndex) - , totalObjectCount(totalObjectCount) - , totalBindingCount(totalBindingCount) - , totalParserStatusCount(totalParserStatusCount) {} - - CompositeMetaTypeIds typeIds; + InlineComponentData( + const QQmlType &qmlType, int objectIndex, int nameIndex, int totalObjectCount, + int totalBindingCount, int totalParserStatusCount) + : qmlType(qmlType) + , objectIndex(objectIndex) + , nameIndex(nameIndex) + , totalObjectCount(totalObjectCount) + , totalBindingCount(totalBindingCount) + , totalParserStatusCount(totalParserStatusCount) {} + + QQmlType qmlType; int objectIndex = -1; int nameIndex = -1; int totalObjectCount = 0; @@ -126,7 +128,7 @@ public: QHash<int, IdentifierHash> namedObjectsPerComponentCache; inline IdentifierHash namedObjectsPerComponent(int componentObjectIndex); - void finalizeCompositeType(CompositeMetaTypeIds typeIdsForComponent); + void finalizeCompositeType(const QQmlType &type); int m_totalBindingsCount = 0; // Number of bindings used in this type int m_totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses @@ -143,10 +145,9 @@ public: bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const; - CompositeMetaTypeIds typeIdsForComponent(const QString &inlineComponentName = QString()) const; + QQmlType qmlTypeForComponent(const QString &inlineComponentName = QString()) const; - CompositeMetaTypeIds typeIds; - bool isRegistered = false; + QQmlType qmlType; QHash<QString, InlineComponentData> inlineComponentData; |