1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQMLTCOBJECTCREATIONHELPER_P_H
5#define QQMLTCOBJECTCREATIONHELPER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtQml/qqml.h>
19#include <QtCore/private/qglobal_p.h>
20#include <QtCore/qversionnumber.h>
21#include <private/qtqmlglobal_p.h>
22#include <private/qqmltype_p.h>
23
24#include <array>
25
26QT_BEGIN_NAMESPACE
27
28/*!
29 \internal
30
31 (Kind of) type-erased object creation utility that can be used throughout
32 the generated C++ code. By nature it shows relative data to the current QML
33 document and allows to get and set object pointers.
34 */
35class QQmltcObjectCreationHelper
36{
37 QObject **m_data = nullptr; // QObject* array
38 const qsizetype m_size = 0; // size of m_data array, exists for bounds checking
39 const qsizetype m_offset = 0; // global offset into m_data array
40
41 qsizetype offset() const { return m_offset; }
42
43public:
44 /*!
45 Constructs initial "view" from basic data. Supposed to only be called
46 once from QQmltcObjectCreationBase.
47 */
48 QQmltcObjectCreationHelper(QObject **data, qsizetype size) : m_data(data), m_size(size)
49 {
50 Q_UNUSED(m_size);
51 }
52
53 /*!
54 Constructs new "view" from \a base view, adding \a localOffset to the
55 offset of that base.
56 */
57 QQmltcObjectCreationHelper(const QQmltcObjectCreationHelper *base, qsizetype localOffset)
58 : m_data(base->m_data), m_size(base->m_size), m_offset(base->m_offset + localOffset)
59 {
60 }
61
62 template<typename T>
63 T *get(qsizetype i) const
64 {
65 Q_ASSERT(m_data);
66 Q_ASSERT(i >= 0 && i + offset() < m_size);
67 Q_ASSERT(qobject_cast<T *>(m_data[i + offset()]) != nullptr);
68 // Note: perform cheap cast as we know *exactly* the real type of the
69 // object
70 return static_cast<T *>(m_data[i + offset()]);
71 }
72
73 void set(qsizetype i, QObject *object)
74 {
75 Q_ASSERT(m_data);
76 Q_ASSERT(i >= 0 && i + offset() < m_size);
77 Q_ASSERT(m_data[i + offset()] == nullptr); // prevent accidental resets
78 m_data[i + offset()] = object;
79 }
80
81 template<typename T>
82 static constexpr uint typeCount() noexcept
83 {
84 return T::q_qmltc_typeCount();
85 }
86};
87
88/*!
89 \internal
90
91 Base helper for qmltc-generated types that linearly stores pointers to all
92 the to-be-created objects for fast access during object creation.
93 */
94template<typename QmltcGeneratedType>
95class QQmltcObjectCreationBase
96{
97 // Note: +1 for the document root itself
98 std::array<QObject *, QmltcGeneratedType::q_qmltc_typeCount() + 1> m_objects = {};
99
100public:
101 QQmltcObjectCreationHelper view()
102 {
103 return QQmltcObjectCreationHelper(m_objects.data(), m_objects.size());
104 }
105};
106
107struct QmltcTypeData
108{
109 QQmlType::RegistrationType regType = QQmlType::CppType;
110 int allocationSize = 0;
111 const QMetaObject *metaObject = nullptr;
112
113 template<typename QmltcGeneratedType>
114 QmltcTypeData(QmltcGeneratedType *)
115 : allocationSize(sizeof(QmltcGeneratedType)),
116 metaObject(&QmltcGeneratedType::staticMetaObject)
117 {
118 }
119};
120
121Q_QML_PRIVATE_EXPORT void qmltcCreateDynamicMetaObject(QObject *object, const QmltcTypeData &data);
122
123QT_END_NAMESPACE
124
125#endif // QQMLTCOBJECTCREATIONHELPER_P_H
126

source code of qtdeclarative/src/qml/qmltc/qqmltcobjectcreationhelper_p.h