Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/variant/variant.h
9903 views
1
/**************************************************************************/
2
/* variant.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/core_string_names.h"
34
#include "core/input/input_enums.h"
35
#include "core/io/ip_address.h"
36
#include "core/math/aabb.h"
37
#include "core/math/basis.h"
38
#include "core/math/color.h"
39
#include "core/math/face3.h"
40
#include "core/math/plane.h"
41
#include "core/math/projection.h"
42
#include "core/math/quaternion.h"
43
#include "core/math/rect2.h"
44
#include "core/math/rect2i.h"
45
#include "core/math/transform_2d.h"
46
#include "core/math/transform_3d.h"
47
#include "core/math/vector2.h"
48
#include "core/math/vector2i.h"
49
#include "core/math/vector3.h"
50
#include "core/math/vector3i.h"
51
#include "core/math/vector4.h"
52
#include "core/math/vector4i.h"
53
#include "core/object/object_id.h"
54
#include "core/os/keyboard.h"
55
#include "core/string/node_path.h"
56
#include "core/string/ustring.h"
57
#include "core/templates/bit_field.h"
58
#include "core/templates/list.h"
59
#include "core/templates/paged_allocator.h"
60
#include "core/templates/rid.h"
61
#include "core/variant/array.h"
62
#include "core/variant/callable.h"
63
#include "core/variant/dictionary.h"
64
#include "core/variant/variant_deep_duplicate.h"
65
66
class Object;
67
class RefCounted;
68
69
template <typename T>
70
class Ref;
71
template <typename T>
72
class BitField;
73
74
struct PropertyInfo;
75
struct MethodInfo;
76
77
typedef Vector<uint8_t> PackedByteArray;
78
typedef Vector<int32_t> PackedInt32Array;
79
typedef Vector<int64_t> PackedInt64Array;
80
typedef Vector<float> PackedFloat32Array;
81
typedef Vector<double> PackedFloat64Array;
82
typedef Vector<real_t> PackedRealArray;
83
typedef Vector<String> PackedStringArray;
84
typedef Vector<Vector2> PackedVector2Array;
85
typedef Vector<Vector3> PackedVector3Array;
86
typedef Vector<Color> PackedColorArray;
87
typedef Vector<Vector4> PackedVector4Array;
88
89
class Variant {
90
public:
91
// If this changes the table in variant_op must be updated
92
enum Type {
93
NIL,
94
95
// atomic types
96
BOOL,
97
INT,
98
FLOAT,
99
STRING,
100
101
// math types
102
VECTOR2,
103
VECTOR2I,
104
RECT2,
105
RECT2I,
106
VECTOR3,
107
VECTOR3I,
108
TRANSFORM2D,
109
VECTOR4,
110
VECTOR4I,
111
PLANE,
112
QUATERNION,
113
AABB,
114
BASIS,
115
TRANSFORM3D,
116
PROJECTION,
117
118
// misc types
119
COLOR,
120
STRING_NAME,
121
NODE_PATH,
122
RID,
123
OBJECT,
124
CALLABLE,
125
SIGNAL,
126
DICTIONARY,
127
ARRAY,
128
129
// typed arrays
130
PACKED_BYTE_ARRAY,
131
PACKED_INT32_ARRAY,
132
PACKED_INT64_ARRAY,
133
PACKED_FLOAT32_ARRAY,
134
PACKED_FLOAT64_ARRAY,
135
PACKED_STRING_ARRAY,
136
PACKED_VECTOR2_ARRAY,
137
PACKED_VECTOR3_ARRAY,
138
PACKED_COLOR_ARRAY,
139
PACKED_VECTOR4_ARRAY,
140
141
VARIANT_MAX
142
};
143
144
enum {
145
// Maximum recursion depth allowed when serializing variants.
146
MAX_RECURSION_DEPTH = 1024,
147
};
148
149
private:
150
struct Pools {
151
union BucketSmall {
152
BucketSmall() {}
153
~BucketSmall() {}
154
Transform2D _transform2d;
155
::AABB _aabb;
156
};
157
union BucketMedium {
158
BucketMedium() {}
159
~BucketMedium() {}
160
Basis _basis;
161
Transform3D _transform3d;
162
};
163
union BucketLarge {
164
BucketLarge() {}
165
~BucketLarge() {}
166
Projection _projection;
167
};
168
169
static PagedAllocator<BucketSmall, true> _bucket_small;
170
static PagedAllocator<BucketMedium, true> _bucket_medium;
171
static PagedAllocator<BucketLarge, true> _bucket_large;
172
};
173
174
friend struct _VariantCall;
175
friend class VariantInternal;
176
// Variant takes 24 bytes when real_t is float, and 40 bytes if double.
177
// It only allocates extra memory for AABB/Transform2D (24, 48 if double),
178
// Basis/Transform3D (48, 96 if double), Projection (64, 128 if double),
179
// and PackedArray/Array/Dictionary (platform-dependent).
180
181
Type type = NIL;
182
183
struct ObjData {
184
ObjectID id;
185
Object *obj = nullptr;
186
187
void ref(const ObjData &p_from);
188
void ref_pointer(Object *p_object);
189
void ref_pointer(RefCounted *p_object);
190
void unref();
191
192
template <typename T>
193
_ALWAYS_INLINE_ void ref(const Ref<T> &p_from) {
194
if (p_from.is_valid()) {
195
ref(ObjData{ p_from->get_instance_id(), p_from.ptr() });
196
} else {
197
unref();
198
}
199
}
200
};
201
202
/* array helpers */
203
struct PackedArrayRefBase {
204
SafeRefCount refcount;
205
_FORCE_INLINE_ PackedArrayRefBase *reference() {
206
if (refcount.ref()) {
207
return this;
208
} else {
209
return nullptr;
210
}
211
}
212
static _FORCE_INLINE_ PackedArrayRefBase *reference_from(PackedArrayRefBase *p_base, PackedArrayRefBase *p_from) {
213
if (p_base == p_from) {
214
return p_base; //same thing, do nothing
215
}
216
217
if (p_from->reference()) {
218
if (p_base->refcount.unref()) {
219
memdelete(p_base);
220
}
221
return p_from;
222
} else {
223
return p_base; //keep, could not reference new
224
}
225
}
226
static _FORCE_INLINE_ void destroy(PackedArrayRefBase *p_array) {
227
if (p_array->refcount.unref()) {
228
memdelete(p_array);
229
}
230
}
231
_FORCE_INLINE_ virtual ~PackedArrayRefBase() {} //needs virtual destructor, but make inline
232
};
233
234
template <typename T>
235
struct PackedArrayRef : public PackedArrayRefBase {
236
Vector<T> array;
237
static _FORCE_INLINE_ PackedArrayRef<T> *create() {
238
return memnew(PackedArrayRef<T>);
239
}
240
static _FORCE_INLINE_ PackedArrayRef<T> *create(const Vector<T> &p_from) {
241
return memnew(PackedArrayRef<T>(p_from));
242
}
243
244
static _FORCE_INLINE_ const Vector<T> &get_array(PackedArrayRefBase *p_base) {
245
return static_cast<PackedArrayRef<T> *>(p_base)->array;
246
}
247
static _FORCE_INLINE_ Vector<T> *get_array_ptr(const PackedArrayRefBase *p_base) {
248
return &const_cast<PackedArrayRef<T> *>(static_cast<const PackedArrayRef<T> *>(p_base))->array;
249
}
250
251
_FORCE_INLINE_ PackedArrayRef(const Vector<T> &p_from) {
252
array = p_from;
253
refcount.init();
254
}
255
_FORCE_INLINE_ PackedArrayRef() {
256
refcount.init();
257
}
258
};
259
260
/* end of array helpers */
261
_ALWAYS_INLINE_ ObjData &_get_obj();
262
_ALWAYS_INLINE_ const ObjData &_get_obj() const;
263
264
union {
265
bool _bool;
266
int64_t _int;
267
double _float;
268
Transform2D *_transform2d;
269
::AABB *_aabb;
270
Basis *_basis;
271
Transform3D *_transform3d;
272
Projection *_projection;
273
PackedArrayRefBase *packed_array;
274
void *_ptr; //generic pointer
275
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]{ 0 };
276
} _data alignas(8);
277
278
void reference(const Variant &p_variant);
279
280
void _clear_internal();
281
282
static constexpr bool needs_deinit[Variant::VARIANT_MAX] = {
283
false, //NIL,
284
false, //BOOL,
285
false, //INT,
286
false, //FLOAT,
287
true, //STRING,
288
false, //VECTOR2,
289
false, //VECTOR2I,
290
false, //RECT2,
291
false, //RECT2I,
292
false, //VECTOR3,
293
false, //VECTOR3I,
294
true, //TRANSFORM2D,
295
false, //VECTOR4,
296
false, //VECTOR4I,
297
false, //PLANE,
298
false, //QUATERNION,
299
true, //AABB,
300
true, //BASIS,
301
true, //TRANSFORM,
302
true, //PROJECTION,
303
304
// misc types
305
false, //COLOR,
306
true, //STRING_NAME,
307
true, //NODE_PATH,
308
false, //RID,
309
true, //OBJECT,
310
true, //CALLABLE,
311
true, //SIGNAL,
312
true, //DICTIONARY,
313
true, //ARRAY,
314
315
// typed arrays
316
true, //PACKED_BYTE_ARRAY,
317
true, //PACKED_INT32_ARRAY,
318
true, //PACKED_INT64_ARRAY,
319
true, //PACKED_FLOAT32_ARRAY,
320
true, //PACKED_FLOAT64_ARRAY,
321
true, //PACKED_STRING_ARRAY,
322
true, //PACKED_VECTOR2_ARRAY,
323
true, //PACKED_VECTOR3_ARRAY,
324
true, //PACKED_COLOR_ARRAY,
325
true, //PACKED_VECTOR4_ARRAY,
326
};
327
328
_FORCE_INLINE_ void clear() {
329
if (unlikely(needs_deinit[type])) { // Make it fast for types that don't need deinit.
330
_clear_internal();
331
}
332
type = NIL;
333
}
334
335
static void _register_variant_operators();
336
static void _unregister_variant_operators();
337
static void _register_variant_methods();
338
static void _unregister_variant_methods();
339
static void _register_variant_setters_getters();
340
static void _unregister_variant_setters_getters();
341
static void _register_variant_constructors();
342
static void _unregister_variant_destructors();
343
static void _register_variant_destructors();
344
static void _unregister_variant_constructors();
345
static void _register_variant_utility_functions();
346
static void _unregister_variant_utility_functions();
347
348
void _variant_call_error(const String &p_method, Callable::CallError &error);
349
350
template <typename T>
351
_ALWAYS_INLINE_ T _to_int() const {
352
switch (get_type()) {
353
case NIL:
354
return 0;
355
case BOOL:
356
return _data._bool ? 1 : 0;
357
case INT:
358
return T(_data._int);
359
case FLOAT:
360
return T(_data._float);
361
case STRING:
362
return reinterpret_cast<const String *>(_data._mem)->to_int();
363
default: {
364
return 0;
365
}
366
}
367
}
368
369
template <typename T>
370
_ALWAYS_INLINE_ T _to_float() const {
371
switch (type) {
372
case NIL:
373
return 0;
374
case BOOL:
375
return _data._bool ? 1 : 0;
376
case INT:
377
return T(_data._int);
378
case FLOAT:
379
return T(_data._float);
380
case STRING:
381
return reinterpret_cast<const String *>(_data._mem)->to_float();
382
default: {
383
return 0;
384
}
385
}
386
}
387
388
// Avoid accidental conversion. If you reached this point, it's because you most likely forgot to dereference
389
// a Variant pointer (so add * like this: *variant_pointer).
390
391
Variant(const Variant *) {}
392
Variant(const Variant **) {}
393
394
public:
395
_FORCE_INLINE_ Type get_type() const {
396
return type;
397
}
398
static String get_type_name(Variant::Type p_type);
399
static Variant::Type get_type_by_name(const String &p_type_name);
400
static bool can_convert(Type p_type_from, Type p_type_to);
401
static bool can_convert_strict(Type p_type_from, Type p_type_to);
402
static bool is_type_shared(Variant::Type p_type);
403
404
bool is_ref_counted() const;
405
_FORCE_INLINE_ bool is_num() const {
406
return type == INT || type == FLOAT;
407
}
408
_FORCE_INLINE_ bool is_string() const {
409
return type == STRING || type == STRING_NAME;
410
}
411
_FORCE_INLINE_ bool is_array() const {
412
return type >= ARRAY;
413
}
414
bool is_shared() const;
415
bool is_zero() const;
416
bool is_one() const;
417
bool is_null() const;
418
bool is_read_only() const;
419
420
// Make sure Variant is not implicitly cast when accessing it with bracket notation (GH-49469).
421
Variant &operator[](const Variant &p_key) = delete;
422
const Variant &operator[](const Variant &p_key) const = delete;
423
424
operator bool() const;
425
operator int64_t() const;
426
operator int32_t() const;
427
operator int16_t() const;
428
operator int8_t() const;
429
operator uint64_t() const;
430
operator uint32_t() const;
431
operator uint16_t() const;
432
operator uint8_t() const;
433
434
operator ObjectID() const;
435
436
operator char32_t() const;
437
operator float() const;
438
operator double() const;
439
operator String() const;
440
operator StringName() const;
441
operator Vector2() const;
442
operator Vector2i() const;
443
operator Rect2() const;
444
operator Rect2i() const;
445
operator Vector3() const;
446
operator Vector3i() const;
447
operator Vector4() const;
448
operator Vector4i() const;
449
operator Plane() const;
450
operator ::AABB() const;
451
operator Quaternion() const;
452
operator Basis() const;
453
operator Transform2D() const;
454
operator Transform3D() const;
455
operator Projection() const;
456
457
operator Color() const;
458
operator NodePath() const;
459
operator ::RID() const;
460
461
operator Object *() const;
462
463
operator Callable() const;
464
operator Signal() const;
465
466
operator Dictionary() const;
467
operator Array() const;
468
469
operator PackedByteArray() const;
470
operator PackedInt32Array() const;
471
operator PackedInt64Array() const;
472
operator PackedFloat32Array() const;
473
operator PackedFloat64Array() const;
474
operator PackedStringArray() const;
475
operator PackedVector3Array() const;
476
operator PackedVector2Array() const;
477
operator PackedColorArray() const;
478
operator PackedVector4Array() const;
479
480
operator Vector<::RID>() const;
481
operator Vector<Plane>() const;
482
operator Vector<Face3>() const;
483
operator Vector<Variant>() const;
484
operator Vector<StringName>() const;
485
486
operator IPAddress() const;
487
488
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
489
_FORCE_INLINE_ operator T() const { return static_cast<T>(operator int64_t()); }
490
template <typename T>
491
_FORCE_INLINE_ operator BitField<T>() const { return static_cast<T>(operator uint64_t()); }
492
493
Object *get_validated_object() const;
494
Object *get_validated_object_with_check(bool &r_previously_freed) const;
495
496
Variant(bool p_bool);
497
Variant(int64_t p_int64);
498
Variant(int32_t p_int32);
499
Variant(int16_t p_int16);
500
Variant(int8_t p_int8);
501
Variant(uint64_t p_uint64);
502
Variant(uint32_t p_uint32);
503
Variant(uint16_t p_uint16);
504
Variant(uint8_t p_uint8);
505
Variant(float p_float);
506
Variant(double p_double);
507
Variant(const ObjectID &p_id);
508
Variant(const String &p_string);
509
Variant(const StringName &p_string);
510
Variant(const char *const p_cstring);
511
Variant(const char32_t *p_wstring);
512
Variant(const Vector2 &p_vector2);
513
Variant(const Vector2i &p_vector2i);
514
Variant(const Rect2 &p_rect2);
515
Variant(const Rect2i &p_rect2i);
516
Variant(const Vector3 &p_vector3);
517
Variant(const Vector3i &p_vector3i);
518
Variant(const Vector4 &p_vector4);
519
Variant(const Vector4i &p_vector4i);
520
Variant(const Plane &p_plane);
521
Variant(const ::AABB &p_aabb);
522
Variant(const Quaternion &p_quat);
523
Variant(const Basis &p_matrix);
524
Variant(const Transform2D &p_transform);
525
Variant(const Transform3D &p_transform);
526
Variant(const Projection &p_projection);
527
Variant(const Color &p_color);
528
Variant(const NodePath &p_node_path);
529
Variant(const ::RID &p_rid);
530
Variant(const Object *p_object);
531
Variant(const Callable &p_callable);
532
Variant(const Signal &p_signal);
533
Variant(const Dictionary &p_dictionary);
534
535
Variant(std::initializer_list<Variant> p_init);
536
Variant(const Array &p_array);
537
Variant(const PackedByteArray &p_byte_array);
538
Variant(const PackedInt32Array &p_int32_array);
539
Variant(const PackedInt64Array &p_int64_array);
540
Variant(const PackedFloat32Array &p_float32_array);
541
Variant(const PackedFloat64Array &p_float64_array);
542
Variant(const PackedStringArray &p_string_array);
543
Variant(const PackedVector2Array &p_vector2_array);
544
Variant(const PackedVector3Array &p_vector3_array);
545
Variant(const PackedColorArray &p_color_array);
546
Variant(const PackedVector4Array &p_vector4_array);
547
548
Variant(const Vector<::RID> &p_array); // helper
549
Variant(const Vector<Plane> &p_array); // helper
550
Variant(const Vector<Face3> &p_face_array);
551
Variant(const Vector<Variant> &p_array);
552
Variant(const Vector<StringName> &p_array);
553
554
Variant(const IPAddress &p_address);
555
556
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
557
_FORCE_INLINE_ Variant(T p_enum) :
558
Variant(static_cast<int64_t>(p_enum)) {}
559
template <typename T>
560
_FORCE_INLINE_ Variant(BitField<T> p_bitfield) :
561
Variant(static_cast<uint64_t>(p_bitfield)) {}
562
563
// If this changes the table in variant_op must be updated
564
enum Operator {
565
//comparison
566
OP_EQUAL,
567
OP_NOT_EQUAL,
568
OP_LESS,
569
OP_LESS_EQUAL,
570
OP_GREATER,
571
OP_GREATER_EQUAL,
572
//mathematic
573
OP_ADD,
574
OP_SUBTRACT,
575
OP_MULTIPLY,
576
OP_DIVIDE,
577
OP_NEGATE,
578
OP_POSITIVE,
579
OP_MODULE,
580
OP_POWER,
581
//bitwise
582
OP_SHIFT_LEFT,
583
OP_SHIFT_RIGHT,
584
OP_BIT_AND,
585
OP_BIT_OR,
586
OP_BIT_XOR,
587
OP_BIT_NEGATE,
588
//logic
589
OP_AND,
590
OP_OR,
591
OP_XOR,
592
OP_NOT,
593
//containment
594
OP_IN,
595
OP_MAX
596
597
};
598
599
static String get_operator_name(Operator p_op);
600
static void evaluate(const Operator &p_op, const Variant &p_a, const Variant &p_b, Variant &r_ret, bool &r_valid);
601
static _FORCE_INLINE_ Variant evaluate(const Operator &p_op, const Variant &p_a, const Variant &p_b) {
602
bool valid = true;
603
Variant res;
604
evaluate(p_op, p_a, p_b, res, valid);
605
return res;
606
}
607
608
static Variant::Type get_operator_return_type(Operator p_operator, Type p_type_a, Type p_type_b);
609
typedef void (*ValidatedOperatorEvaluator)(const Variant *left, const Variant *right, Variant *r_ret);
610
static ValidatedOperatorEvaluator get_validated_operator_evaluator(Operator p_operator, Type p_type_a, Type p_type_b);
611
typedef void (*PTROperatorEvaluator)(const void *left, const void *right, void *r_ret);
612
static PTROperatorEvaluator get_ptr_operator_evaluator(Operator p_operator, Type p_type_a, Type p_type_b);
613
614
void zero();
615
Variant duplicate(bool p_deep = false) const;
616
Variant duplicate_deep(ResourceDeepDuplicateMode p_deep_subresources_mode = RESOURCE_DEEP_DUPLICATE_INTERNAL) const;
617
Variant recursive_duplicate(bool p_deep, ResourceDeepDuplicateMode p_deep_subresources_mode, int recursion_count) const;
618
619
/* Built-In Methods */
620
621
typedef void (*ValidatedBuiltInMethod)(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret);
622
typedef void (*PTRBuiltInMethod)(void *p_base, const void **p_args, void *r_ret, int p_argcount);
623
624
static bool has_builtin_method(Variant::Type p_type, const StringName &p_method);
625
626
static ValidatedBuiltInMethod get_validated_builtin_method(Variant::Type p_type, const StringName &p_method);
627
static PTRBuiltInMethod get_ptr_builtin_method(Variant::Type p_type, const StringName &p_method);
628
629
static MethodInfo get_builtin_method_info(Variant::Type p_type, const StringName &p_method);
630
static int get_builtin_method_argument_count(Variant::Type p_type, const StringName &p_method);
631
static Variant::Type get_builtin_method_argument_type(Variant::Type p_type, const StringName &p_method, int p_argument);
632
static String get_builtin_method_argument_name(Variant::Type p_type, const StringName &p_method, int p_argument);
633
static Vector<Variant> get_builtin_method_default_arguments(Variant::Type p_type, const StringName &p_method);
634
static bool has_builtin_method_return_value(Variant::Type p_type, const StringName &p_method);
635
static Variant::Type get_builtin_method_return_type(Variant::Type p_type, const StringName &p_method);
636
static bool is_builtin_method_const(Variant::Type p_type, const StringName &p_method);
637
static bool is_builtin_method_static(Variant::Type p_type, const StringName &p_method);
638
static bool is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method);
639
static void get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list);
640
static int get_builtin_method_count(Variant::Type p_type);
641
static uint32_t get_builtin_method_hash(Variant::Type p_type, const StringName &p_method);
642
643
void callp(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
644
645
template <typename... VarArgs>
646
Variant call(const StringName &p_method, VarArgs... p_args) {
647
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
648
const Variant *argptrs[sizeof...(p_args) + 1];
649
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
650
argptrs[i] = &args[i];
651
}
652
Callable::CallError cerr;
653
Variant ret;
654
callp(p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), ret, cerr);
655
if (cerr.error != Callable::CallError::CALL_OK) {
656
_variant_call_error(p_method, cerr);
657
}
658
return ret;
659
}
660
661
void call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
662
static void call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
663
664
static String get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
665
static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
666
static String get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
667
668
//dynamic (includes Object)
669
void get_method_list(List<MethodInfo> *p_list) const;
670
bool has_method(const StringName &p_method) const;
671
672
/* Constructors */
673
674
typedef void (*ValidatedConstructor)(Variant *r_base, const Variant **p_args);
675
typedef void (*PTRConstructor)(void *base, const void **p_args);
676
677
static int get_constructor_count(Variant::Type p_type);
678
static ValidatedConstructor get_validated_constructor(Variant::Type p_type, int p_constructor);
679
static PTRConstructor get_ptr_constructor(Variant::Type p_type, int p_constructor);
680
static int get_constructor_argument_count(Variant::Type p_type, int p_constructor);
681
static Variant::Type get_constructor_argument_type(Variant::Type p_type, int p_constructor, int p_argument);
682
static String get_constructor_argument_name(Variant::Type p_type, int p_constructor, int p_argument);
683
static void construct(Variant::Type, Variant &base, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
684
685
static void get_constructor_list(Type p_type, List<MethodInfo> *r_list); //convenience
686
687
/* Destructors */
688
689
// Only ptrcall is available.
690
typedef void (*PTRDestructor)(void *base);
691
692
static PTRDestructor get_ptr_destructor(Variant::Type p_type);
693
static bool has_destructor(Variant::Type p_type);
694
695
/* Properties */
696
697
void set_named(const StringName &p_member, const Variant &p_value, bool &r_valid);
698
Variant get_named(const StringName &p_member, bool &r_valid) const;
699
700
typedef void (*ValidatedSetter)(Variant *base, const Variant *value);
701
typedef void (*ValidatedGetter)(const Variant *base, Variant *value);
702
703
static bool has_member(Variant::Type p_type, const StringName &p_member);
704
static Variant::Type get_member_type(Variant::Type p_type, const StringName &p_member);
705
static void get_member_list(Type p_type, List<StringName> *r_members);
706
static int get_member_count(Type p_type);
707
708
static ValidatedSetter get_member_validated_setter(Variant::Type p_type, const StringName &p_member);
709
static ValidatedGetter get_member_validated_getter(Variant::Type p_type, const StringName &p_member);
710
711
typedef void (*PTRSetter)(void *base, const void *value);
712
typedef void (*PTRGetter)(const void *base, void *value);
713
714
static PTRSetter get_member_ptr_setter(Variant::Type p_type, const StringName &p_member);
715
static PTRGetter get_member_ptr_getter(Variant::Type p_type, const StringName &p_member);
716
717
/* Indexing */
718
719
static bool has_indexing(Variant::Type p_type);
720
static Variant::Type get_indexed_element_type(Variant::Type p_type);
721
static uint32_t get_indexed_element_usage(Variant::Type p_type);
722
723
typedef void (*ValidatedIndexedSetter)(Variant *base, int64_t index, const Variant *value, bool *oob);
724
typedef void (*ValidatedIndexedGetter)(const Variant *base, int64_t index, Variant *value, bool *oob);
725
726
static ValidatedIndexedSetter get_member_validated_indexed_setter(Variant::Type p_type);
727
static ValidatedIndexedGetter get_member_validated_indexed_getter(Variant::Type p_type);
728
729
typedef void (*PTRIndexedSetter)(void *base, int64_t index, const void *value);
730
typedef void (*PTRIndexedGetter)(const void *base, int64_t index, void *value);
731
732
static PTRIndexedSetter get_member_ptr_indexed_setter(Variant::Type p_type);
733
static PTRIndexedGetter get_member_ptr_indexed_getter(Variant::Type p_type);
734
735
void set_indexed(int64_t p_index, const Variant &p_value, bool &r_valid, bool &r_oob);
736
Variant get_indexed(int64_t p_index, bool &r_valid, bool &r_oob) const;
737
738
uint64_t get_indexed_size() const;
739
740
/* Keying */
741
742
static bool is_keyed(Variant::Type p_type);
743
744
typedef void (*ValidatedKeyedSetter)(Variant *base, const Variant *key, const Variant *value, bool *valid);
745
typedef void (*ValidatedKeyedGetter)(const Variant *base, const Variant *key, Variant *value, bool *valid);
746
typedef bool (*ValidatedKeyedChecker)(const Variant *base, const Variant *key, bool *valid);
747
748
static ValidatedKeyedSetter get_member_validated_keyed_setter(Variant::Type p_type);
749
static ValidatedKeyedGetter get_member_validated_keyed_getter(Variant::Type p_type);
750
static ValidatedKeyedChecker get_member_validated_keyed_checker(Variant::Type p_type);
751
752
typedef void (*PTRKeyedSetter)(void *base, const void *key, const void *value);
753
typedef void (*PTRKeyedGetter)(const void *base, const void *key, void *value);
754
typedef uint32_t (*PTRKeyedChecker)(const void *base, const void *key);
755
756
static PTRKeyedSetter get_member_ptr_keyed_setter(Variant::Type p_type);
757
static PTRKeyedGetter get_member_ptr_keyed_getter(Variant::Type p_type);
758
static PTRKeyedChecker get_member_ptr_keyed_checker(Variant::Type p_type);
759
760
void set_keyed(const Variant &p_key, const Variant &p_value, bool &r_valid);
761
Variant get_keyed(const Variant &p_key, bool &r_valid) const;
762
bool has_key(const Variant &p_key, bool &r_valid) const;
763
764
/* Generic */
765
enum VariantSetError {
766
SET_OK,
767
SET_KEYED_ERR,
768
SET_NAMED_ERR,
769
SET_INDEXED_ERR
770
};
771
enum VariantGetError {
772
GET_OK,
773
GET_KEYED_ERR,
774
GET_NAMED_ERR,
775
GET_INDEXED_ERR
776
};
777
void set(const Variant &p_index, const Variant &p_value, bool *r_valid = nullptr, VariantSetError *err_code = nullptr);
778
Variant get(const Variant &p_index, bool *r_valid = nullptr, VariantGetError *err_code = nullptr) const;
779
bool in(const Variant &p_index, bool *r_valid = nullptr) const;
780
781
bool iter_init(Variant &r_iter, bool &r_valid) const;
782
bool iter_next(Variant &r_iter, bool &r_valid) const;
783
Variant iter_get(const Variant &r_iter, bool &r_valid) const;
784
785
void get_property_list(List<PropertyInfo> *p_list) const;
786
787
static void call_utility_function(const StringName &p_name, Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
788
static bool has_utility_function(const StringName &p_name);
789
790
typedef void (*ValidatedUtilityFunction)(Variant *r_ret, const Variant **p_args, int p_argcount);
791
typedef void (*PTRUtilityFunction)(void *r_ret, const void **p_args, int p_argcount);
792
793
static ValidatedUtilityFunction get_validated_utility_function(const StringName &p_name);
794
static PTRUtilityFunction get_ptr_utility_function(const StringName &p_name);
795
796
enum UtilityFunctionType {
797
UTILITY_FUNC_TYPE_MATH,
798
UTILITY_FUNC_TYPE_RANDOM,
799
UTILITY_FUNC_TYPE_GENERAL,
800
};
801
802
static UtilityFunctionType get_utility_function_type(const StringName &p_name);
803
804
static MethodInfo get_utility_function_info(const StringName &p_name);
805
static int get_utility_function_argument_count(const StringName &p_name);
806
static Variant::Type get_utility_function_argument_type(const StringName &p_name, int p_arg);
807
static String get_utility_function_argument_name(const StringName &p_name, int p_arg);
808
static bool has_utility_function_return_value(const StringName &p_name);
809
static Variant::Type get_utility_function_return_type(const StringName &p_name);
810
static bool is_utility_function_vararg(const StringName &p_name);
811
static uint32_t get_utility_function_hash(const StringName &p_name);
812
813
static void get_utility_function_list(List<StringName> *r_functions);
814
static int get_utility_function_count();
815
816
//argsVariant call()
817
818
bool operator==(const Variant &p_variant) const;
819
bool operator!=(const Variant &p_variant) const;
820
bool operator<(const Variant &p_variant) const;
821
uint32_t hash() const;
822
uint32_t recursive_hash(int recursion_count) const;
823
824
// By default, performs a semantic comparison. Otherwise, numeric/binary comparison (if appropriate).
825
bool hash_compare(const Variant &p_variant, int recursion_count = 0, bool semantic_comparison = true) const;
826
bool identity_compare(const Variant &p_variant) const;
827
bool booleanize() const;
828
String stringify(int recursion_count = 0) const;
829
String to_json_string() const;
830
831
static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants);
832
static int get_constants_count_for_type(Variant::Type p_type);
833
static bool has_constant(Variant::Type p_type, const StringName &p_value);
834
static Variant get_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid = nullptr);
835
836
static void get_enums_for_type(Variant::Type p_type, List<StringName> *p_enums);
837
static void get_enumerations_for_enum(Variant::Type p_type, const StringName &p_enum_name, List<StringName> *p_enumerations);
838
static int get_enum_value(Variant::Type p_type, const StringName &p_enum_name, const StringName &p_enumeration, bool *r_valid = nullptr);
839
static bool has_enum(Variant::Type p_type, const StringName &p_enum_name);
840
static StringName get_enum_for_enumeration(Variant::Type p_type, const StringName &p_enumeration);
841
842
typedef String (*ObjectDeConstruct)(const Variant &p_object, void *ud);
843
typedef void (*ObjectConstruct)(const String &p_text, void *ud, Variant &r_value);
844
845
String get_construct_string() const;
846
static void construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct = nullptr, void *p_construct_ud = nullptr);
847
848
void operator=(const Variant &p_variant); // only this is enough for all the other types
849
void operator=(Variant &&p_variant) {
850
if (unlikely(this == &p_variant)) {
851
return;
852
}
853
clear();
854
type = p_variant.type;
855
_data = p_variant._data;
856
p_variant.type = NIL;
857
}
858
859
static void register_types();
860
static void unregister_types();
861
862
Variant(const Variant &p_variant);
863
Variant(Variant &&p_variant) {
864
type = p_variant.type;
865
_data = p_variant._data;
866
p_variant.type = NIL;
867
}
868
_FORCE_INLINE_ Variant() {}
869
_FORCE_INLINE_ ~Variant() {
870
if (unlikely(needs_deinit[type])) { // Make it fast for types that don't need deinit.
871
_clear_internal();
872
}
873
}
874
};
875
876
//typedef Dictionary Dictionary; no
877
//typedef Array Array;
878
879
template <typename... VarArgs>
880
Vector<Variant> varray(VarArgs... p_args) {
881
Vector<Variant> v;
882
883
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
884
uint32_t argc = sizeof...(p_args);
885
886
if (argc > 0) {
887
v.resize(argc);
888
Variant *vw = v.ptrw();
889
890
for (uint32_t i = 0; i < argc; i++) {
891
vw[i] = args[i];
892
}
893
}
894
return v;
895
}
896
897
struct VariantHasher {
898
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
899
};
900
901
struct VariantComparator {
902
static _FORCE_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) { return p_lhs.hash_compare(p_rhs); }
903
};
904
905
struct StringLikeVariantComparator {
906
static bool compare(const Variant &p_lhs, const Variant &p_rhs);
907
};
908
909
struct StringLikeVariantOrder {
910
static bool compare(const Variant &p_lhs, const Variant &p_rhs);
911
912
_ALWAYS_INLINE_ bool operator()(const Variant &p_lhs, const Variant &p_rhs) const {
913
return compare(p_lhs, p_rhs);
914
}
915
};
916
917
Variant::ObjData &Variant::_get_obj() {
918
return *reinterpret_cast<ObjData *>(&_data._mem[0]);
919
}
920
921
const Variant::ObjData &Variant::_get_obj() const {
922
return *reinterpret_cast<const ObjData *>(&_data._mem[0]);
923
}
924
925
template <typename... VarArgs>
926
String vformat(const String &p_text, const VarArgs... p_args) {
927
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
928
Array args_array;
929
args_array.resize(sizeof...(p_args));
930
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
931
args_array[i] = args[i];
932
}
933
934
bool error = false;
935
String fmt = p_text.sprintf(args_array, &error);
936
937
ERR_FAIL_COND_V_MSG(error, String(), String("Formatting error in string \"") + p_text + "\": " + fmt + ".");
938
939
return fmt;
940
}
941
942
template <typename... VarArgs>
943
Variant Callable::call(VarArgs... p_args) const {
944
Variant args[sizeof...(p_args) + 1] = { p_args..., 0 }; // +1 makes sure zero sized arrays are also supported.
945
const Variant *argptrs[sizeof...(p_args) + 1];
946
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
947
argptrs[i] = &args[i];
948
}
949
950
Variant ret;
951
CallError ce;
952
callp(sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), ret, ce);
953
return ret;
954
}
955
956
template <typename... VarArgs>
957
Callable Callable::bind(VarArgs... p_args) const {
958
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
959
const Variant *argptrs[sizeof...(p_args) + 1];
960
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
961
argptrs[i] = &args[i];
962
}
963
return bindp(sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
964
}
965
966
Variant &Array::Iterator::operator*() const {
967
if (unlikely(read_only)) {
968
*read_only = *element_ptr;
969
return *read_only;
970
}
971
return *element_ptr;
972
}
973
974
Variant *Array::Iterator::operator->() const {
975
if (unlikely(read_only)) {
976
*read_only = *element_ptr;
977
return read_only;
978
}
979
return element_ptr;
980
}
981
982
Array::Iterator &Array::Iterator::operator++() {
983
element_ptr++;
984
return *this;
985
}
986
987
Array::Iterator &Array::Iterator::operator--() {
988
element_ptr--;
989
return *this;
990
}
991
992
const Variant &Array::ConstIterator::operator*() const {
993
return *element_ptr;
994
}
995
996
const Variant *Array::ConstIterator::operator->() const {
997
return element_ptr;
998
}
999
1000
Array::ConstIterator &Array::ConstIterator::operator++() {
1001
element_ptr++;
1002
return *this;
1003
}
1004
1005
Array::ConstIterator &Array::ConstIterator::operator--() {
1006
element_ptr--;
1007
return *this;
1008
}
1009
1010
// Zero-constructing Variant results in NULL.
1011
template <>
1012
struct is_zero_constructible<Variant> : std::true_type {};
1013
1014