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