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