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 | |
63 | class Object; |
64 | |
65 | struct PropertyInfo; |
66 | struct MethodInfo; |
67 | |
68 | typedef Vector<uint8_t> PackedByteArray; |
69 | typedef Vector<int32_t> PackedInt32Array; |
70 | typedef Vector<int64_t> PackedInt64Array; |
71 | typedef Vector<float> PackedFloat32Array; |
72 | typedef Vector<double> PackedFloat64Array; |
73 | typedef Vector<String> PackedStringArray; |
74 | typedef Vector<Vector2> PackedVector2Array; |
75 | typedef Vector<Vector3> PackedVector3Array; |
76 | typedef Vector<Color> PackedColorArray; |
77 | |
78 | class Variant { |
79 | public: |
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 | |
137 | private: |
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 | |
328 | public: |
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 | |
791 | Vector<Variant> varray(); |
792 | Vector<Variant> varray(const Variant &p_arg1); |
793 | Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2); |
794 | Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3); |
795 | Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4); |
796 | Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5); |
797 | |
798 | struct VariantHasher { |
799 | static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); } |
800 | }; |
801 | |
802 | struct VariantComparator { |
803 | static _FORCE_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) { return p_lhs.hash_compare(p_rhs); } |
804 | }; |
805 | |
806 | struct StringLikeVariantComparator { |
807 | static bool compare(const Variant &p_lhs, const Variant &p_rhs); |
808 | }; |
809 | |
810 | Variant::ObjData &Variant::_get_obj() { |
811 | return *reinterpret_cast<ObjData *>(&_data._mem[0]); |
812 | } |
813 | |
814 | const Variant::ObjData &Variant::_get_obj() const { |
815 | return *reinterpret_cast<const ObjData *>(&_data._mem[0]); |
816 | } |
817 | |
818 | template <typename... VarArgs> |
819 | String 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 | |
835 | template <typename... VarArgs> |
836 | Callable 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 | |