1 | /**************************************************************************/ |
2 | /* method_ptrcall.h */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #ifndef METHOD_PTRCALL_H |
32 | #define METHOD_PTRCALL_H |
33 | |
34 | #include "core/object/object_id.h" |
35 | #include "core/typedefs.h" |
36 | #include "core/variant/variant.h" |
37 | |
38 | template <class T> |
39 | struct PtrToArg {}; |
40 | |
41 | #define MAKE_PTRARG(m_type) \ |
42 | template <> \ |
43 | struct PtrToArg<m_type> { \ |
44 | _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ |
45 | return *reinterpret_cast<const m_type *>(p_ptr); \ |
46 | } \ |
47 | typedef m_type EncodeT; \ |
48 | _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ |
49 | *((m_type *)p_ptr) = p_val; \ |
50 | } \ |
51 | }; \ |
52 | template <> \ |
53 | struct PtrToArg<const m_type &> { \ |
54 | _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ |
55 | return *reinterpret_cast<const m_type *>(p_ptr); \ |
56 | } \ |
57 | typedef m_type EncodeT; \ |
58 | _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ |
59 | *((m_type *)p_ptr) = p_val; \ |
60 | } \ |
61 | } |
62 | |
63 | #define MAKE_PTRARGCONV(m_type, m_conv) \ |
64 | template <> \ |
65 | struct PtrToArg<m_type> { \ |
66 | _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ |
67 | return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \ |
68 | } \ |
69 | typedef m_conv EncodeT; \ |
70 | _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ |
71 | *((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \ |
72 | } \ |
73 | }; \ |
74 | template <> \ |
75 | struct PtrToArg<const m_type &> { \ |
76 | _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ |
77 | return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \ |
78 | } \ |
79 | typedef m_conv EncodeT; \ |
80 | _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ |
81 | *((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \ |
82 | } \ |
83 | } |
84 | |
85 | #define MAKE_PTRARG_BY_REFERENCE(m_type) \ |
86 | template <> \ |
87 | struct PtrToArg<m_type> { \ |
88 | _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ |
89 | return *reinterpret_cast<const m_type *>(p_ptr); \ |
90 | } \ |
91 | typedef m_type EncodeT; \ |
92 | _FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \ |
93 | *((m_type *)p_ptr) = p_val; \ |
94 | } \ |
95 | }; \ |
96 | template <> \ |
97 | struct PtrToArg<const m_type &> { \ |
98 | _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ |
99 | return *reinterpret_cast<const m_type *>(p_ptr); \ |
100 | } \ |
101 | typedef m_type EncodeT; \ |
102 | _FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \ |
103 | *((m_type *)p_ptr) = p_val; \ |
104 | } \ |
105 | } |
106 | |
107 | MAKE_PTRARGCONV(bool, uint8_t); |
108 | // Integer types. |
109 | MAKE_PTRARGCONV(uint8_t, int64_t); |
110 | MAKE_PTRARGCONV(int8_t, int64_t); |
111 | MAKE_PTRARGCONV(uint16_t, int64_t); |
112 | MAKE_PTRARGCONV(int16_t, int64_t); |
113 | MAKE_PTRARGCONV(uint32_t, int64_t); |
114 | MAKE_PTRARGCONV(int32_t, int64_t); |
115 | MAKE_PTRARG(int64_t); |
116 | MAKE_PTRARG(uint64_t); |
117 | // Float types |
118 | MAKE_PTRARGCONV(float, double); |
119 | MAKE_PTRARG(double); |
120 | |
121 | MAKE_PTRARG(String); |
122 | MAKE_PTRARG(Vector2); |
123 | MAKE_PTRARG(Vector2i); |
124 | MAKE_PTRARG(Rect2); |
125 | MAKE_PTRARG(Rect2i); |
126 | MAKE_PTRARG_BY_REFERENCE(Vector3); |
127 | MAKE_PTRARG_BY_REFERENCE(Vector3i); |
128 | MAKE_PTRARG_BY_REFERENCE(Vector4); |
129 | MAKE_PTRARG_BY_REFERENCE(Vector4i); |
130 | MAKE_PTRARG(Transform2D); |
131 | MAKE_PTRARG(Projection); |
132 | MAKE_PTRARG_BY_REFERENCE(Plane); |
133 | MAKE_PTRARG(Quaternion); |
134 | MAKE_PTRARG_BY_REFERENCE(AABB); |
135 | MAKE_PTRARG_BY_REFERENCE(Basis); |
136 | MAKE_PTRARG_BY_REFERENCE(Transform3D); |
137 | MAKE_PTRARG_BY_REFERENCE(Color); |
138 | MAKE_PTRARG(StringName); |
139 | MAKE_PTRARG(NodePath); |
140 | MAKE_PTRARG(RID); |
141 | // Object doesn't need this. |
142 | MAKE_PTRARG(Callable); |
143 | MAKE_PTRARG(Signal); |
144 | MAKE_PTRARG(Dictionary); |
145 | MAKE_PTRARG(Array); |
146 | MAKE_PTRARG(PackedByteArray); |
147 | MAKE_PTRARG(PackedInt32Array); |
148 | MAKE_PTRARG(PackedInt64Array); |
149 | MAKE_PTRARG(PackedFloat32Array); |
150 | MAKE_PTRARG(PackedFloat64Array); |
151 | MAKE_PTRARG(PackedStringArray); |
152 | MAKE_PTRARG(PackedVector2Array); |
153 | MAKE_PTRARG(PackedVector3Array); |
154 | MAKE_PTRARG(PackedColorArray); |
155 | MAKE_PTRARG_BY_REFERENCE(Variant); |
156 | |
157 | // This is for Object. |
158 | |
159 | template <class T> |
160 | struct PtrToArg<T *> { |
161 | _FORCE_INLINE_ static T *convert(const void *p_ptr) { |
162 | if (p_ptr == nullptr) { |
163 | return nullptr; |
164 | } |
165 | return const_cast<T *>(*reinterpret_cast<T *const *>(p_ptr)); |
166 | } |
167 | typedef Object *EncodeT; |
168 | _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { |
169 | *((T **)p_ptr) = p_var; |
170 | } |
171 | }; |
172 | |
173 | template <class T> |
174 | struct PtrToArg<const T *> { |
175 | _FORCE_INLINE_ static const T *convert(const void *p_ptr) { |
176 | if (p_ptr == nullptr) { |
177 | return nullptr; |
178 | } |
179 | return *reinterpret_cast<T *const *>(p_ptr); |
180 | } |
181 | typedef const Object *EncodeT; |
182 | _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { |
183 | *((T **)p_ptr) = p_var; |
184 | } |
185 | }; |
186 | |
187 | // This is for ObjectID. |
188 | |
189 | template <> |
190 | struct PtrToArg<ObjectID> { |
191 | _FORCE_INLINE_ static const ObjectID convert(const void *p_ptr) { |
192 | return ObjectID(*reinterpret_cast<const uint64_t *>(p_ptr)); |
193 | } |
194 | typedef uint64_t EncodeT; |
195 | _FORCE_INLINE_ static void encode(const ObjectID &p_val, void *p_ptr) { |
196 | *((uint64_t *)p_ptr) = p_val; |
197 | } |
198 | }; |
199 | |
200 | // This is for the special cases used by Variant. |
201 | |
202 | // No EncodeT because direct pointer conversion not possible. |
203 | #define MAKE_VECARG(m_type) \ |
204 | template <> \ |
205 | struct PtrToArg<Vector<m_type>> { \ |
206 | _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ |
207 | const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \ |
208 | Vector<m_type> ret; \ |
209 | int len = dvs->size(); \ |
210 | ret.resize(len); \ |
211 | { \ |
212 | const m_type *r = dvs->ptr(); \ |
213 | for (int i = 0; i < len; i++) { \ |
214 | ret.write[i] = r[i]; \ |
215 | } \ |
216 | } \ |
217 | return ret; \ |
218 | } \ |
219 | _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \ |
220 | Vector<m_type> *dv = reinterpret_cast<Vector<m_type> *>(p_ptr); \ |
221 | int len = p_vec.size(); \ |
222 | dv->resize(len); \ |
223 | { \ |
224 | m_type *w = dv->ptrw(); \ |
225 | for (int i = 0; i < len; i++) { \ |
226 | w[i] = p_vec[i]; \ |
227 | } \ |
228 | } \ |
229 | } \ |
230 | }; \ |
231 | template <> \ |
232 | struct PtrToArg<const Vector<m_type> &> { \ |
233 | _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ |
234 | const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \ |
235 | Vector<m_type> ret; \ |
236 | int len = dvs->size(); \ |
237 | ret.resize(len); \ |
238 | { \ |
239 | const m_type *r = dvs->ptr(); \ |
240 | for (int i = 0; i < len; i++) { \ |
241 | ret.write[i] = r[i]; \ |
242 | } \ |
243 | } \ |
244 | return ret; \ |
245 | } \ |
246 | } |
247 | |
248 | // No EncodeT because direct pointer conversion not possible. |
249 | #define MAKE_VECARG_ALT(m_type, m_type_alt) \ |
250 | template <> \ |
251 | struct PtrToArg<Vector<m_type_alt>> { \ |
252 | _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \ |
253 | const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \ |
254 | Vector<m_type_alt> ret; \ |
255 | int len = dvs->size(); \ |
256 | ret.resize(len); \ |
257 | { \ |
258 | const m_type *r = dvs->ptr(); \ |
259 | for (int i = 0; i < len; i++) { \ |
260 | ret.write[i] = r[i]; \ |
261 | } \ |
262 | } \ |
263 | return ret; \ |
264 | } \ |
265 | _FORCE_INLINE_ static void encode(Vector<m_type_alt> p_vec, void *p_ptr) { \ |
266 | Vector<m_type> *dv = reinterpret_cast<Vector<m_type> *>(p_ptr); \ |
267 | int len = p_vec.size(); \ |
268 | dv->resize(len); \ |
269 | { \ |
270 | m_type *w = dv->ptrw(); \ |
271 | for (int i = 0; i < len; i++) { \ |
272 | w[i] = p_vec[i]; \ |
273 | } \ |
274 | } \ |
275 | } \ |
276 | }; \ |
277 | template <> \ |
278 | struct PtrToArg<const Vector<m_type_alt> &> { \ |
279 | _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \ |
280 | const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \ |
281 | Vector<m_type_alt> ret; \ |
282 | int len = dvs->size(); \ |
283 | ret.resize(len); \ |
284 | { \ |
285 | const m_type *r = dvs->ptr(); \ |
286 | for (int i = 0; i < len; i++) { \ |
287 | ret.write[i] = r[i]; \ |
288 | } \ |
289 | } \ |
290 | return ret; \ |
291 | } \ |
292 | } |
293 | |
294 | MAKE_VECARG_ALT(String, StringName); |
295 | |
296 | // For stuff that gets converted to Array vectors. |
297 | |
298 | // No EncodeT because direct pointer conversion not possible. |
299 | #define MAKE_VECARR(m_type) \ |
300 | template <> \ |
301 | struct PtrToArg<Vector<m_type>> { \ |
302 | _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ |
303 | const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ |
304 | Vector<m_type> ret; \ |
305 | int len = arr->size(); \ |
306 | ret.resize(len); \ |
307 | for (int i = 0; i < len; i++) { \ |
308 | ret.write[i] = (*arr)[i]; \ |
309 | } \ |
310 | return ret; \ |
311 | } \ |
312 | _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \ |
313 | Array *arr = reinterpret_cast<Array *>(p_ptr); \ |
314 | int len = p_vec.size(); \ |
315 | arr->resize(len); \ |
316 | for (int i = 0; i < len; i++) { \ |
317 | (*arr)[i] = p_vec[i]; \ |
318 | } \ |
319 | } \ |
320 | }; \ |
321 | template <> \ |
322 | struct PtrToArg<const Vector<m_type> &> { \ |
323 | _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ |
324 | const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ |
325 | Vector<m_type> ret; \ |
326 | int len = arr->size(); \ |
327 | ret.resize(len); \ |
328 | for (int i = 0; i < len; i++) { \ |
329 | ret.write[i] = (*arr)[i]; \ |
330 | } \ |
331 | return ret; \ |
332 | } \ |
333 | } |
334 | |
335 | MAKE_VECARR(Variant); |
336 | MAKE_VECARR(RID); |
337 | MAKE_VECARR(Plane); |
338 | |
339 | // No EncodeT because direct pointer conversion not possible. |
340 | #define MAKE_DVECARR(m_type) \ |
341 | template <> \ |
342 | struct PtrToArg<Vector<m_type>> { \ |
343 | _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ |
344 | const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ |
345 | Vector<m_type> ret; \ |
346 | int len = arr->size(); \ |
347 | ret.resize(len); \ |
348 | { \ |
349 | m_type *w = ret.ptrw(); \ |
350 | for (int i = 0; i < len; i++) { \ |
351 | w[i] = (*arr)[i]; \ |
352 | } \ |
353 | } \ |
354 | return ret; \ |
355 | } \ |
356 | _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \ |
357 | Array *arr = reinterpret_cast<Array *>(p_ptr); \ |
358 | int len = p_vec.size(); \ |
359 | arr->resize(len); \ |
360 | { \ |
361 | const m_type *r = p_vec.ptr(); \ |
362 | for (int i = 0; i < len; i++) { \ |
363 | (*arr)[i] = r[i]; \ |
364 | } \ |
365 | } \ |
366 | } \ |
367 | }; \ |
368 | template <> \ |
369 | struct PtrToArg<const Vector<m_type> &> { \ |
370 | _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ |
371 | const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ |
372 | Vector<m_type> ret; \ |
373 | int len = arr->size(); \ |
374 | ret.resize(len); \ |
375 | { \ |
376 | m_type *w = ret.ptrw(); \ |
377 | for (int i = 0; i < len; i++) { \ |
378 | w[i] = (*arr)[i]; \ |
379 | } \ |
380 | } \ |
381 | return ret; \ |
382 | } \ |
383 | } |
384 | |
385 | // Special case for IPAddress. |
386 | |
387 | // No EncodeT because direct pointer conversion not possible. |
388 | #define MAKE_STRINGCONV_BY_REFERENCE(m_type) \ |
389 | template <> \ |
390 | struct PtrToArg<m_type> { \ |
391 | _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ |
392 | m_type s = *reinterpret_cast<const String *>(p_ptr); \ |
393 | return s; \ |
394 | } \ |
395 | _FORCE_INLINE_ static void encode(const m_type &p_vec, void *p_ptr) { \ |
396 | String *arr = reinterpret_cast<String *>(p_ptr); \ |
397 | *arr = p_vec; \ |
398 | } \ |
399 | }; \ |
400 | \ |
401 | template <> \ |
402 | struct PtrToArg<const m_type &> { \ |
403 | _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ |
404 | m_type s = *reinterpret_cast<const String *>(p_ptr); \ |
405 | return s; \ |
406 | } \ |
407 | } |
408 | |
409 | MAKE_STRINGCONV_BY_REFERENCE(IPAddress); |
410 | |
411 | // No EncodeT because direct pointer conversion not possible. |
412 | template <> |
413 | struct PtrToArg<Vector<Face3>> { |
414 | _FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) { |
415 | const Vector<Vector3> *dvs = reinterpret_cast<const Vector<Vector3> *>(p_ptr); |
416 | Vector<Face3> ret; |
417 | int len = dvs->size() / 3; |
418 | ret.resize(len); |
419 | { |
420 | const Vector3 *r = dvs->ptr(); |
421 | Face3 *w = ret.ptrw(); |
422 | for (int i = 0; i < len; i++) { |
423 | w[i].vertex[0] = r[i * 3 + 0]; |
424 | w[i].vertex[1] = r[i * 3 + 1]; |
425 | w[i].vertex[2] = r[i * 3 + 2]; |
426 | } |
427 | } |
428 | return ret; |
429 | } |
430 | _FORCE_INLINE_ static void encode(Vector<Face3> p_vec, void *p_ptr) { |
431 | Vector<Vector3> *arr = reinterpret_cast<Vector<Vector3> *>(p_ptr); |
432 | int len = p_vec.size(); |
433 | arr->resize(len * 3); |
434 | { |
435 | const Face3 *r = p_vec.ptr(); |
436 | Vector3 *w = arr->ptrw(); |
437 | for (int i = 0; i < len; i++) { |
438 | w[i * 3 + 0] = r[i].vertex[0]; |
439 | w[i * 3 + 1] = r[i].vertex[1]; |
440 | w[i * 3 + 2] = r[i].vertex[2]; |
441 | } |
442 | } |
443 | } |
444 | }; |
445 | |
446 | // No EncodeT because direct pointer conversion not possible. |
447 | template <> |
448 | struct PtrToArg<const Vector<Face3> &> { |
449 | _FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) { |
450 | const Vector<Vector3> *dvs = reinterpret_cast<const Vector<Vector3> *>(p_ptr); |
451 | Vector<Face3> ret; |
452 | int len = dvs->size() / 3; |
453 | ret.resize(len); |
454 | { |
455 | const Vector3 *r = dvs->ptr(); |
456 | Face3 *w = ret.ptrw(); |
457 | for (int i = 0; i < len; i++) { |
458 | w[i].vertex[0] = r[i * 3 + 0]; |
459 | w[i].vertex[1] = r[i * 3 + 1]; |
460 | w[i].vertex[2] = r[i * 3 + 2]; |
461 | } |
462 | } |
463 | return ret; |
464 | } |
465 | }; |
466 | |
467 | #endif // METHOD_PTRCALL_H |
468 | |