| 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 | |