Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/variant/binder_common.h
21331 views
1
/**************************************************************************/
2
/* binder_common.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
#pragma once
32
33
#include "core/object/object.h"
34
#include "core/templates/simple_type.h"
35
#include "core/typedefs.h"
36
#include "core/variant/method_ptrcall.h"
37
#include "core/variant/type_info.h"
38
#include "core/variant/variant.h"
39
#include "core/variant/variant_internal.h"
40
41
#include <cstdio>
42
43
enum class HatDir;
44
enum class HatMask;
45
enum class JoyAxis;
46
enum class JoyButton;
47
48
enum class MIDIMessage;
49
enum class MouseButton;
50
enum class MouseButtonMask;
51
52
enum class Key;
53
enum class KeyModifierMask;
54
enum class KeyLocation;
55
56
// Variant cannot define an implicit cast operator for every Object subclass, so the
57
// casting is done here, to allow binding methods with parameters more specific than Object *
58
59
template <typename T>
60
struct VariantCaster {
61
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
62
using TStripped = std::remove_pointer_t<T>;
63
if constexpr (std::is_base_of_v<Object, TStripped>) {
64
return Object::cast_to<TStripped>(p_variant);
65
} else {
66
return p_variant;
67
}
68
}
69
};
70
71
template <typename T>
72
struct VariantCaster<T &> {
73
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
74
using TStripped = std::remove_pointer_t<T>;
75
if constexpr (std::is_base_of_v<Object, TStripped>) {
76
return Object::cast_to<TStripped>(p_variant);
77
} else {
78
return p_variant;
79
}
80
}
81
};
82
83
template <typename T>
84
struct VariantCaster<const T &> {
85
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
86
using TStripped = std::remove_pointer_t<T>;
87
if constexpr (std::is_base_of_v<Object, TStripped>) {
88
return Object::cast_to<TStripped>(p_variant);
89
} else {
90
return p_variant;
91
}
92
}
93
};
94
95
#define VARIANT_ENUM_CAST(m_enum) MAKE_ENUM_TYPE_INFO(m_enum)
96
#define VARIANT_BITFIELD_CAST(m_enum) MAKE_BITFIELD_TYPE_INFO(m_enum)
97
98
// Object enum casts must go here
99
VARIANT_ENUM_CAST(Object::ConnectFlags);
100
101
VARIANT_ENUM_CAST(Vector2::Axis);
102
VARIANT_ENUM_CAST(Vector2i::Axis);
103
VARIANT_ENUM_CAST(Vector3::Axis);
104
VARIANT_ENUM_CAST(Vector3i::Axis);
105
VARIANT_ENUM_CAST(Vector4::Axis);
106
VARIANT_ENUM_CAST(Vector4i::Axis);
107
VARIANT_ENUM_CAST(EulerOrder);
108
VARIANT_ENUM_CAST(Projection::Planes);
109
110
VARIANT_ENUM_CAST(Error);
111
VARIANT_ENUM_CAST(Side);
112
VARIANT_ENUM_CAST(ClockDirection);
113
VARIANT_ENUM_CAST(Corner);
114
VARIANT_ENUM_CAST(HatDir);
115
VARIANT_BITFIELD_CAST(HatMask);
116
VARIANT_ENUM_CAST(JoyAxis);
117
VARIANT_ENUM_CAST(JoyButton);
118
119
VARIANT_ENUM_CAST(MIDIMessage);
120
VARIANT_ENUM_CAST(MouseButton);
121
VARIANT_BITFIELD_CAST(MouseButtonMask);
122
VARIANT_ENUM_CAST(Orientation);
123
VARIANT_ENUM_CAST(HorizontalAlignment);
124
VARIANT_ENUM_CAST(VerticalAlignment);
125
VARIANT_ENUM_CAST(InlineAlignment);
126
VARIANT_ENUM_CAST(PropertyHint);
127
VARIANT_BITFIELD_CAST(PropertyUsageFlags);
128
VARIANT_ENUM_CAST(Variant::Type);
129
VARIANT_ENUM_CAST(Variant::Operator);
130
131
// Key
132
133
VARIANT_ENUM_CAST(Key);
134
VARIANT_BITFIELD_CAST(KeyModifierMask);
135
VARIANT_ENUM_CAST(KeyLocation);
136
137
template <>
138
struct VariantCaster<char32_t> {
139
static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {
140
return (char32_t)p_variant.operator int();
141
}
142
};
143
144
template <>
145
struct PtrToArg<char32_t> {
146
_FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
147
return char32_t(*reinterpret_cast<const int64_t *>(p_ptr));
148
}
149
typedef int64_t EncodeT;
150
_FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
151
*(int64_t *)p_ptr = p_val;
152
}
153
};
154
155
template <typename T>
156
struct VariantObjectClassChecker {
157
static _FORCE_INLINE_ bool check(const Variant &p_variant) {
158
using TStripped = std::remove_pointer_t<T>;
159
if constexpr (std::is_base_of_v<Object, TStripped>) {
160
Object *obj = p_variant;
161
return Object::cast_to<TStripped>(p_variant) || !obj;
162
} else {
163
return true;
164
}
165
}
166
};
167
168
template <typename T>
169
class Ref;
170
171
template <typename T>
172
struct VariantObjectClassChecker<const Ref<T> &> {
173
static _FORCE_INLINE_ bool check(const Variant &p_variant) {
174
Object *obj = p_variant;
175
const Ref<T> node = p_variant;
176
return node.ptr() || !obj;
177
}
178
};
179
180
#ifdef DEBUG_ENABLED
181
182
template <typename T>
183
struct VariantCasterAndValidate {
184
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
185
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
186
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
187
!VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
188
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
189
r_error.argument = p_arg_idx;
190
r_error.expected = argtype;
191
}
192
193
return VariantCaster<T>::cast(*p_args[p_arg_idx]);
194
}
195
};
196
197
template <typename T>
198
struct VariantCasterAndValidate<T &> {
199
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
200
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
201
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
202
!VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
203
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
204
r_error.argument = p_arg_idx;
205
r_error.expected = argtype;
206
}
207
208
return VariantCaster<T>::cast(*p_args[p_arg_idx]);
209
}
210
};
211
212
template <typename T>
213
struct VariantCasterAndValidate<const T &> {
214
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
215
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
216
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
217
!VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
218
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
219
r_error.argument = p_arg_idx;
220
r_error.expected = argtype;
221
}
222
223
return VariantCaster<T>::cast(*p_args[p_arg_idx]);
224
}
225
};
226
227
#endif // DEBUG_ENABLED
228
229
template <typename T, typename... P, size_t... Is>
230
void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
231
r_error.error = Callable::CallError::CALL_OK;
232
233
#ifdef DEBUG_ENABLED
234
(p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
235
#else
236
(p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
237
#endif // DEBUG_ENABLED
238
(void)(p_args); //avoid warning
239
}
240
241
template <typename T, typename... P, size_t... Is>
242
void call_with_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
243
r_error.error = Callable::CallError::CALL_OK;
244
245
#ifdef DEBUG_ENABLED
246
(p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
247
#else
248
(p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
249
#endif // DEBUG_ENABLED
250
(void)(p_args); //avoid warning
251
}
252
253
template <typename T, typename... P, size_t... Is>
254
void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
255
(p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
256
}
257
258
template <typename T, typename... P, size_t... Is>
259
void call_with_ptr_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const void **p_args, IndexSequence<Is...>) {
260
(p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
261
}
262
263
template <typename T, typename R, typename... P, size_t... Is>
264
void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
265
PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
266
}
267
268
template <typename T, typename R, typename... P, size_t... Is>
269
void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret, IndexSequence<Is...>) {
270
PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
271
}
272
273
template <typename T, typename... P, size_t... Is>
274
void call_with_ptr_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const void **p_args, IndexSequence<Is...>) {
275
p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...);
276
}
277
278
template <typename T, typename R, typename... P, size_t... Is>
279
void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
280
PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
281
}
282
283
template <typename R, typename... P, size_t... Is>
284
void call_with_ptr_args_static_method_ret_helper(R (*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
285
PtrToArg<R>::encode(p_method(PtrToArg<P>::convert(p_args[Is])...), r_ret);
286
}
287
288
template <typename... P, size_t... Is>
289
void call_with_ptr_args_static_method_helper(void (*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
290
p_method(PtrToArg<P>::convert(p_args[Is])...);
291
}
292
293
template <typename T, typename... P, size_t... Is>
294
void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
295
(p_instance->*p_method)((VariantInternalAccessor<GetSimpleTypeT<P>>::get(p_args[Is]))...);
296
}
297
298
template <typename T, typename... P, size_t... Is>
299
void call_with_validated_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, IndexSequence<Is...>) {
300
(p_instance->*p_method)((VariantInternalAccessor<GetSimpleTypeT<P>>::get(p_args[Is]))...);
301
}
302
303
template <typename T, typename R, typename... P, size_t... Is>
304
void call_with_validated_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
305
VariantInternalAccessor<GetSimpleTypeT<R>>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<GetSimpleTypeT<P>>::get(p_args[Is]))...));
306
}
307
308
template <typename T, typename R, typename... P, size_t... Is>
309
void call_with_validated_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
310
VariantInternalAccessor<GetSimpleTypeT<R>>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<GetSimpleTypeT<P>>::get(p_args[Is]))...));
311
}
312
313
template <typename T, typename R, typename... P, size_t... Is>
314
void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
315
VariantInternalAccessor<GetSimpleTypeT<R>>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<GetSimpleTypeT<P>>::get(p_args[Is]))...));
316
}
317
318
template <typename T, typename... P, size_t... Is>
319
void call_with_validated_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, IndexSequence<Is...>) {
320
p_method(p_instance, (VariantInternalAccessor<GetSimpleTypeT<P>>::get(p_args[Is]))...);
321
}
322
323
template <typename R, typename... P, size_t... Is>
324
void call_with_validated_variant_args_static_method_ret_helper(R (*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
325
VariantInternalAccessor<GetSimpleTypeT<R>>::set(r_ret, p_method((VariantInternalAccessor<GetSimpleTypeT<P>>::get(p_args[Is]))...));
326
}
327
328
template <typename... P, size_t... Is>
329
void call_with_validated_variant_args_static_method_helper(void (*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
330
p_method((VariantInternalAccessor<GetSimpleTypeT<P>>::get(p_args[Is]))...);
331
}
332
333
template <typename T, typename... P>
334
void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
335
#ifdef DEBUG_ENABLED
336
if ((size_t)p_argcount > sizeof...(P)) {
337
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
338
r_error.expected = sizeof...(P);
339
return;
340
}
341
342
if ((size_t)p_argcount < sizeof...(P)) {
343
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
344
r_error.expected = sizeof...(P);
345
return;
346
}
347
#endif // DEBUG_ENABLED
348
call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
349
}
350
351
template <typename T, typename... P>
352
void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
353
#ifdef DEBUG_ENABLED
354
if ((size_t)p_argcount > sizeof...(P)) {
355
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
356
r_error.expected = sizeof...(P);
357
return;
358
}
359
#endif // DEBUG_ENABLED
360
361
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
362
363
int32_t dvs = default_values.size();
364
#ifdef DEBUG_ENABLED
365
if (missing > dvs) {
366
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
367
r_error.expected = sizeof...(P);
368
return;
369
}
370
#endif // DEBUG_ENABLED
371
372
const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
373
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
374
if (i < p_argcount) {
375
args[i] = p_args[i];
376
} else {
377
args[i] = &default_values[i - p_argcount + (dvs - missing)];
378
}
379
}
380
381
call_with_variant_args_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
382
}
383
384
template <typename T, typename... P>
385
void call_with_variant_argsc(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
386
#ifdef DEBUG_ENABLED
387
if ((size_t)p_argcount > sizeof...(P)) {
388
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
389
r_error.expected = sizeof...(P);
390
return;
391
}
392
393
if ((size_t)p_argcount < sizeof...(P)) {
394
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
395
r_error.expected = sizeof...(P);
396
return;
397
}
398
#endif // DEBUG_ENABLED
399
call_with_variant_argsc_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
400
}
401
402
template <typename T, typename... P>
403
void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
404
#ifdef DEBUG_ENABLED
405
if ((size_t)p_argcount > sizeof...(P)) {
406
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
407
r_error.expected = sizeof...(P);
408
return;
409
}
410
#endif // DEBUG_ENABLED
411
412
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
413
414
int32_t dvs = default_values.size();
415
#ifdef DEBUG_ENABLED
416
if (missing > dvs) {
417
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
418
r_error.expected = sizeof...(P);
419
return;
420
}
421
#endif // DEBUG_ENABLED
422
423
const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
424
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
425
if (i < p_argcount) {
426
args[i] = p_args[i];
427
} else {
428
args[i] = &default_values[i - p_argcount + (dvs - missing)];
429
}
430
}
431
432
call_with_variant_argsc_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
433
}
434
435
template <typename T, typename R, typename... P>
436
void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
437
#ifdef DEBUG_ENABLED
438
if ((size_t)p_argcount > sizeof...(P)) {
439
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
440
r_error.expected = sizeof...(P);
441
return;
442
}
443
#endif // DEBUG_ENABLED
444
445
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
446
447
int32_t dvs = default_values.size();
448
#ifdef DEBUG_ENABLED
449
if (missing > dvs) {
450
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
451
r_error.expected = sizeof...(P);
452
return;
453
}
454
#endif // DEBUG_ENABLED
455
456
const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
457
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
458
if (i < p_argcount) {
459
args[i] = p_args[i];
460
} else {
461
args[i] = &default_values[i - p_argcount + (dvs - missing)];
462
}
463
}
464
465
call_with_variant_args_ret_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
466
}
467
468
template <typename T, typename R, typename... P>
469
void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
470
#ifdef DEBUG_ENABLED
471
if ((size_t)p_argcount > sizeof...(P)) {
472
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
473
r_error.expected = sizeof...(P);
474
return;
475
}
476
#endif // DEBUG_ENABLED
477
478
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
479
480
int32_t dvs = default_values.size();
481
#ifdef DEBUG_ENABLED
482
if (missing > dvs) {
483
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
484
r_error.expected = sizeof...(P);
485
return;
486
}
487
#endif // DEBUG_ENABLED
488
489
const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
490
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
491
if (i < p_argcount) {
492
args[i] = p_args[i];
493
} else {
494
args[i] = &default_values[i - p_argcount + (dvs - missing)];
495
}
496
}
497
498
call_with_variant_args_retc_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
499
}
500
501
template <typename T, typename... P>
502
void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const void **p_args) {
503
call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
504
}
505
506
template <typename T, typename... P>
507
void call_with_ptr_argsc(T *p_instance, void (T::*p_method)(P...) const, const void **p_args) {
508
call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
509
}
510
511
template <typename T, typename R, typename... P>
512
void call_with_ptr_args_ret(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret) {
513
call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
514
}
515
516
template <typename T, typename R, typename... P>
517
void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret) {
518
call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
519
}
520
521
template <typename T, typename... P>
522
void call_with_ptr_args_static(T *p_instance, void (*p_method)(T *, P...), const void **p_args) {
523
call_with_ptr_args_static_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
524
}
525
526
template <typename T, typename R, typename... P>
527
void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) {
528
call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
529
}
530
531
template <typename R, typename... P>
532
void call_with_ptr_args_static_method_ret(R (*p_method)(P...), const void **p_args, void *r_ret) {
533
call_with_ptr_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
534
}
535
536
template <typename... P>
537
void call_with_ptr_args_static_method(void (*p_method)(P...), const void **p_args) {
538
call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
539
}
540
541
// Validated
542
543
template <typename T, typename... P>
544
void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
545
call_with_validated_variant_args_helper<T, P...>(&VariantInternalAccessor<T>::get(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
546
}
547
548
template <typename T, typename R, typename... P>
549
void call_with_validated_variant_args_ret(Variant *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
550
call_with_validated_variant_args_ret_helper<T, R, P...>(&VariantInternalAccessor<T>::get(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
551
}
552
553
template <typename T, typename R, typename... P>
554
void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
555
call_with_validated_variant_args_retc_helper<T, R, P...>(&VariantInternalAccessor<T>::get(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
556
}
557
558
template <typename T, typename... P>
559
void call_with_validated_variant_args_static(Variant *base, void (*p_method)(T *, P...), const Variant **p_args) {
560
call_with_validated_variant_args_static_helper<T, P...>(&VariantInternalAccessor<T>::get(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
561
}
562
563
template <typename T, typename R, typename... P>
564
void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
565
call_with_validated_variant_args_static_retc_helper<T, R, P...>(&VariantInternalAccessor<T>::get(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
566
}
567
568
template <typename... P>
569
void call_with_validated_variant_args_static_method(void (*p_method)(P...), const Variant **p_args) {
570
call_with_validated_variant_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
571
}
572
573
template <typename R, typename... P>
574
void call_with_validated_variant_args_static_method_ret(R (*p_method)(P...), const Variant **p_args, Variant *r_ret) {
575
call_with_validated_variant_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
576
}
577
578
// Validated Object
579
580
template <typename T, typename... P>
581
void call_with_validated_object_instance_args(T *base, void (T::*p_method)(P...), const Variant **p_args) {
582
call_with_validated_variant_args_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
583
}
584
585
template <typename T, typename... P>
586
void call_with_validated_object_instance_argsc(T *base, void (T::*p_method)(P...) const, const Variant **p_args) {
587
call_with_validated_variant_argsc_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
588
}
589
590
template <typename T, typename R, typename... P>
591
void call_with_validated_object_instance_args_ret(T *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
592
call_with_validated_variant_args_ret_helper<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
593
}
594
595
template <typename T, typename R, typename... P>
596
void call_with_validated_object_instance_args_retc(T *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
597
call_with_validated_variant_args_retc_helper<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
598
}
599
600
template <typename T, typename... P>
601
void call_with_validated_object_instance_args_static(T *base, void (*p_method)(T *, P...), const Variant **p_args) {
602
call_with_validated_variant_args_static_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
603
}
604
605
template <typename T, typename R, typename... P>
606
void call_with_validated_object_instance_args_static_retc(T *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
607
call_with_validated_variant_args_static_retc_helper<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
608
}
609
610
// GCC raises "parameter 'p_args' set but not used" when P = {},
611
// it's not clever enough to treat other P values as making this branch valid.
612
GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wunused-but-set-parameter")
613
614
template <typename Q>
615
void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
616
if (p_arg == index) {
617
type = GetTypeInfo<Q>::VARIANT_TYPE;
618
}
619
index++;
620
}
621
622
template <typename... P>
623
Variant::Type call_get_argument_type(int p_arg) {
624
Variant::Type type = Variant::NIL;
625
int index = 0;
626
// I think rocket science is simpler than modern C++.
627
using expand_type = int[];
628
expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... };
629
(void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
630
(void)index; // Suppress GCC warning.
631
return type;
632
}
633
634
template <typename Q>
635
void call_get_argument_type_info_helper(int p_arg, int &index, PropertyInfo &info) {
636
if (p_arg == index) {
637
info = GetTypeInfo<Q>::get_class_info();
638
}
639
index++;
640
}
641
642
template <typename... P>
643
void call_get_argument_type_info(int p_arg, PropertyInfo &info) {
644
int index = 0;
645
// I think rocket science is simpler than modern C++.
646
using expand_type = int[];
647
expand_type a{ 0, (call_get_argument_type_info_helper<P>(p_arg, index, info), 0)... };
648
(void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
649
(void)index; // Suppress GCC warning.
650
}
651
652
#ifdef DEBUG_ENABLED
653
template <typename Q>
654
void call_get_argument_metadata_helper(int p_arg, int &index, GodotTypeInfo::Metadata &md) {
655
if (p_arg == index) {
656
md = GetTypeInfo<Q>::METADATA;
657
}
658
index++;
659
}
660
661
template <typename... P>
662
GodotTypeInfo::Metadata call_get_argument_metadata(int p_arg) {
663
GodotTypeInfo::Metadata md = GodotTypeInfo::METADATA_NONE;
664
665
int index = 0;
666
// I think rocket science is simpler than modern C++.
667
using expand_type = int[];
668
expand_type a{ 0, (call_get_argument_metadata_helper<P>(p_arg, index, md), 0)... };
669
(void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
670
(void)index;
671
return md;
672
}
673
674
#endif // DEBUG_ENABLED
675
676
//////////////////////
677
678
template <typename T, typename R, typename... P, size_t... Is>
679
void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
680
r_error.error = Callable::CallError::CALL_OK;
681
682
#ifdef DEBUG_ENABLED
683
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
684
#else
685
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...));
686
#endif
687
}
688
689
template <typename R, typename... P, size_t... Is>
690
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
691
r_error.error = Callable::CallError::CALL_OK;
692
693
#ifdef DEBUG_ENABLED
694
r_ret = VariantInternal::make((p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
695
#else
696
r_ret = VariantInternal::make((p_method)(VariantCaster<P>::cast(*p_args[Is])...));
697
#endif // DEBUG_ENABLED
698
}
699
700
template <typename... P, size_t... Is>
701
void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
702
r_error.error = Callable::CallError::CALL_OK;
703
704
#ifdef DEBUG_ENABLED
705
(p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
706
#else
707
(p_method)(VariantCaster<P>::cast(*p_args[Is])...);
708
#endif // DEBUG_ENABLED
709
}
710
711
template <typename T, typename R, typename... P>
712
void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
713
#ifdef DEBUG_ENABLED
714
if ((size_t)p_argcount > sizeof...(P)) {
715
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
716
r_error.expected = sizeof...(P);
717
return;
718
}
719
720
if ((size_t)p_argcount < sizeof...(P)) {
721
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
722
r_error.expected = sizeof...(P);
723
return;
724
}
725
#endif // DEBUG_ENABLED
726
call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
727
}
728
729
template <typename T, typename R, typename... P, size_t... Is>
730
void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
731
r_error.error = Callable::CallError::CALL_OK;
732
733
#ifdef DEBUG_ENABLED
734
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
735
#else
736
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...));
737
#endif // DEBUG_ENABLED
738
(void)p_args;
739
}
740
741
template <typename R, typename... P>
742
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
743
#ifdef DEBUG_ENABLED
744
if ((size_t)p_argcount > sizeof...(P)) {
745
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
746
r_error.expected = sizeof...(P);
747
return;
748
}
749
750
if ((size_t)p_argcount < sizeof...(P)) {
751
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
752
r_error.expected = sizeof...(P);
753
return;
754
}
755
#endif // DEBUG_ENABLED
756
call_with_variant_args_static_ret<R, P...>(p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
757
}
758
759
template <typename... P>
760
void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
761
#ifdef DEBUG_ENABLED
762
if ((size_t)p_argcount > sizeof...(P)) {
763
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
764
r_error.expected = sizeof...(P);
765
return;
766
}
767
768
if ((size_t)p_argcount < sizeof...(P)) {
769
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
770
r_error.expected = sizeof...(P);
771
return;
772
}
773
#endif // DEBUG_ENABLED
774
call_with_variant_args_static<P...>(p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
775
}
776
777
template <typename T, typename R, typename... P>
778
void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
779
#ifdef DEBUG_ENABLED
780
if ((size_t)p_argcount > sizeof...(P)) {
781
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
782
r_error.expected = sizeof...(P);
783
return;
784
}
785
786
if ((size_t)p_argcount < sizeof...(P)) {
787
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
788
r_error.expected = sizeof...(P);
789
return;
790
}
791
#endif // DEBUG_ENABLED
792
call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
793
}
794
795
template <typename T, typename R, typename... P, size_t... Is>
796
void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
797
r_error.error = Callable::CallError::CALL_OK;
798
799
#ifdef DEBUG_ENABLED
800
r_ret = VariantInternal::make((p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
801
#else
802
r_ret = VariantInternal::make((p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...));
803
#endif // DEBUG_ENABLED
804
805
(void)p_args;
806
}
807
808
template <typename T, typename R, typename... P>
809
void call_with_variant_args_retc_static_helper_dv(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &default_values, Callable::CallError &r_error) {
810
#ifdef DEBUG_ENABLED
811
if ((size_t)p_argcount > sizeof...(P)) {
812
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
813
r_error.expected = sizeof...(P);
814
return;
815
}
816
#endif // DEBUG_ENABLED
817
818
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
819
820
int32_t dvs = default_values.size();
821
#ifdef DEBUG_ENABLED
822
if (missing > dvs) {
823
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
824
r_error.expected = sizeof...(P);
825
return;
826
}
827
#endif // DEBUG_ENABLED
828
829
const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
830
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
831
if (i < p_argcount) {
832
args[i] = p_args[i];
833
} else {
834
args[i] = &default_values[i - p_argcount + (dvs - missing)];
835
}
836
}
837
838
call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
839
}
840
841
template <typename T, typename... P, size_t... Is>
842
void call_with_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
843
r_error.error = Callable::CallError::CALL_OK;
844
845
#ifdef DEBUG_ENABLED
846
(p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
847
#else
848
(p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
849
#endif // DEBUG_ENABLED
850
851
(void)p_args;
852
}
853
854
template <typename T, typename... P>
855
void call_with_variant_args_static_helper_dv(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, int p_argcount, const Vector<Variant> &default_values, Callable::CallError &r_error) {
856
#ifdef DEBUG_ENABLED
857
if ((size_t)p_argcount > sizeof...(P)) {
858
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
859
r_error.expected = sizeof...(P);
860
return;
861
}
862
#endif // DEBUG_ENABLED
863
864
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
865
866
int32_t dvs = default_values.size();
867
#ifdef DEBUG_ENABLED
868
if (missing > dvs) {
869
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
870
r_error.expected = sizeof...(P);
871
return;
872
}
873
#endif // DEBUG_ENABLED
874
875
const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
876
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
877
if (i < p_argcount) {
878
args[i] = p_args[i];
879
} else {
880
args[i] = &default_values[i - p_argcount + (dvs - missing)];
881
}
882
}
883
884
call_with_variant_args_static_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
885
}
886
887
template <typename R, typename... P>
888
void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
889
#ifdef DEBUG_ENABLED
890
if ((size_t)p_argcount > sizeof...(P)) {
891
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
892
r_error.expected = sizeof...(P);
893
return;
894
}
895
#endif // DEBUG_ENABLED
896
897
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
898
899
int32_t dvs = default_values.size();
900
#ifdef DEBUG_ENABLED
901
if (missing > dvs) {
902
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
903
r_error.expected = sizeof...(P);
904
return;
905
}
906
#endif // DEBUG_ENABLED
907
908
const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
909
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
910
if (i < p_argcount) {
911
args[i] = p_args[i];
912
} else {
913
args[i] = &default_values[i - p_argcount + (dvs - missing)];
914
}
915
}
916
917
call_with_variant_args_static_ret(p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
918
}
919
920
template <typename... P>
921
void call_with_variant_args_static_dv(void (*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
922
#ifdef DEBUG_ENABLED
923
if ((size_t)p_argcount > sizeof...(P)) {
924
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
925
r_error.expected = sizeof...(P);
926
return;
927
}
928
#endif // DEBUG_ENABLED
929
930
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
931
932
int32_t dvs = default_values.size();
933
#ifdef DEBUG_ENABLED
934
if (missing > dvs) {
935
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
936
r_error.expected = sizeof...(P);
937
return;
938
}
939
#endif // DEBUG_ENABLED
940
941
const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
942
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
943
if (i < p_argcount) {
944
args[i] = p_args[i];
945
} else {
946
args[i] = &default_values[i - p_argcount + (dvs - missing)];
947
}
948
}
949
950
call_with_variant_args_static(p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
951
}
952
953
GODOT_GCC_WARNING_POP
954
955