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