1 | // Copyright (C) 2024 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 QV4QMETAOBJECTWRAPPER_P_H |
5 | #define QV4QMETAOBJECTWRAPPER_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 <private/qv4functionobject_p.h> |
19 | #include <private/qv4value_p.h> |
20 | |
21 | #include <QtCore/qmetaobject.h> |
22 | |
23 | QT_BEGIN_NAMESPACE |
24 | |
25 | class QQmlPropertyData; |
26 | |
27 | namespace QV4 { |
28 | namespace Heap { |
29 | |
30 | struct QMetaObjectWrapper : FunctionObject |
31 | { |
32 | void init(const QMetaObject *metaObject); |
33 | void destroy(); |
34 | |
35 | const QMetaObject *metaObject() const { return m_metaObject; } |
36 | QMetaType metaType() const |
37 | { |
38 | const QMetaType type = m_metaObject->metaType(); |
39 | if (type.flags() & QMetaType::IsGadget) |
40 | return type; |
41 | |
42 | // QObject* is our best guess because we can't get from a metatype to |
43 | // the metatype of its pointer. |
44 | return QMetaType::fromType<QObject *>(); |
45 | } |
46 | |
47 | const QQmlPropertyData *ensureConstructorsCache( |
48 | const QMetaObject *metaObject, QMetaType metaType) |
49 | { |
50 | Q_ASSERT(metaObject); |
51 | if (!m_constructors) |
52 | m_constructors = createConstructors(metaObject, metaType); |
53 | return m_constructors; |
54 | } |
55 | |
56 | |
57 | static const QQmlPropertyData *createConstructors( |
58 | const QMetaObject *metaObject, QMetaType metaType) |
59 | { |
60 | Q_ASSERT(metaObject); |
61 | const int count = metaObject->constructorCount(); |
62 | if (count == 0) |
63 | return nullptr; |
64 | |
65 | QQmlPropertyData *constructors = new QQmlPropertyData[count]; |
66 | |
67 | for (int i = 0; i < count; ++i) { |
68 | QMetaMethod method = metaObject->constructor(index: i); |
69 | QQmlPropertyData &d = constructors[i]; |
70 | d.load(method); |
71 | d.setPropType(metaType); |
72 | d.setCoreIndex(i); |
73 | } |
74 | |
75 | return constructors; |
76 | } |
77 | |
78 | private: |
79 | const QMetaObject *m_metaObject; |
80 | const QQmlPropertyData *m_constructors; |
81 | }; |
82 | |
83 | } // namespace Heap |
84 | |
85 | struct Q_QML_EXPORT QMetaObjectWrapper : public FunctionObject |
86 | { |
87 | V4_OBJECT2(QMetaObjectWrapper, FunctionObject) |
88 | V4_NEEDS_DESTROY |
89 | |
90 | static ReturnedValue create(ExecutionEngine *engine, const QMetaObject* metaObject); |
91 | const QMetaObject *metaObject() const { return d()->metaObject(); } |
92 | |
93 | template<typename HeapObject> |
94 | ReturnedValue static construct(HeapObject *d, const Value *argv, int argc) |
95 | { |
96 | const QMetaObject *mo = d->metaObject(); |
97 | return constructInternal( |
98 | mo, constructors: d->ensureConstructorsCache(mo, d->metaType()), d, argv, argc); |
99 | } |
100 | |
101 | protected: |
102 | static ReturnedValue virtualCallAsConstructor( |
103 | const FunctionObject *, const Value *argv, int argc, const Value *); |
104 | static bool virtualIsEqualTo(Managed *a, Managed *b); |
105 | |
106 | private: |
107 | void init(ExecutionEngine *engine); |
108 | |
109 | static ReturnedValue constructInternal( |
110 | const QMetaObject *mo, const QQmlPropertyData *constructors, Heap::FunctionObject *d, |
111 | const Value *argv, int argc); |
112 | }; |
113 | |
114 | } // namespace QV4 |
115 | |
116 | QT_END_NAMESPACE |
117 | |
118 | #endif // QV4QMETAOBJECTWRAPPER_P_H |
119 | |
120 | |
121 | |