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#ifndef VARIANT_H
32#define VARIANT_H
33
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/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
63class Object;
64
65struct PropertyInfo;
66struct MethodInfo;
67
68typedef Vector<uint8_t> PackedByteArray;
69typedef Vector<int32_t> PackedInt32Array;
70typedef Vector<int64_t> PackedInt64Array;
71typedef Vector<float> PackedFloat32Array;
72typedef Vector<double> PackedFloat64Array;
73typedef Vector<String> PackedStringArray;
74typedef Vector<Vector2> PackedVector2Array;
75typedef Vector<Vector3> PackedVector3Array;
76typedef Vector<Color> PackedColorArray;
77
78class Variant {
79public:
80 // If this changes the table in variant_op must be updated
81 enum Type {
82 NIL,
83
84 // atomic types
85 BOOL,
86 INT,
87 FLOAT,
88 STRING,
89
90 // math types
91 VECTOR2,
92 VECTOR2I,
93 RECT2,
94 RECT2I,
95 VECTOR3,
96 VECTOR3I,
97 TRANSFORM2D,
98 VECTOR4,
99 VECTOR4I,
100 PLANE,
101 QUATERNION,
102 AABB,
103 BASIS,
104 TRANSFORM3D,
105 PROJECTION,
106
107 // misc types
108 COLOR,
109 STRING_NAME,
110 NODE_PATH,
111 RID,
112 OBJECT,
113 CALLABLE,
114 SIGNAL,
115 DICTIONARY,
116 ARRAY,
117
118 // typed arrays
119 PACKED_BYTE_ARRAY,
120 PACKED_INT32_ARRAY,
121 PACKED_INT64_ARRAY,
122 PACKED_FLOAT32_ARRAY,
123 PACKED_FLOAT64_ARRAY,
124 PACKED_STRING_ARRAY,
125 PACKED_VECTOR2_ARRAY,
126 PACKED_VECTOR3_ARRAY,
127 PACKED_COLOR_ARRAY,
128
129 VARIANT_MAX
130 };
131
132 enum {
133 // Maximum recursion depth allowed when serializing variants.
134 MAX_RECURSION_DEPTH = 1024,
135 };
136
137private:
138 struct Pools {
139 union BucketSmall {
140 BucketSmall() {}
141 ~BucketSmall() {}
142 Transform2D _transform2d;
143 ::AABB _aabb;
144 };
145 union BucketMedium {
146 BucketMedium() {}
147 ~BucketMedium() {}
148 Basis _basis;
149 Transform3D _transform3d;
150 };
151 union BucketLarge {
152 BucketLarge() {}
153 ~BucketLarge() {}
154 Projection _projection;
155 };
156
157 static PagedAllocator<BucketSmall, true> _bucket_small;
158 static PagedAllocator<BucketMedium, true> _bucket_medium;
159 static PagedAllocator<BucketLarge, true> _bucket_large;
160 };
161
162 friend struct _VariantCall;
163 friend class VariantInternal;
164 // Variant takes 20 bytes when real_t is float, and 36 if double
165 // it only allocates extra memory for aabb/matrix.
166
167 Type type = NIL;
168
169 struct ObjData {
170 ObjectID id;
171 Object *obj = nullptr;
172 };
173
174 /* array helpers */
175 struct PackedArrayRefBase {
176 SafeRefCount refcount;
177 _FORCE_INLINE_ PackedArrayRefBase *reference() {
178 if (this->refcount.ref()) {
179 return this;
180 } else {
181 return nullptr;
182 }
183 }
184 static _FORCE_INLINE_ PackedArrayRefBase *reference_from(PackedArrayRefBase *p_base, PackedArrayRefBase *p_from) {
185 if (p_base == p_from) {
186 return p_base; //same thing, do nothing
187 }
188
189 if (p_from->reference()) {
190 if (p_base->refcount.unref()) {
191 memdelete(p_base);
192 }
193 return p_from;
194 } else {
195 return p_base; //keep, could not reference new
196 }
197 }
198 static _FORCE_INLINE_ void destroy(PackedArrayRefBase *p_array) {
199 if (p_array->refcount.unref()) {
200 memdelete(p_array);
201 }
202 }
203 _FORCE_INLINE_ virtual ~PackedArrayRefBase() {} //needs virtual destructor, but make inline
204 };
205
206 template <class T>
207 struct PackedArrayRef : public PackedArrayRefBase {
208 Vector<T> array;
209 static _FORCE_INLINE_ PackedArrayRef<T> *create() {
210 return memnew(PackedArrayRef<T>);
211 }
212 static _FORCE_INLINE_ PackedArrayRef<T> *create(const Vector<T> &p_from) {
213 return memnew(PackedArrayRef<T>(p_from));
214 }
215
216 static _FORCE_INLINE_ const Vector<T> &get_array(PackedArrayRefBase *p_base) {
217 return static_cast<PackedArrayRef<T> *>(p_base)->array;
218 }
219 static _FORCE_INLINE_ Vector<T> *get_array_ptr(const PackedArrayRefBase *p_base) {
220 return &const_cast<PackedArrayRef<T> *>(static_cast<const PackedArrayRef<T> *>(p_base))->array;
221 }
222
223 _FORCE_INLINE_ PackedArrayRef(const Vector<T> &p_from) {
224 array = p_from;
225 refcount.init();
226 }
227 _FORCE_INLINE_ PackedArrayRef() {
228 refcount.init();
229 }
230 };
231
232 /* end of array helpers */
233 _ALWAYS_INLINE_ ObjData &_get_obj();
234 _ALWAYS_INLINE_ const ObjData &_get_obj() const;
235
236 union {
237 bool _bool;
238 int64_t _int;
239 double _float;
240 Transform2D *_transform2d;
241 ::AABB *_aabb;
242 Basis *_basis;
243 Transform3D *_transform3d;
244 Projection *_projection;
245 PackedArrayRefBase *packed_array;
246 void *_ptr; //generic pointer
247 uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]{ 0 };
248 } _data alignas(8);
249
250 void reference(const Variant &p_variant);
251 static bool initialize_ref(Object *p_object);
252
253 void _clear_internal();
254
255 _FORCE_INLINE_ void clear() {
256 static const bool needs_deinit[Variant::VARIANT_MAX] = {
257 false, //NIL,
258 false, //BOOL,
259 false, //INT,
260 false, //FLOAT,
261 true, //STRING,
262 false, //VECTOR2,
263 false, //VECTOR2I,
264 false, //RECT2,
265 false, //RECT2I,
266 false, //VECTOR3,
267 false, //VECTOR3I,
268 true, //TRANSFORM2D,
269 false, //VECTOR4,
270 false, //VECTOR4I,
271 false, //PLANE,
272 false, //QUATERNION,
273 true, //AABB,
274 true, //BASIS,
275 true, //TRANSFORM,
276 true, //PROJECTION,
277
278 // misc types
279 false, //COLOR,
280 true, //STRING_NAME,
281 true, //NODE_PATH,
282 false, //RID,
283 true, //OBJECT,
284 true, //CALLABLE,
285 true, //SIGNAL,
286 true, //DICTIONARY,
287 true, //ARRAY,
288
289 // typed arrays
290 true, //PACKED_BYTE_ARRAY,
291 true, //PACKED_INT32_ARRAY,
292 true, //PACKED_INT64_ARRAY,
293 true, //PACKED_FLOAT32_ARRAY,
294 true, //PACKED_FLOAT64_ARRAY,
295 true, //PACKED_STRING_ARRAY,
296 true, //PACKED_VECTOR2_ARRAY,
297 true, //PACKED_VECTOR3_ARRAY,
298 true, //PACKED_COLOR_ARRAY,
299 };
300
301 if (unlikely(needs_deinit[type])) { // Make it fast for types that don't need deinit.
302 _clear_internal();
303 }
304 type = NIL;
305 }
306
307 static void _register_variant_operators();
308 static void _unregister_variant_operators();
309 static void _register_variant_methods();
310 static void _unregister_variant_methods();
311 static void _register_variant_setters_getters();
312 static void _unregister_variant_setters_getters();
313 static void _register_variant_constructors();
314 static void _unregister_variant_destructors();
315 static void _register_variant_destructors();
316 static void _unregister_variant_constructors();
317 static void _register_variant_utility_functions();
318 static void _unregister_variant_utility_functions();
319
320 void _variant_call_error(const String &p_method, Callable::CallError &error);
321
322 // Avoid accidental conversion. If you reached this point, it's because you most likely forgot to dereference
323 // a Variant pointer (so add * like this: *variant_pointer).
324
325 Variant(const Variant *) {}
326 Variant(const Variant **) {}
327
328public:
329 _FORCE_INLINE_ Type get_type() const {
330 return type;
331 }
332 static String get_type_name(Variant::Type p_type);
333 static bool can_convert(Type p_type_from, Type p_type_to);
334 static bool can_convert_strict(Type p_type_from, Type p_type_to);
335 static bool is_type_shared(Variant::Type p_type);
336
337 bool is_ref_counted() const;
338 _FORCE_INLINE_ bool is_num() const {
339 return type == INT || type == FLOAT;
340 }
341 _FORCE_INLINE_ bool is_array() const {
342 return type >= ARRAY;
343 }
344 bool is_shared() const;
345 bool is_zero() const;
346 bool is_one() const;
347 bool is_null() const;
348
349 // Make sure Variant is not implicitly cast when accessing it with bracket notation (GH-49469).
350 Variant &operator[](const Variant &p_key) = delete;
351 const Variant &operator[](const Variant &p_key) const = delete;
352
353 operator bool() const;
354 operator signed int() const;
355 operator unsigned int() const; // this is the real one
356 operator signed short() const;
357 operator unsigned short() const;
358 operator signed char() const;
359 operator unsigned char() const;
360 //operator long unsigned int() const;
361 operator int64_t() const;
362 operator uint64_t() const;
363#ifdef NEED_LONG_INT
364 operator signed long() const;
365 operator unsigned long() const;
366#endif
367
368 operator ObjectID() const;
369
370 operator char32_t() const;
371 operator float() const;
372 operator double() const;
373 operator String() const;
374 operator StringName() const;
375 operator Vector2() const;
376 operator Vector2i() const;
377 operator Rect2() const;
378 operator Rect2i() const;
379 operator Vector3() const;
380 operator Vector3i() const;
381 operator Vector4() const;
382 operator Vector4i() const;
383 operator Plane() const;
384 operator ::AABB() const;
385 operator Quaternion() const;
386 operator Basis() const;
387 operator Transform2D() const;
388 operator Transform3D() const;
389 operator Projection() const;
390
391 operator Color() const;
392 operator NodePath() const;
393 operator ::RID() const;
394
395 operator Object *() const;
396
397 operator Callable() const;
398 operator Signal() const;
399
400 operator Dictionary() const;
401 operator Array() const;
402
403 operator Vector<uint8_t>() const;
404 operator Vector<int32_t>() const;
405 operator Vector<int64_t>() const;
406 operator Vector<float>() const;
407 operator Vector<double>() const;
408 operator Vector<String>() const;
409 operator Vector<Vector3>() const;
410 operator Vector<Color>() const;
411 operator Vector<Plane>() const;
412 operator Vector<Face3>() const;
413
414 operator Vector<Variant>() const;
415 operator Vector<StringName>() const;
416 operator Vector<::RID>() const;
417 operator Vector<Vector2>() const;
418
419 // some core type enums to convert to
420 operator Side() const;
421 operator Orientation() const;
422
423 operator IPAddress() const;
424
425 Object *get_validated_object() const;
426 Object *get_validated_object_with_check(bool &r_previously_freed) const;
427
428 Variant(bool p_bool);
429 Variant(signed int p_int); // real one
430 Variant(unsigned int p_int);
431#ifdef NEED_LONG_INT
432 Variant(signed long p_long); // real one
433 Variant(unsigned long p_long);
434#endif
435 Variant(signed short p_short); // real one
436 Variant(unsigned short p_short);
437 Variant(signed char p_char); // real one
438 Variant(unsigned char p_char);
439 Variant(int64_t p_int); // real one
440 Variant(uint64_t p_int);
441 Variant(float p_float);
442 Variant(double p_double);
443 Variant(const ObjectID &p_id);
444 Variant(const String &p_string);
445 Variant(const StringName &p_string);
446 Variant(const char *const p_cstring);
447 Variant(const char32_t *p_wstring);
448 Variant(const Vector2 &p_vector2);
449 Variant(const Vector2i &p_vector2i);
450 Variant(const Rect2 &p_rect2);
451 Variant(const Rect2i &p_rect2i);
452 Variant(const Vector3 &p_vector3);
453 Variant(const Vector3i &p_vector3i);
454 Variant(const Vector4 &p_vector4);
455 Variant(const Vector4i &p_vector4i);
456 Variant(const Plane &p_plane);
457 Variant(const ::AABB &p_aabb);
458 Variant(const Quaternion &p_quat);
459 Variant(const Basis &p_matrix);
460 Variant(const Transform2D &p_transform);
461 Variant(const Transform3D &p_transform);
462 Variant(const Projection &p_projection);
463 Variant(const Color &p_color);
464 Variant(const NodePath &p_node_path);
465 Variant(const ::RID &p_rid);
466 Variant(const Object *p_object);
467 Variant(const Callable &p_callable);
468 Variant(const Signal &p_signal);
469 Variant(const Dictionary &p_dictionary);
470
471 Variant(const Array &p_array);
472 Variant(const Vector<Plane> &p_array); // helper
473 Variant(const Vector<uint8_t> &p_byte_array);
474 Variant(const Vector<int32_t> &p_int32_array);
475 Variant(const Vector<int64_t> &p_int64_array);
476 Variant(const Vector<float> &p_float32_array);
477 Variant(const Vector<double> &p_float64_array);
478 Variant(const Vector<String> &p_string_array);
479 Variant(const Vector<Vector3> &p_vector3_array);
480 Variant(const Vector<Color> &p_color_array);
481 Variant(const Vector<Face3> &p_face_array);
482
483 Variant(const Vector<Variant> &p_array);
484 Variant(const Vector<StringName> &p_array);
485 Variant(const Vector<::RID> &p_array); // helper
486 Variant(const Vector<Vector2> &p_array); // helper
487
488 Variant(const IPAddress &p_address);
489
490#define VARIANT_ENUM_CLASS_CONSTRUCTOR(m_enum) \
491 Variant(m_enum p_value) { \
492 type = INT; \
493 _data._int = (int64_t)p_value; \
494 }
495
496 // Only enum classes that need to be bound need this to be defined.
497 VARIANT_ENUM_CLASS_CONSTRUCTOR(EulerOrder)
498 VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyAxis)
499 VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyButton)
500 VARIANT_ENUM_CLASS_CONSTRUCTOR(Key)
501 VARIANT_ENUM_CLASS_CONSTRUCTOR(MIDIMessage)
502 VARIANT_ENUM_CLASS_CONSTRUCTOR(MouseButton)
503
504#undef VARIANT_ENUM_CLASS_CONSTRUCTOR
505
506 // If this changes the table in variant_op must be updated
507 enum Operator {
508 //comparison
509 OP_EQUAL,
510 OP_NOT_EQUAL,
511 OP_LESS,
512 OP_LESS_EQUAL,
513 OP_GREATER,
514 OP_GREATER_EQUAL,
515 //mathematic
516 OP_ADD,
517 OP_SUBTRACT,
518 OP_MULTIPLY,
519 OP_DIVIDE,
520 OP_NEGATE,
521 OP_POSITIVE,
522 OP_MODULE,
523 OP_POWER,
524 //bitwise
525 OP_SHIFT_LEFT,
526 OP_SHIFT_RIGHT,
527 OP_BIT_AND,
528 OP_BIT_OR,
529 OP_BIT_XOR,
530 OP_BIT_NEGATE,
531 //logic
532 OP_AND,
533 OP_OR,
534 OP_XOR,
535 OP_NOT,
536 //containment
537 OP_IN,
538 OP_MAX
539
540 };
541
542 static String get_operator_name(Operator p_op);
543 static void evaluate(const Operator &p_op, const Variant &p_a, const Variant &p_b, Variant &r_ret, bool &r_valid);
544 static _FORCE_INLINE_ Variant evaluate(const Operator &p_op, const Variant &p_a, const Variant &p_b) {
545 bool valid = true;
546 Variant res;
547 evaluate(p_op, p_a, p_b, res, valid);
548 return res;
549 }
550
551 static Variant::Type get_operator_return_type(Operator p_operator, Type p_type_a, Type p_type_b);
552 typedef void (*ValidatedOperatorEvaluator)(const Variant *left, const Variant *right, Variant *r_ret);
553 static ValidatedOperatorEvaluator get_validated_operator_evaluator(Operator p_operator, Type p_type_a, Type p_type_b);
554 typedef void (*PTROperatorEvaluator)(const void *left, const void *right, void *r_ret);
555 static PTROperatorEvaluator get_ptr_operator_evaluator(Operator p_operator, Type p_type_a, Type p_type_b);
556
557 void zero();
558 Variant duplicate(bool p_deep = false) const;
559 Variant recursive_duplicate(bool p_deep, int recursion_count) const;
560
561 /* Built-In Methods */
562
563 typedef void (*ValidatedBuiltInMethod)(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret);
564 typedef void (*PTRBuiltInMethod)(void *p_base, const void **p_args, void *r_ret, int p_argcount);
565
566 static bool has_builtin_method(Variant::Type p_type, const StringName &p_method);
567
568 static ValidatedBuiltInMethod get_validated_builtin_method(Variant::Type p_type, const StringName &p_method);
569 static PTRBuiltInMethod get_ptr_builtin_method(Variant::Type p_type, const StringName &p_method);
570
571 static int get_builtin_method_argument_count(Variant::Type p_type, const StringName &p_method);
572 static Variant::Type get_builtin_method_argument_type(Variant::Type p_type, const StringName &p_method, int p_argument);
573 static String get_builtin_method_argument_name(Variant::Type p_type, const StringName &p_method, int p_argument);
574 static Vector<Variant> get_builtin_method_default_arguments(Variant::Type p_type, const StringName &p_method);
575 static bool has_builtin_method_return_value(Variant::Type p_type, const StringName &p_method);
576 static Variant::Type get_builtin_method_return_type(Variant::Type p_type, const StringName &p_method);
577 static bool is_builtin_method_const(Variant::Type p_type, const StringName &p_method);
578 static bool is_builtin_method_static(Variant::Type p_type, const StringName &p_method);
579 static bool is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method);
580 static void get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list);
581 static int get_builtin_method_count(Variant::Type p_type);
582 static uint32_t get_builtin_method_hash(Variant::Type p_type, const StringName &p_method);
583
584 void callp(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
585
586 template <typename... VarArgs>
587 Variant call(const StringName &p_method, VarArgs... p_args) {
588 Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
589 const Variant *argptrs[sizeof...(p_args) + 1];
590 for (uint32_t i = 0; i < sizeof...(p_args); i++) {
591 argptrs[i] = &args[i];
592 }
593 Callable::CallError cerr;
594 Variant ret;
595 callp(p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), ret, cerr);
596 if (cerr.error != Callable::CallError::CALL_OK) {
597 _variant_call_error(p_method, cerr);
598 }
599 return ret;
600 }
601
602 void call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
603 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);
604
605 static String get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
606 static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
607 static String get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
608
609 //dynamic (includes Object)
610 void get_method_list(List<MethodInfo> *p_list) const;
611 bool has_method(const StringName &p_method) const;
612
613 /* Constructors */
614
615 typedef void (*ValidatedConstructor)(Variant *r_base, const Variant **p_args);
616 typedef void (*PTRConstructor)(void *base, const void **p_args);
617
618 static int get_constructor_count(Variant::Type p_type);
619 static ValidatedConstructor get_validated_constructor(Variant::Type p_type, int p_constructor);
620 static PTRConstructor get_ptr_constructor(Variant::Type p_type, int p_constructor);
621 static int get_constructor_argument_count(Variant::Type p_type, int p_constructor);
622 static Variant::Type get_constructor_argument_type(Variant::Type p_type, int p_constructor, int p_argument);
623 static String get_constructor_argument_name(Variant::Type p_type, int p_constructor, int p_argument);
624 static void construct(Variant::Type, Variant &base, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
625
626 static void get_constructor_list(Type p_type, List<MethodInfo> *r_list); //convenience
627
628 /* Destructors */
629
630 // Only ptrcall is available.
631 typedef void (*PTRDestructor)(void *base);
632
633 static PTRDestructor get_ptr_destructor(Variant::Type p_type);
634 static bool has_destructor(Variant::Type p_type);
635
636 /* Properties */
637
638 void set_named(const StringName &p_member, const Variant &p_value, bool &r_valid);
639 Variant get_named(const StringName &p_member, bool &r_valid) const;
640
641 typedef void (*ValidatedSetter)(Variant *base, const Variant *value);
642 typedef void (*ValidatedGetter)(const Variant *base, Variant *value);
643
644 static bool has_member(Variant::Type p_type, const StringName &p_member);
645 static Variant::Type get_member_type(Variant::Type p_type, const StringName &p_member);
646 static void get_member_list(Type p_type, List<StringName> *r_members);
647 static int get_member_count(Type p_type);
648
649 static ValidatedSetter get_member_validated_setter(Variant::Type p_type, const StringName &p_member);
650 static ValidatedGetter get_member_validated_getter(Variant::Type p_type, const StringName &p_member);
651
652 typedef void (*PTRSetter)(void *base, const void *value);
653 typedef void (*PTRGetter)(const void *base, void *value);
654
655 static PTRSetter get_member_ptr_setter(Variant::Type p_type, const StringName &p_member);
656 static PTRGetter get_member_ptr_getter(Variant::Type p_type, const StringName &p_member);
657
658 /* Indexing */
659
660 static bool has_indexing(Variant::Type p_type);
661 static Variant::Type get_indexed_element_type(Variant::Type p_type);
662 static uint32_t get_indexed_element_usage(Variant::Type p_type);
663
664 typedef void (*ValidatedIndexedSetter)(Variant *base, int64_t index, const Variant *value, bool *oob);
665 typedef void (*ValidatedIndexedGetter)(const Variant *base, int64_t index, Variant *value, bool *oob);
666
667 static ValidatedIndexedSetter get_member_validated_indexed_setter(Variant::Type p_type);
668 static ValidatedIndexedGetter get_member_validated_indexed_getter(Variant::Type p_type);
669
670 typedef void (*PTRIndexedSetter)(void *base, int64_t index, const void *value);
671 typedef void (*PTRIndexedGetter)(const void *base, int64_t index, void *value);
672
673 static PTRIndexedSetter get_member_ptr_indexed_setter(Variant::Type p_type);
674 static PTRIndexedGetter get_member_ptr_indexed_getter(Variant::Type p_type);
675
676 void set_indexed(int64_t p_index, const Variant &p_value, bool &r_valid, bool &r_oob);
677 Variant get_indexed(int64_t p_index, bool &r_valid, bool &r_oob) const;
678
679 uint64_t get_indexed_size() const;
680
681 /* Keying */
682
683 static bool is_keyed(Variant::Type p_type);
684
685 typedef void (*ValidatedKeyedSetter)(Variant *base, const Variant *key, const Variant *value, bool *valid);
686 typedef void (*ValidatedKeyedGetter)(const Variant *base, const Variant *key, Variant *value, bool *valid);
687 typedef bool (*ValidatedKeyedChecker)(const Variant *base, const Variant *key, bool *valid);
688
689 static ValidatedKeyedSetter get_member_validated_keyed_setter(Variant::Type p_type);
690 static ValidatedKeyedGetter get_member_validated_keyed_getter(Variant::Type p_type);
691 static ValidatedKeyedChecker get_member_validated_keyed_checker(Variant::Type p_type);
692
693 typedef void (*PTRKeyedSetter)(void *base, const void *key, const void *value);
694 typedef void (*PTRKeyedGetter)(const void *base, const void *key, void *value);
695 typedef uint32_t (*PTRKeyedChecker)(const void *base, const void *key);
696
697 static PTRKeyedSetter get_member_ptr_keyed_setter(Variant::Type p_type);
698 static PTRKeyedGetter get_member_ptr_keyed_getter(Variant::Type p_type);
699 static PTRKeyedChecker get_member_ptr_keyed_checker(Variant::Type p_type);
700
701 void set_keyed(const Variant &p_key, const Variant &p_value, bool &r_valid);
702 Variant get_keyed(const Variant &p_key, bool &r_valid) const;
703 bool has_key(const Variant &p_key, bool &r_valid) const;
704
705 /* Generic */
706
707 void set(const Variant &p_index, const Variant &p_value, bool *r_valid = nullptr);
708 Variant get(const Variant &p_index, bool *r_valid = nullptr) const;
709 bool in(const Variant &p_index, bool *r_valid = nullptr) const;
710
711 bool iter_init(Variant &r_iter, bool &r_valid) const;
712 bool iter_next(Variant &r_iter, bool &r_valid) const;
713 Variant iter_get(const Variant &r_iter, bool &r_valid) const;
714
715 void get_property_list(List<PropertyInfo> *p_list) const;
716
717 static void call_utility_function(const StringName &p_name, Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
718 static bool has_utility_function(const StringName &p_name);
719
720 typedef void (*ValidatedUtilityFunction)(Variant *r_ret, const Variant **p_args, int p_argcount);
721 typedef void (*PTRUtilityFunction)(void *r_ret, const void **p_args, int p_argcount);
722
723 static ValidatedUtilityFunction get_validated_utility_function(const StringName &p_name);
724 static PTRUtilityFunction get_ptr_utility_function(const StringName &p_name);
725
726 enum UtilityFunctionType {
727 UTILITY_FUNC_TYPE_MATH,
728 UTILITY_FUNC_TYPE_RANDOM,
729 UTILITY_FUNC_TYPE_GENERAL,
730 };
731
732 static UtilityFunctionType get_utility_function_type(const StringName &p_name);
733
734 static MethodInfo get_utility_function_info(const StringName &p_name);
735 static int get_utility_function_argument_count(const StringName &p_name);
736 static Variant::Type get_utility_function_argument_type(const StringName &p_name, int p_arg);
737 static String get_utility_function_argument_name(const StringName &p_name, int p_arg);
738 static bool has_utility_function_return_value(const StringName &p_name);
739 static Variant::Type get_utility_function_return_type(const StringName &p_name);
740 static bool is_utility_function_vararg(const StringName &p_name);
741 static uint32_t get_utility_function_hash(const StringName &p_name);
742
743 static void get_utility_function_list(List<StringName> *r_functions);
744 static int get_utility_function_count();
745
746 //argsVariant call()
747
748 bool operator==(const Variant &p_variant) const;
749 bool operator!=(const Variant &p_variant) const;
750 bool operator<(const Variant &p_variant) const;
751 uint32_t hash() const;
752 uint32_t recursive_hash(int recursion_count) const;
753
754 bool hash_compare(const Variant &p_variant, int recursion_count = 0) const;
755 bool identity_compare(const Variant &p_variant) const;
756 bool booleanize() const;
757 String stringify(int recursion_count = 0) const;
758 String to_json_string() const;
759
760 void static_assign(const Variant &p_variant);
761 static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants);
762 static int get_constants_count_for_type(Variant::Type p_type);
763 static bool has_constant(Variant::Type p_type, const StringName &p_value);
764 static Variant get_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid = nullptr);
765
766 static void get_enums_for_type(Variant::Type p_type, List<StringName> *p_enums);
767 static void get_enumerations_for_enum(Variant::Type p_type, StringName p_enum_name, List<StringName> *p_enumerations);
768 static int get_enum_value(Variant::Type p_type, StringName p_enum_name, StringName p_enumeration, bool *r_valid = nullptr);
769
770 typedef String (*ObjectDeConstruct)(const Variant &p_object, void *ud);
771 typedef void (*ObjectConstruct)(const String &p_text, void *ud, Variant &r_value);
772
773 String get_construct_string() const;
774 static void construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct = nullptr, void *p_construct_ud = nullptr);
775
776 void operator=(const Variant &p_variant); // only this is enough for all the other types
777
778 static void register_types();
779 static void unregister_types();
780
781 Variant(const Variant &p_variant);
782 _FORCE_INLINE_ Variant() {}
783 _FORCE_INLINE_ ~Variant() {
784 clear();
785 }
786};
787
788//typedef Dictionary Dictionary; no
789//typedef Array Array;
790
791Vector<Variant> varray();
792Vector<Variant> varray(const Variant &p_arg1);
793Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2);
794Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3);
795Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4);
796Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5);
797
798struct VariantHasher {
799 static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
800};
801
802struct VariantComparator {
803 static _FORCE_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) { return p_lhs.hash_compare(p_rhs); }
804};
805
806struct StringLikeVariantComparator {
807 static bool compare(const Variant &p_lhs, const Variant &p_rhs);
808};
809
810Variant::ObjData &Variant::_get_obj() {
811 return *reinterpret_cast<ObjData *>(&_data._mem[0]);
812}
813
814const Variant::ObjData &Variant::_get_obj() const {
815 return *reinterpret_cast<const ObjData *>(&_data._mem[0]);
816}
817
818template <typename... VarArgs>
819String vformat(const String &p_text, const VarArgs... p_args) {
820 Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
821 Array args_array;
822 args_array.resize(sizeof...(p_args));
823 for (uint32_t i = 0; i < sizeof...(p_args); i++) {
824 args_array[i] = args[i];
825 }
826
827 bool error = false;
828 String fmt = p_text.sprintf(args_array, &error);
829
830 ERR_FAIL_COND_V_MSG(error, String(), fmt);
831
832 return fmt;
833}
834
835template <typename... VarArgs>
836Callable Callable::bind(VarArgs... p_args) {
837 Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
838 const Variant *argptrs[sizeof...(p_args) + 1];
839 for (uint32_t i = 0; i < sizeof...(p_args); i++) {
840 argptrs[i] = &args[i];
841 }
842 return bindp(sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
843}
844
845#endif // VARIANT_H
846