1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtQml module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #ifndef QQMLPRIVATE_H |
41 | #define QQMLPRIVATE_H |
42 | |
43 | // |
44 | // W A R N I N G |
45 | // ------------- |
46 | // |
47 | // This file is not part of the Qt API. It exists purely as an |
48 | // implementation detail. This header file may change from version to |
49 | // version without notice, or even be removed. |
50 | // |
51 | // We mean it. |
52 | // |
53 | |
54 | #include <functional> |
55 | |
56 | #include <QtQml/qtqmlglobal.h> |
57 | |
58 | #include <QtCore/qglobal.h> |
59 | #include <QtCore/qvariant.h> |
60 | #include <QtCore/qurl.h> |
61 | |
62 | QT_BEGIN_NAMESPACE |
63 | |
64 | namespace QQmlPrivate { |
65 | struct CachedQmlUnit; |
66 | } |
67 | |
68 | namespace QV4 { |
69 | struct ExecutionEngine; |
70 | namespace CompiledData { |
71 | struct Unit; |
72 | struct CompilationUnit; |
73 | } |
74 | } |
75 | namespace QmlIR { |
76 | struct Document; |
77 | typedef void (*IRLoaderFunction)(Document *, const QQmlPrivate::CachedQmlUnit *); |
78 | } |
79 | |
80 | typedef QObject *(*QQmlAttachedPropertiesFunc)(QObject *); |
81 | |
82 | inline uint qHash(QQmlAttachedPropertiesFunc func, uint seed = 0) |
83 | { |
84 | return qHash(quintptr(func), seed); |
85 | } |
86 | |
87 | template <typename TYPE> |
88 | class QQmlTypeInfo |
89 | { |
90 | public: |
91 | enum { |
92 | hasAttachedProperties = 0 |
93 | }; |
94 | }; |
95 | |
96 | |
97 | class QJSValue; |
98 | class QJSEngine; |
99 | class QQmlEngine; |
100 | class QQmlCustomParser; |
101 | namespace QQmlPrivate |
102 | { |
103 | void Q_QML_EXPORT qdeclarativeelement_destructor(QObject *); |
104 | template<typename T> |
105 | class QQmlElement final : public T |
106 | { |
107 | public: |
108 | ~QQmlElement() override { |
109 | QQmlPrivate::qdeclarativeelement_destructor(this); |
110 | } |
111 | static void operator delete(void *ptr) { |
112 | // We allocate memory from this class in QQmlType::create |
113 | // along with some additional memory. |
114 | // So we override the operator delete in order to avoid the |
115 | // sized operator delete to be called with a different size than |
116 | // the size that was allocated. |
117 | ::operator delete (ptr); |
118 | } |
119 | static void operator delete(void *, void *) { |
120 | // Deliberately empty placement delete operator. |
121 | // Silences MSVC warning C4291: no matching operator delete found |
122 | } |
123 | }; |
124 | |
125 | template<typename T> |
126 | void createInto(void *memory) { new (memory) QQmlElement<T>; } |
127 | |
128 | template<typename T> |
129 | QObject *createParent(QObject *p) { return new T(p); } |
130 | |
131 | template<class From, class To, int N> |
132 | struct StaticCastSelectorClass |
133 | { |
134 | static inline int cast() { return -1; } |
135 | }; |
136 | |
137 | template<class From, class To> |
138 | struct StaticCastSelectorClass<From, To, sizeof(int)> |
139 | { |
140 | static inline int cast() { return int(reinterpret_cast<quintptr>(static_cast<To *>(reinterpret_cast<From *>(0x10000000)))) - 0x10000000; } |
141 | }; |
142 | |
143 | template<class From, class To> |
144 | struct StaticCastSelector |
145 | { |
146 | typedef int yes_type; |
147 | typedef char no_type; |
148 | |
149 | static yes_type checkType(To *); |
150 | static no_type checkType(...); |
151 | |
152 | static inline int cast() |
153 | { |
154 | return StaticCastSelectorClass<From, To, sizeof(checkType(reinterpret_cast<From *>(0)))>::cast(); |
155 | } |
156 | }; |
157 | |
158 | template <typename T> |
159 | struct has_attachedPropertiesMember |
160 | { |
161 | static bool const value = QQmlTypeInfo<T>::hasAttachedProperties; |
162 | }; |
163 | |
164 | template <typename T, bool hasMember> |
165 | class has_attachedPropertiesMethod |
166 | { |
167 | public: |
168 | typedef int yes_type; |
169 | typedef char no_type; |
170 | |
171 | template<typename ReturnType> |
172 | static yes_type checkType(ReturnType *(*)(QObject *)); |
173 | static no_type checkType(...); |
174 | |
175 | static bool const value = sizeof(checkType(&T::qmlAttachedProperties)) == sizeof(yes_type); |
176 | }; |
177 | |
178 | template <typename T> |
179 | class has_attachedPropertiesMethod<T, false> |
180 | { |
181 | public: |
182 | static bool const value = false; |
183 | }; |
184 | |
185 | template<typename T, int N> |
186 | class AttachedPropertySelector |
187 | { |
188 | public: |
189 | static inline QQmlAttachedPropertiesFunc func() { return nullptr; } |
190 | static inline const QMetaObject *metaObject() { return nullptr; } |
191 | }; |
192 | template<typename T> |
193 | class AttachedPropertySelector<T, 1> |
194 | { |
195 | template<typename ReturnType> |
196 | static inline const QMetaObject *attachedPropertiesMetaObject(ReturnType *(*)(QObject *)) { |
197 | return &ReturnType::staticMetaObject; |
198 | } |
199 | public: |
200 | static inline QQmlAttachedPropertiesFunc func() { |
201 | return QQmlAttachedPropertiesFunc(&T::qmlAttachedProperties); |
202 | } |
203 | static inline const QMetaObject *metaObject() { |
204 | return attachedPropertiesMetaObject(&T::qmlAttachedProperties); |
205 | } |
206 | }; |
207 | |
208 | template<typename T> |
209 | inline QQmlAttachedPropertiesFunc attachedPropertiesFunc() |
210 | { |
211 | return AttachedPropertySelector<T, has_attachedPropertiesMethod<T, has_attachedPropertiesMember<T>::value>::value>::func(); |
212 | } |
213 | |
214 | template<typename T> |
215 | inline const QMetaObject *attachedPropertiesMetaObject() |
216 | { |
217 | return AttachedPropertySelector<T, has_attachedPropertiesMethod<T, has_attachedPropertiesMember<T>::value>::value>::metaObject(); |
218 | } |
219 | |
220 | enum AutoParentResult { Parented, IncompatibleObject, IncompatibleParent }; |
221 | typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent); |
222 | |
223 | struct RegisterType { |
224 | int version; |
225 | |
226 | int typeId; |
227 | int listId; |
228 | int objectSize; |
229 | void (*create)(void *); |
230 | QString noCreationReason; |
231 | |
232 | const char *uri; |
233 | int versionMajor; |
234 | int versionMinor; |
235 | const char *elementName; |
236 | const QMetaObject *metaObject; |
237 | |
238 | QQmlAttachedPropertiesFunc attachedPropertiesFunction; |
239 | const QMetaObject *attachedPropertiesMetaObject; |
240 | |
241 | int parserStatusCast; |
242 | int valueSourceCast; |
243 | int valueInterceptorCast; |
244 | |
245 | QObject *(*extensionObjectCreate)(QObject *); |
246 | const QMetaObject *extensionMetaObject; |
247 | |
248 | QQmlCustomParser *customParser; |
249 | int revision; |
250 | // If this is extended ensure "version" is bumped!!! |
251 | }; |
252 | |
253 | struct RegisterInterface { |
254 | int version; |
255 | |
256 | int typeId; |
257 | int listId; |
258 | |
259 | const char *iid; |
260 | }; |
261 | |
262 | struct RegisterAutoParent { |
263 | int version; |
264 | |
265 | AutoParentFunction function; |
266 | }; |
267 | |
268 | struct RegisterSingletonType { |
269 | int version; |
270 | |
271 | const char *uri; |
272 | int versionMajor; |
273 | int versionMinor; |
274 | const char *typeName; |
275 | |
276 | QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *); |
277 | QObject *(*qobjectApi)(QQmlEngine *, QJSEngine *); |
278 | const QMetaObject *instanceMetaObject; // new in version 1 |
279 | int typeId; // new in version 2 |
280 | int revision; // new in version 2 |
281 | std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3 |
282 | // If this is extended ensure "version" is bumped!!! |
283 | }; |
284 | |
285 | struct RegisterCompositeType { |
286 | QUrl url; |
287 | const char *uri; |
288 | int versionMajor; |
289 | int versionMinor; |
290 | const char *typeName; |
291 | }; |
292 | |
293 | struct RegisterCompositeSingletonType { |
294 | QUrl url; |
295 | const char *uri; |
296 | int versionMajor; |
297 | int versionMinor; |
298 | const char *typeName; |
299 | }; |
300 | |
301 | struct CachedQmlUnit { |
302 | const QV4::CompiledData::Unit *qmlData; |
303 | void *unused1; |
304 | void *unused2; |
305 | }; |
306 | |
307 | typedef const CachedQmlUnit *(*QmlUnitCacheLookupFunction)(const QUrl &url); |
308 | struct RegisterQmlUnitCacheHook { |
309 | int version; |
310 | QmlUnitCacheLookupFunction lookupCachedQmlUnit; |
311 | }; |
312 | |
313 | enum RegistrationType { |
314 | TypeRegistration = 0, |
315 | InterfaceRegistration = 1, |
316 | AutoParentRegistration = 2, |
317 | SingletonRegistration = 3, |
318 | CompositeRegistration = 4, |
319 | CompositeSingletonRegistration = 5, |
320 | QmlUnitCacheHookRegistration = 6 |
321 | }; |
322 | |
323 | int Q_QML_EXPORT qmlregister(RegistrationType, void *); |
324 | void Q_QML_EXPORT qmlunregister(RegistrationType, quintptr); |
325 | struct Q_QML_EXPORT RegisterSingletonFunctor |
326 | { |
327 | QObject *operator()(QQmlEngine *, QJSEngine *); |
328 | |
329 | QObject *m_object; |
330 | bool alreadyCalled = false; |
331 | }; |
332 | } |
333 | |
334 | QT_END_NAMESPACE |
335 | |
336 | #endif // QQMLPRIVATE_H |
337 | |