1 | /**************************************************************************/ |
2 | /* variant.cpp */ |
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 | #include "variant.h" |
32 | |
33 | #include "core/core_string_names.h" |
34 | #include "core/debugger/engine_debugger.h" |
35 | #include "core/io/json.h" |
36 | #include "core/io/marshalls.h" |
37 | #include "core/io/resource.h" |
38 | #include "core/math/math_funcs.h" |
39 | #include "core/string/print_string.h" |
40 | #include "core/variant/variant_parser.h" |
41 | |
42 | PagedAllocator<Variant::Pools::BucketSmall, true> Variant::Pools::_bucket_small; |
43 | PagedAllocator<Variant::Pools::BucketMedium, true> Variant::Pools::_bucket_medium; |
44 | PagedAllocator<Variant::Pools::BucketLarge, true> Variant::Pools::_bucket_large; |
45 | |
46 | String Variant::get_type_name(Variant::Type p_type) { |
47 | switch (p_type) { |
48 | case NIL: { |
49 | return "Nil" ; |
50 | } |
51 | |
52 | // Atomic types. |
53 | case BOOL: { |
54 | return "bool" ; |
55 | } |
56 | case INT: { |
57 | return "int" ; |
58 | } |
59 | case FLOAT: { |
60 | return "float" ; |
61 | } |
62 | case STRING: { |
63 | return "String" ; |
64 | } |
65 | |
66 | // Math types. |
67 | case VECTOR2: { |
68 | return "Vector2" ; |
69 | } |
70 | case VECTOR2I: { |
71 | return "Vector2i" ; |
72 | } |
73 | case RECT2: { |
74 | return "Rect2" ; |
75 | } |
76 | case RECT2I: { |
77 | return "Rect2i" ; |
78 | } |
79 | case TRANSFORM2D: { |
80 | return "Transform2D" ; |
81 | } |
82 | case VECTOR3: { |
83 | return "Vector3" ; |
84 | } |
85 | case VECTOR3I: { |
86 | return "Vector3i" ; |
87 | } |
88 | case VECTOR4: { |
89 | return "Vector4" ; |
90 | } |
91 | case VECTOR4I: { |
92 | return "Vector4i" ; |
93 | } |
94 | case PLANE: { |
95 | return "Plane" ; |
96 | } |
97 | case AABB: { |
98 | return "AABB" ; |
99 | } |
100 | case QUATERNION: { |
101 | return "Quaternion" ; |
102 | } |
103 | case BASIS: { |
104 | return "Basis" ; |
105 | } |
106 | case TRANSFORM3D: { |
107 | return "Transform3D" ; |
108 | } |
109 | case PROJECTION: { |
110 | return "Projection" ; |
111 | } |
112 | |
113 | // Miscellaneous types. |
114 | case COLOR: { |
115 | return "Color" ; |
116 | } |
117 | case RID: { |
118 | return "RID" ; |
119 | } |
120 | case OBJECT: { |
121 | return "Object" ; |
122 | } |
123 | case CALLABLE: { |
124 | return "Callable" ; |
125 | } |
126 | case SIGNAL: { |
127 | return "Signal" ; |
128 | } |
129 | case STRING_NAME: { |
130 | return "StringName" ; |
131 | } |
132 | case NODE_PATH: { |
133 | return "NodePath" ; |
134 | } |
135 | case DICTIONARY: { |
136 | return "Dictionary" ; |
137 | } |
138 | case ARRAY: { |
139 | return "Array" ; |
140 | } |
141 | |
142 | // Arrays. |
143 | case PACKED_BYTE_ARRAY: { |
144 | return "PackedByteArray" ; |
145 | } |
146 | case PACKED_INT32_ARRAY: { |
147 | return "PackedInt32Array" ; |
148 | } |
149 | case PACKED_INT64_ARRAY: { |
150 | return "PackedInt64Array" ; |
151 | } |
152 | case PACKED_FLOAT32_ARRAY: { |
153 | return "PackedFloat32Array" ; |
154 | } |
155 | case PACKED_FLOAT64_ARRAY: { |
156 | return "PackedFloat64Array" ; |
157 | } |
158 | case PACKED_STRING_ARRAY: { |
159 | return "PackedStringArray" ; |
160 | } |
161 | case PACKED_VECTOR2_ARRAY: { |
162 | return "PackedVector2Array" ; |
163 | } |
164 | case PACKED_VECTOR3_ARRAY: { |
165 | return "PackedVector3Array" ; |
166 | } |
167 | case PACKED_COLOR_ARRAY: { |
168 | return "PackedColorArray" ; |
169 | } |
170 | default: { |
171 | } |
172 | } |
173 | |
174 | return "" ; |
175 | } |
176 | |
177 | bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { |
178 | if (p_type_from == p_type_to) { |
179 | return true; |
180 | } |
181 | if (p_type_to == NIL) { //nil can convert to anything |
182 | return true; |
183 | } |
184 | |
185 | if (p_type_from == NIL) { |
186 | return (p_type_to == OBJECT); |
187 | } |
188 | |
189 | const Type *valid_types = nullptr; |
190 | const Type *invalid_types = nullptr; |
191 | |
192 | switch (p_type_to) { |
193 | case BOOL: { |
194 | static const Type valid[] = { |
195 | INT, |
196 | FLOAT, |
197 | STRING, |
198 | NIL, |
199 | }; |
200 | |
201 | valid_types = valid; |
202 | } break; |
203 | case INT: { |
204 | static const Type valid[] = { |
205 | BOOL, |
206 | FLOAT, |
207 | STRING, |
208 | NIL, |
209 | }; |
210 | |
211 | valid_types = valid; |
212 | |
213 | } break; |
214 | case FLOAT: { |
215 | static const Type valid[] = { |
216 | BOOL, |
217 | INT, |
218 | STRING, |
219 | NIL, |
220 | }; |
221 | |
222 | valid_types = valid; |
223 | |
224 | } break; |
225 | case STRING: { |
226 | static const Type invalid[] = { |
227 | OBJECT, |
228 | NIL |
229 | }; |
230 | |
231 | invalid_types = invalid; |
232 | } break; |
233 | case VECTOR2: { |
234 | static const Type valid[] = { |
235 | VECTOR2I, |
236 | NIL, |
237 | }; |
238 | |
239 | valid_types = valid; |
240 | |
241 | } break; |
242 | case VECTOR2I: { |
243 | static const Type valid[] = { |
244 | VECTOR2, |
245 | NIL, |
246 | }; |
247 | |
248 | valid_types = valid; |
249 | |
250 | } break; |
251 | case RECT2: { |
252 | static const Type valid[] = { |
253 | RECT2I, |
254 | NIL, |
255 | }; |
256 | |
257 | valid_types = valid; |
258 | |
259 | } break; |
260 | case RECT2I: { |
261 | static const Type valid[] = { |
262 | RECT2, |
263 | NIL, |
264 | }; |
265 | |
266 | valid_types = valid; |
267 | |
268 | } break; |
269 | case TRANSFORM2D: { |
270 | static const Type valid[] = { |
271 | TRANSFORM3D, |
272 | NIL |
273 | }; |
274 | |
275 | valid_types = valid; |
276 | } break; |
277 | case VECTOR3: { |
278 | static const Type valid[] = { |
279 | VECTOR3I, |
280 | NIL, |
281 | }; |
282 | |
283 | valid_types = valid; |
284 | |
285 | } break; |
286 | case VECTOR3I: { |
287 | static const Type valid[] = { |
288 | VECTOR3, |
289 | NIL, |
290 | }; |
291 | |
292 | valid_types = valid; |
293 | |
294 | } break; |
295 | case VECTOR4: { |
296 | static const Type valid[] = { |
297 | VECTOR4I, |
298 | NIL, |
299 | }; |
300 | |
301 | valid_types = valid; |
302 | |
303 | } break; |
304 | case VECTOR4I: { |
305 | static const Type valid[] = { |
306 | VECTOR4, |
307 | NIL, |
308 | }; |
309 | |
310 | valid_types = valid; |
311 | |
312 | } break; |
313 | |
314 | case QUATERNION: { |
315 | static const Type valid[] = { |
316 | BASIS, |
317 | NIL |
318 | }; |
319 | |
320 | valid_types = valid; |
321 | |
322 | } break; |
323 | case BASIS: { |
324 | static const Type valid[] = { |
325 | QUATERNION, |
326 | NIL |
327 | }; |
328 | |
329 | valid_types = valid; |
330 | |
331 | } break; |
332 | case TRANSFORM3D: { |
333 | static const Type valid[] = { |
334 | TRANSFORM2D, |
335 | QUATERNION, |
336 | BASIS, |
337 | PROJECTION, |
338 | NIL |
339 | }; |
340 | |
341 | valid_types = valid; |
342 | |
343 | } break; |
344 | case PROJECTION: { |
345 | static const Type valid[] = { |
346 | TRANSFORM3D, |
347 | NIL |
348 | }; |
349 | |
350 | valid_types = valid; |
351 | |
352 | } break; |
353 | |
354 | case COLOR: { |
355 | static const Type valid[] = { |
356 | STRING, |
357 | INT, |
358 | NIL, |
359 | }; |
360 | |
361 | valid_types = valid; |
362 | |
363 | } break; |
364 | |
365 | case RID: { |
366 | static const Type valid[] = { |
367 | OBJECT, |
368 | NIL |
369 | }; |
370 | |
371 | valid_types = valid; |
372 | } break; |
373 | case OBJECT: { |
374 | static const Type valid[] = { |
375 | NIL |
376 | }; |
377 | |
378 | valid_types = valid; |
379 | } break; |
380 | case STRING_NAME: { |
381 | static const Type valid[] = { |
382 | STRING, |
383 | NIL |
384 | }; |
385 | |
386 | valid_types = valid; |
387 | } break; |
388 | case NODE_PATH: { |
389 | static const Type valid[] = { |
390 | STRING, |
391 | NIL |
392 | }; |
393 | |
394 | valid_types = valid; |
395 | } break; |
396 | case ARRAY: { |
397 | static const Type valid[] = { |
398 | PACKED_BYTE_ARRAY, |
399 | PACKED_INT32_ARRAY, |
400 | PACKED_INT64_ARRAY, |
401 | PACKED_FLOAT32_ARRAY, |
402 | PACKED_FLOAT64_ARRAY, |
403 | PACKED_STRING_ARRAY, |
404 | PACKED_COLOR_ARRAY, |
405 | PACKED_VECTOR2_ARRAY, |
406 | PACKED_VECTOR3_ARRAY, |
407 | NIL |
408 | }; |
409 | |
410 | valid_types = valid; |
411 | } break; |
412 | // arrays |
413 | case PACKED_BYTE_ARRAY: { |
414 | static const Type valid[] = { |
415 | ARRAY, |
416 | NIL |
417 | }; |
418 | |
419 | valid_types = valid; |
420 | } break; |
421 | case PACKED_INT32_ARRAY: { |
422 | static const Type valid[] = { |
423 | ARRAY, |
424 | NIL |
425 | }; |
426 | valid_types = valid; |
427 | } break; |
428 | case PACKED_INT64_ARRAY: { |
429 | static const Type valid[] = { |
430 | ARRAY, |
431 | NIL |
432 | }; |
433 | valid_types = valid; |
434 | } break; |
435 | case PACKED_FLOAT32_ARRAY: { |
436 | static const Type valid[] = { |
437 | ARRAY, |
438 | NIL |
439 | }; |
440 | |
441 | valid_types = valid; |
442 | } break; |
443 | case PACKED_FLOAT64_ARRAY: { |
444 | static const Type valid[] = { |
445 | ARRAY, |
446 | NIL |
447 | }; |
448 | |
449 | valid_types = valid; |
450 | } break; |
451 | case PACKED_STRING_ARRAY: { |
452 | static const Type valid[] = { |
453 | ARRAY, |
454 | NIL |
455 | }; |
456 | valid_types = valid; |
457 | } break; |
458 | case PACKED_VECTOR2_ARRAY: { |
459 | static const Type valid[] = { |
460 | ARRAY, |
461 | NIL |
462 | }; |
463 | valid_types = valid; |
464 | |
465 | } break; |
466 | case PACKED_VECTOR3_ARRAY: { |
467 | static const Type valid[] = { |
468 | ARRAY, |
469 | NIL |
470 | }; |
471 | valid_types = valid; |
472 | |
473 | } break; |
474 | case PACKED_COLOR_ARRAY: { |
475 | static const Type valid[] = { |
476 | ARRAY, |
477 | NIL |
478 | }; |
479 | |
480 | valid_types = valid; |
481 | |
482 | } break; |
483 | default: { |
484 | } |
485 | } |
486 | |
487 | if (valid_types) { |
488 | int i = 0; |
489 | while (valid_types[i] != NIL) { |
490 | if (p_type_from == valid_types[i]) { |
491 | return true; |
492 | } |
493 | i++; |
494 | } |
495 | |
496 | } else if (invalid_types) { |
497 | int i = 0; |
498 | while (invalid_types[i] != NIL) { |
499 | if (p_type_from == invalid_types[i]) { |
500 | return false; |
501 | } |
502 | i++; |
503 | } |
504 | |
505 | return true; |
506 | } |
507 | |
508 | return false; |
509 | } |
510 | |
511 | bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type_to) { |
512 | if (p_type_from == p_type_to) { |
513 | return true; |
514 | } |
515 | if (p_type_to == NIL) { //nil can convert to anything |
516 | return true; |
517 | } |
518 | |
519 | if (p_type_from == NIL) { |
520 | return (p_type_to == OBJECT); |
521 | } |
522 | |
523 | const Type *valid_types = nullptr; |
524 | |
525 | switch (p_type_to) { |
526 | case BOOL: { |
527 | static const Type valid[] = { |
528 | INT, |
529 | FLOAT, |
530 | //STRING, |
531 | NIL, |
532 | }; |
533 | |
534 | valid_types = valid; |
535 | } break; |
536 | case INT: { |
537 | static const Type valid[] = { |
538 | BOOL, |
539 | FLOAT, |
540 | //STRING, |
541 | NIL, |
542 | }; |
543 | |
544 | valid_types = valid; |
545 | |
546 | } break; |
547 | case FLOAT: { |
548 | static const Type valid[] = { |
549 | BOOL, |
550 | INT, |
551 | //STRING, |
552 | NIL, |
553 | }; |
554 | |
555 | valid_types = valid; |
556 | |
557 | } break; |
558 | case STRING: { |
559 | static const Type valid[] = { |
560 | NODE_PATH, |
561 | STRING_NAME, |
562 | NIL |
563 | }; |
564 | |
565 | valid_types = valid; |
566 | } break; |
567 | case VECTOR2: { |
568 | static const Type valid[] = { |
569 | VECTOR2I, |
570 | NIL, |
571 | }; |
572 | |
573 | valid_types = valid; |
574 | |
575 | } break; |
576 | case VECTOR2I: { |
577 | static const Type valid[] = { |
578 | VECTOR2, |
579 | NIL, |
580 | }; |
581 | |
582 | valid_types = valid; |
583 | |
584 | } break; |
585 | case RECT2: { |
586 | static const Type valid[] = { |
587 | RECT2I, |
588 | NIL, |
589 | }; |
590 | |
591 | valid_types = valid; |
592 | |
593 | } break; |
594 | case RECT2I: { |
595 | static const Type valid[] = { |
596 | RECT2, |
597 | NIL, |
598 | }; |
599 | |
600 | valid_types = valid; |
601 | |
602 | } break; |
603 | case TRANSFORM2D: { |
604 | static const Type valid[] = { |
605 | TRANSFORM3D, |
606 | NIL |
607 | }; |
608 | |
609 | valid_types = valid; |
610 | } break; |
611 | case VECTOR3: { |
612 | static const Type valid[] = { |
613 | VECTOR3I, |
614 | NIL, |
615 | }; |
616 | |
617 | valid_types = valid; |
618 | |
619 | } break; |
620 | case VECTOR3I: { |
621 | static const Type valid[] = { |
622 | VECTOR3, |
623 | NIL, |
624 | }; |
625 | |
626 | valid_types = valid; |
627 | |
628 | } break; |
629 | case VECTOR4: { |
630 | static const Type valid[] = { |
631 | VECTOR4I, |
632 | NIL, |
633 | }; |
634 | |
635 | valid_types = valid; |
636 | |
637 | } break; |
638 | case VECTOR4I: { |
639 | static const Type valid[] = { |
640 | VECTOR4, |
641 | NIL, |
642 | }; |
643 | |
644 | valid_types = valid; |
645 | |
646 | } break; |
647 | |
648 | case QUATERNION: { |
649 | static const Type valid[] = { |
650 | BASIS, |
651 | NIL |
652 | }; |
653 | |
654 | valid_types = valid; |
655 | |
656 | } break; |
657 | case BASIS: { |
658 | static const Type valid[] = { |
659 | QUATERNION, |
660 | NIL |
661 | }; |
662 | |
663 | valid_types = valid; |
664 | |
665 | } break; |
666 | case TRANSFORM3D: { |
667 | static const Type valid[] = { |
668 | TRANSFORM2D, |
669 | QUATERNION, |
670 | BASIS, |
671 | PROJECTION, |
672 | NIL |
673 | }; |
674 | |
675 | valid_types = valid; |
676 | |
677 | } break; |
678 | case PROJECTION: { |
679 | static const Type valid[] = { |
680 | TRANSFORM3D, |
681 | NIL |
682 | }; |
683 | |
684 | valid_types = valid; |
685 | |
686 | } break; |
687 | |
688 | case COLOR: { |
689 | static const Type valid[] = { |
690 | STRING, |
691 | INT, |
692 | NIL, |
693 | }; |
694 | |
695 | valid_types = valid; |
696 | |
697 | } break; |
698 | |
699 | case RID: { |
700 | static const Type valid[] = { |
701 | OBJECT, |
702 | NIL |
703 | }; |
704 | |
705 | valid_types = valid; |
706 | } break; |
707 | case OBJECT: { |
708 | static const Type valid[] = { |
709 | NIL |
710 | }; |
711 | |
712 | valid_types = valid; |
713 | } break; |
714 | case STRING_NAME: { |
715 | static const Type valid[] = { |
716 | STRING, |
717 | NIL |
718 | }; |
719 | |
720 | valid_types = valid; |
721 | } break; |
722 | case NODE_PATH: { |
723 | static const Type valid[] = { |
724 | STRING, |
725 | NIL |
726 | }; |
727 | |
728 | valid_types = valid; |
729 | } break; |
730 | case ARRAY: { |
731 | static const Type valid[] = { |
732 | PACKED_BYTE_ARRAY, |
733 | PACKED_INT32_ARRAY, |
734 | PACKED_INT64_ARRAY, |
735 | PACKED_FLOAT32_ARRAY, |
736 | PACKED_FLOAT64_ARRAY, |
737 | PACKED_STRING_ARRAY, |
738 | PACKED_COLOR_ARRAY, |
739 | PACKED_VECTOR2_ARRAY, |
740 | PACKED_VECTOR3_ARRAY, |
741 | NIL |
742 | }; |
743 | |
744 | valid_types = valid; |
745 | } break; |
746 | // arrays |
747 | case PACKED_BYTE_ARRAY: { |
748 | static const Type valid[] = { |
749 | ARRAY, |
750 | NIL |
751 | }; |
752 | |
753 | valid_types = valid; |
754 | } break; |
755 | case PACKED_INT32_ARRAY: { |
756 | static const Type valid[] = { |
757 | ARRAY, |
758 | NIL |
759 | }; |
760 | valid_types = valid; |
761 | } break; |
762 | case PACKED_INT64_ARRAY: { |
763 | static const Type valid[] = { |
764 | ARRAY, |
765 | NIL |
766 | }; |
767 | valid_types = valid; |
768 | } break; |
769 | case PACKED_FLOAT32_ARRAY: { |
770 | static const Type valid[] = { |
771 | ARRAY, |
772 | NIL |
773 | }; |
774 | |
775 | valid_types = valid; |
776 | } break; |
777 | case PACKED_FLOAT64_ARRAY: { |
778 | static const Type valid[] = { |
779 | ARRAY, |
780 | NIL |
781 | }; |
782 | |
783 | valid_types = valid; |
784 | } break; |
785 | case PACKED_STRING_ARRAY: { |
786 | static const Type valid[] = { |
787 | ARRAY, |
788 | NIL |
789 | }; |
790 | valid_types = valid; |
791 | } break; |
792 | case PACKED_VECTOR2_ARRAY: { |
793 | static const Type valid[] = { |
794 | ARRAY, |
795 | NIL |
796 | }; |
797 | valid_types = valid; |
798 | |
799 | } break; |
800 | case PACKED_VECTOR3_ARRAY: { |
801 | static const Type valid[] = { |
802 | ARRAY, |
803 | NIL |
804 | }; |
805 | valid_types = valid; |
806 | |
807 | } break; |
808 | case PACKED_COLOR_ARRAY: { |
809 | static const Type valid[] = { |
810 | ARRAY, |
811 | NIL |
812 | }; |
813 | |
814 | valid_types = valid; |
815 | |
816 | } break; |
817 | default: { |
818 | } |
819 | } |
820 | |
821 | if (valid_types) { |
822 | int i = 0; |
823 | while (valid_types[i] != NIL) { |
824 | if (p_type_from == valid_types[i]) { |
825 | return true; |
826 | } |
827 | i++; |
828 | } |
829 | } |
830 | |
831 | return false; |
832 | } |
833 | |
834 | bool Variant::operator==(const Variant &p_variant) const { |
835 | return hash_compare(p_variant); |
836 | } |
837 | |
838 | bool Variant::operator!=(const Variant &p_variant) const { |
839 | // Don't use `!hash_compare(p_variant)` given it makes use of OP_EQUAL |
840 | if (type != p_variant.type) { //evaluation of operator== needs to be more strict |
841 | return true; |
842 | } |
843 | bool v; |
844 | Variant r; |
845 | evaluate(OP_NOT_EQUAL, *this, p_variant, r, v); |
846 | return r; |
847 | } |
848 | |
849 | bool Variant::operator<(const Variant &p_variant) const { |
850 | if (type != p_variant.type) { //if types differ, then order by type first |
851 | return type < p_variant.type; |
852 | } |
853 | bool v; |
854 | Variant r; |
855 | evaluate(OP_LESS, *this, p_variant, r, v); |
856 | return r; |
857 | } |
858 | |
859 | bool Variant::is_zero() const { |
860 | switch (type) { |
861 | case NIL: { |
862 | return true; |
863 | } |
864 | |
865 | // Atomic types. |
866 | case BOOL: { |
867 | return !(_data._bool); |
868 | } |
869 | case INT: { |
870 | return _data._int == 0; |
871 | } |
872 | case FLOAT: { |
873 | return _data._float == 0; |
874 | } |
875 | case STRING: { |
876 | return *reinterpret_cast<const String *>(_data._mem) == String(); |
877 | } |
878 | |
879 | // Math types. |
880 | case VECTOR2: { |
881 | return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2(); |
882 | } |
883 | case VECTOR2I: { |
884 | return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i(); |
885 | } |
886 | case RECT2: { |
887 | return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2(); |
888 | } |
889 | case RECT2I: { |
890 | return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i(); |
891 | } |
892 | case TRANSFORM2D: { |
893 | return *_data._transform2d == Transform2D(); |
894 | } |
895 | case VECTOR3: { |
896 | return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3(); |
897 | } |
898 | case VECTOR3I: { |
899 | return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(); |
900 | } |
901 | case VECTOR4: { |
902 | return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(); |
903 | } |
904 | case VECTOR4I: { |
905 | return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(); |
906 | } |
907 | case PLANE: { |
908 | return *reinterpret_cast<const Plane *>(_data._mem) == Plane(); |
909 | } |
910 | case AABB: { |
911 | return *_data._aabb == ::AABB(); |
912 | } |
913 | case QUATERNION: { |
914 | return *reinterpret_cast<const Quaternion *>(_data._mem) == Quaternion(); |
915 | } |
916 | case BASIS: { |
917 | return *_data._basis == Basis(); |
918 | } |
919 | case TRANSFORM3D: { |
920 | return *_data._transform3d == Transform3D(); |
921 | } |
922 | case PROJECTION: { |
923 | return *_data._projection == Projection(); |
924 | } |
925 | |
926 | // Miscellaneous types. |
927 | case COLOR: { |
928 | return *reinterpret_cast<const Color *>(_data._mem) == Color(); |
929 | } |
930 | case RID: { |
931 | return *reinterpret_cast<const ::RID *>(_data._mem) == ::RID(); |
932 | } |
933 | case OBJECT: { |
934 | return _get_obj().obj == nullptr; |
935 | } |
936 | case CALLABLE: { |
937 | return reinterpret_cast<const Callable *>(_data._mem)->is_null(); |
938 | } |
939 | case SIGNAL: { |
940 | return reinterpret_cast<const Signal *>(_data._mem)->is_null(); |
941 | } |
942 | case STRING_NAME: { |
943 | return *reinterpret_cast<const StringName *>(_data._mem) == StringName(); |
944 | } |
945 | case NODE_PATH: { |
946 | return reinterpret_cast<const NodePath *>(_data._mem)->is_empty(); |
947 | } |
948 | case DICTIONARY: { |
949 | return reinterpret_cast<const Dictionary *>(_data._mem)->is_empty(); |
950 | } |
951 | case ARRAY: { |
952 | return reinterpret_cast<const Array *>(_data._mem)->is_empty(); |
953 | } |
954 | |
955 | // Arrays. |
956 | case PACKED_BYTE_ARRAY: { |
957 | return PackedArrayRef<uint8_t>::get_array(_data.packed_array).size() == 0; |
958 | } |
959 | case PACKED_INT32_ARRAY: { |
960 | return PackedArrayRef<int32_t>::get_array(_data.packed_array).size() == 0; |
961 | } |
962 | case PACKED_INT64_ARRAY: { |
963 | return PackedArrayRef<int64_t>::get_array(_data.packed_array).size() == 0; |
964 | } |
965 | case PACKED_FLOAT32_ARRAY: { |
966 | return PackedArrayRef<float>::get_array(_data.packed_array).size() == 0; |
967 | } |
968 | case PACKED_FLOAT64_ARRAY: { |
969 | return PackedArrayRef<double>::get_array(_data.packed_array).size() == 0; |
970 | } |
971 | case PACKED_STRING_ARRAY: { |
972 | return PackedArrayRef<String>::get_array(_data.packed_array).size() == 0; |
973 | } |
974 | case PACKED_VECTOR2_ARRAY: { |
975 | return PackedArrayRef<Vector2>::get_array(_data.packed_array).size() == 0; |
976 | } |
977 | case PACKED_VECTOR3_ARRAY: { |
978 | return PackedArrayRef<Vector3>::get_array(_data.packed_array).size() == 0; |
979 | } |
980 | case PACKED_COLOR_ARRAY: { |
981 | return PackedArrayRef<Color>::get_array(_data.packed_array).size() == 0; |
982 | } |
983 | default: { |
984 | } |
985 | } |
986 | |
987 | return false; |
988 | } |
989 | |
990 | bool Variant::is_one() const { |
991 | switch (type) { |
992 | case NIL: { |
993 | return true; |
994 | } |
995 | |
996 | case BOOL: { |
997 | return _data._bool; |
998 | } |
999 | case INT: { |
1000 | return _data._int == 1; |
1001 | } |
1002 | case FLOAT: { |
1003 | return _data._float == 1; |
1004 | } |
1005 | |
1006 | case VECTOR2: { |
1007 | return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2(1, 1); |
1008 | } |
1009 | case VECTOR2I: { |
1010 | return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i(1, 1); |
1011 | } |
1012 | case RECT2: { |
1013 | return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2(1, 1, 1, 1); |
1014 | } |
1015 | case RECT2I: { |
1016 | return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i(1, 1, 1, 1); |
1017 | } |
1018 | case VECTOR3: { |
1019 | return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3(1, 1, 1); |
1020 | } |
1021 | case VECTOR3I: { |
1022 | return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(1, 1, 1); |
1023 | } |
1024 | case VECTOR4: { |
1025 | return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(1, 1, 1, 1); |
1026 | } |
1027 | case VECTOR4I: { |
1028 | return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(1, 1, 1, 1); |
1029 | } |
1030 | case PLANE: { |
1031 | return *reinterpret_cast<const Plane *>(_data._mem) == Plane(1, 1, 1, 1); |
1032 | } |
1033 | |
1034 | case COLOR: { |
1035 | return *reinterpret_cast<const Color *>(_data._mem) == Color(1, 1, 1, 1); |
1036 | } |
1037 | |
1038 | default: { |
1039 | return !is_zero(); |
1040 | } |
1041 | } |
1042 | } |
1043 | |
1044 | bool Variant::is_null() const { |
1045 | if (type == OBJECT && _get_obj().obj) { |
1046 | return false; |
1047 | } else { |
1048 | return true; |
1049 | } |
1050 | } |
1051 | |
1052 | bool Variant::initialize_ref(Object *p_object) { |
1053 | RefCounted *ref_counted = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_object)); |
1054 | if (!ref_counted->init_ref()) { |
1055 | return false; |
1056 | } |
1057 | return true; |
1058 | } |
1059 | void Variant::reference(const Variant &p_variant) { |
1060 | switch (type) { |
1061 | case NIL: |
1062 | case BOOL: |
1063 | case INT: |
1064 | case FLOAT: |
1065 | break; |
1066 | default: |
1067 | clear(); |
1068 | } |
1069 | |
1070 | type = p_variant.type; |
1071 | |
1072 | switch (p_variant.type) { |
1073 | case NIL: { |
1074 | // None. |
1075 | } break; |
1076 | |
1077 | // Atomic types. |
1078 | case BOOL: { |
1079 | _data._bool = p_variant._data._bool; |
1080 | } break; |
1081 | case INT: { |
1082 | _data._int = p_variant._data._int; |
1083 | } break; |
1084 | case FLOAT: { |
1085 | _data._float = p_variant._data._float; |
1086 | } break; |
1087 | case STRING: { |
1088 | memnew_placement(_data._mem, String(*reinterpret_cast<const String *>(p_variant._data._mem))); |
1089 | } break; |
1090 | |
1091 | // Math types. |
1092 | case VECTOR2: { |
1093 | memnew_placement(_data._mem, Vector2(*reinterpret_cast<const Vector2 *>(p_variant._data._mem))); |
1094 | } break; |
1095 | case VECTOR2I: { |
1096 | memnew_placement(_data._mem, Vector2i(*reinterpret_cast<const Vector2i *>(p_variant._data._mem))); |
1097 | } break; |
1098 | case RECT2: { |
1099 | memnew_placement(_data._mem, Rect2(*reinterpret_cast<const Rect2 *>(p_variant._data._mem))); |
1100 | } break; |
1101 | case RECT2I: { |
1102 | memnew_placement(_data._mem, Rect2i(*reinterpret_cast<const Rect2i *>(p_variant._data._mem))); |
1103 | } break; |
1104 | case TRANSFORM2D: { |
1105 | _data._transform2d = (Transform2D *)Pools::_bucket_small.alloc(); |
1106 | memnew_placement(_data._transform2d, Transform2D(*p_variant._data._transform2d)); |
1107 | } break; |
1108 | case VECTOR3: { |
1109 | memnew_placement(_data._mem, Vector3(*reinterpret_cast<const Vector3 *>(p_variant._data._mem))); |
1110 | } break; |
1111 | case VECTOR3I: { |
1112 | memnew_placement(_data._mem, Vector3i(*reinterpret_cast<const Vector3i *>(p_variant._data._mem))); |
1113 | } break; |
1114 | case VECTOR4: { |
1115 | memnew_placement(_data._mem, Vector4(*reinterpret_cast<const Vector4 *>(p_variant._data._mem))); |
1116 | } break; |
1117 | case VECTOR4I: { |
1118 | memnew_placement(_data._mem, Vector4i(*reinterpret_cast<const Vector4i *>(p_variant._data._mem))); |
1119 | } break; |
1120 | case PLANE: { |
1121 | memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem))); |
1122 | } break; |
1123 | case AABB: { |
1124 | _data._aabb = (::AABB *)Pools::_bucket_small.alloc(); |
1125 | memnew_placement(_data._aabb, ::AABB(*p_variant._data._aabb)); |
1126 | } break; |
1127 | case QUATERNION: { |
1128 | memnew_placement(_data._mem, Quaternion(*reinterpret_cast<const Quaternion *>(p_variant._data._mem))); |
1129 | } break; |
1130 | case BASIS: { |
1131 | _data._basis = (Basis *)Pools::_bucket_medium.alloc(); |
1132 | memnew_placement(_data._basis, Basis(*p_variant._data._basis)); |
1133 | } break; |
1134 | case TRANSFORM3D: { |
1135 | _data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc(); |
1136 | memnew_placement(_data._transform3d, Transform3D(*p_variant._data._transform3d)); |
1137 | } break; |
1138 | case PROJECTION: { |
1139 | _data._projection = (Projection *)Pools::_bucket_large.alloc(); |
1140 | memnew_placement(_data._projection, Projection(*p_variant._data._projection)); |
1141 | } break; |
1142 | |
1143 | // Miscellaneous types. |
1144 | case COLOR: { |
1145 | memnew_placement(_data._mem, Color(*reinterpret_cast<const Color *>(p_variant._data._mem))); |
1146 | } break; |
1147 | case RID: { |
1148 | memnew_placement(_data._mem, ::RID(*reinterpret_cast<const ::RID *>(p_variant._data._mem))); |
1149 | } break; |
1150 | case OBJECT: { |
1151 | memnew_placement(_data._mem, ObjData); |
1152 | |
1153 | if (p_variant._get_obj().obj && p_variant._get_obj().id.is_ref_counted()) { |
1154 | RefCounted *ref_counted = static_cast<RefCounted *>(p_variant._get_obj().obj); |
1155 | if (!ref_counted->reference()) { |
1156 | _get_obj().obj = nullptr; |
1157 | _get_obj().id = ObjectID(); |
1158 | break; |
1159 | } |
1160 | } |
1161 | |
1162 | _get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj); |
1163 | _get_obj().id = p_variant._get_obj().id; |
1164 | } break; |
1165 | case CALLABLE: { |
1166 | memnew_placement(_data._mem, Callable(*reinterpret_cast<const Callable *>(p_variant._data._mem))); |
1167 | } break; |
1168 | case SIGNAL: { |
1169 | memnew_placement(_data._mem, Signal(*reinterpret_cast<const Signal *>(p_variant._data._mem))); |
1170 | } break; |
1171 | case STRING_NAME: { |
1172 | memnew_placement(_data._mem, StringName(*reinterpret_cast<const StringName *>(p_variant._data._mem))); |
1173 | } break; |
1174 | case NODE_PATH: { |
1175 | memnew_placement(_data._mem, NodePath(*reinterpret_cast<const NodePath *>(p_variant._data._mem))); |
1176 | } break; |
1177 | case DICTIONARY: { |
1178 | memnew_placement(_data._mem, Dictionary(*reinterpret_cast<const Dictionary *>(p_variant._data._mem))); |
1179 | } break; |
1180 | case ARRAY: { |
1181 | memnew_placement(_data._mem, Array(*reinterpret_cast<const Array *>(p_variant._data._mem))); |
1182 | } break; |
1183 | |
1184 | // Arrays. |
1185 | case PACKED_BYTE_ARRAY: { |
1186 | _data.packed_array = static_cast<PackedArrayRef<uint8_t> *>(p_variant._data.packed_array)->reference(); |
1187 | if (!_data.packed_array) { |
1188 | _data.packed_array = PackedArrayRef<uint8_t>::create(); |
1189 | } |
1190 | } break; |
1191 | case PACKED_INT32_ARRAY: { |
1192 | _data.packed_array = static_cast<PackedArrayRef<int32_t> *>(p_variant._data.packed_array)->reference(); |
1193 | if (!_data.packed_array) { |
1194 | _data.packed_array = PackedArrayRef<int32_t>::create(); |
1195 | } |
1196 | } break; |
1197 | case PACKED_INT64_ARRAY: { |
1198 | _data.packed_array = static_cast<PackedArrayRef<int64_t> *>(p_variant._data.packed_array)->reference(); |
1199 | if (!_data.packed_array) { |
1200 | _data.packed_array = PackedArrayRef<int64_t>::create(); |
1201 | } |
1202 | } break; |
1203 | case PACKED_FLOAT32_ARRAY: { |
1204 | _data.packed_array = static_cast<PackedArrayRef<float> *>(p_variant._data.packed_array)->reference(); |
1205 | if (!_data.packed_array) { |
1206 | _data.packed_array = PackedArrayRef<float>::create(); |
1207 | } |
1208 | } break; |
1209 | case PACKED_FLOAT64_ARRAY: { |
1210 | _data.packed_array = static_cast<PackedArrayRef<double> *>(p_variant._data.packed_array)->reference(); |
1211 | if (!_data.packed_array) { |
1212 | _data.packed_array = PackedArrayRef<double>::create(); |
1213 | } |
1214 | } break; |
1215 | case PACKED_STRING_ARRAY: { |
1216 | _data.packed_array = static_cast<PackedArrayRef<String> *>(p_variant._data.packed_array)->reference(); |
1217 | if (!_data.packed_array) { |
1218 | _data.packed_array = PackedArrayRef<String>::create(); |
1219 | } |
1220 | } break; |
1221 | case PACKED_VECTOR2_ARRAY: { |
1222 | _data.packed_array = static_cast<PackedArrayRef<Vector2> *>(p_variant._data.packed_array)->reference(); |
1223 | if (!_data.packed_array) { |
1224 | _data.packed_array = PackedArrayRef<Vector2>::create(); |
1225 | } |
1226 | } break; |
1227 | case PACKED_VECTOR3_ARRAY: { |
1228 | _data.packed_array = static_cast<PackedArrayRef<Vector3> *>(p_variant._data.packed_array)->reference(); |
1229 | if (!_data.packed_array) { |
1230 | _data.packed_array = PackedArrayRef<Vector3>::create(); |
1231 | } |
1232 | } break; |
1233 | case PACKED_COLOR_ARRAY: { |
1234 | _data.packed_array = static_cast<PackedArrayRef<Color> *>(p_variant._data.packed_array)->reference(); |
1235 | if (!_data.packed_array) { |
1236 | _data.packed_array = PackedArrayRef<Color>::create(); |
1237 | } |
1238 | } break; |
1239 | default: { |
1240 | } |
1241 | } |
1242 | } |
1243 | |
1244 | void Variant::zero() { |
1245 | switch (type) { |
1246 | case NIL: |
1247 | break; |
1248 | case BOOL: |
1249 | this->_data._bool = false; |
1250 | break; |
1251 | case INT: |
1252 | this->_data._int = 0; |
1253 | break; |
1254 | case FLOAT: |
1255 | this->_data._float = 0; |
1256 | break; |
1257 | |
1258 | case VECTOR2: |
1259 | *reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2(); |
1260 | break; |
1261 | case VECTOR2I: |
1262 | *reinterpret_cast<Vector2i *>(this->_data._mem) = Vector2i(); |
1263 | break; |
1264 | case RECT2: |
1265 | *reinterpret_cast<Rect2 *>(this->_data._mem) = Rect2(); |
1266 | break; |
1267 | case RECT2I: |
1268 | *reinterpret_cast<Rect2i *>(this->_data._mem) = Rect2i(); |
1269 | break; |
1270 | case VECTOR3: |
1271 | *reinterpret_cast<Vector3 *>(this->_data._mem) = Vector3(); |
1272 | break; |
1273 | case VECTOR3I: |
1274 | *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i(); |
1275 | break; |
1276 | case VECTOR4: |
1277 | *reinterpret_cast<Vector4 *>(this->_data._mem) = Vector4(); |
1278 | break; |
1279 | case VECTOR4I: |
1280 | *reinterpret_cast<Vector4i *>(this->_data._mem) = Vector4i(); |
1281 | break; |
1282 | case PLANE: |
1283 | *reinterpret_cast<Plane *>(this->_data._mem) = Plane(); |
1284 | break; |
1285 | case QUATERNION: |
1286 | *reinterpret_cast<Quaternion *>(this->_data._mem) = Quaternion(); |
1287 | break; |
1288 | |
1289 | case COLOR: |
1290 | *reinterpret_cast<Color *>(this->_data._mem) = Color(); |
1291 | break; |
1292 | |
1293 | default: |
1294 | this->clear(); |
1295 | break; |
1296 | } |
1297 | } |
1298 | |
1299 | void Variant::_clear_internal() { |
1300 | switch (type) { |
1301 | case STRING: { |
1302 | reinterpret_cast<String *>(_data._mem)->~String(); |
1303 | } break; |
1304 | |
1305 | // Math types. |
1306 | case TRANSFORM2D: { |
1307 | if (_data._transform2d) { |
1308 | _data._transform2d->~Transform2D(); |
1309 | Pools::_bucket_small.free((Pools::BucketSmall *)_data._transform2d); |
1310 | _data._transform2d = nullptr; |
1311 | } |
1312 | } break; |
1313 | case AABB: { |
1314 | if (_data._aabb) { |
1315 | _data._aabb->~AABB(); |
1316 | Pools::_bucket_small.free((Pools::BucketSmall *)_data._aabb); |
1317 | _data._aabb = nullptr; |
1318 | } |
1319 | } break; |
1320 | case BASIS: { |
1321 | if (_data._basis) { |
1322 | _data._basis->~Basis(); |
1323 | Pools::_bucket_medium.free((Pools::BucketMedium *)_data._basis); |
1324 | _data._basis = nullptr; |
1325 | } |
1326 | } break; |
1327 | case TRANSFORM3D: { |
1328 | if (_data._transform3d) { |
1329 | _data._transform3d->~Transform3D(); |
1330 | Pools::_bucket_medium.free((Pools::BucketMedium *)_data._transform3d); |
1331 | _data._transform3d = nullptr; |
1332 | } |
1333 | } break; |
1334 | case PROJECTION: { |
1335 | if (_data._projection) { |
1336 | _data._projection->~Projection(); |
1337 | Pools::_bucket_large.free((Pools::BucketLarge *)_data._projection); |
1338 | _data._projection = nullptr; |
1339 | } |
1340 | } break; |
1341 | |
1342 | // Miscellaneous types. |
1343 | case STRING_NAME: { |
1344 | reinterpret_cast<StringName *>(_data._mem)->~StringName(); |
1345 | } break; |
1346 | case NODE_PATH: { |
1347 | reinterpret_cast<NodePath *>(_data._mem)->~NodePath(); |
1348 | } break; |
1349 | case OBJECT: { |
1350 | if (_get_obj().id.is_ref_counted()) { |
1351 | // We are safe that there is a reference here. |
1352 | RefCounted *ref_counted = static_cast<RefCounted *>(_get_obj().obj); |
1353 | if (ref_counted->unreference()) { |
1354 | memdelete(ref_counted); |
1355 | } |
1356 | } |
1357 | _get_obj().obj = nullptr; |
1358 | _get_obj().id = ObjectID(); |
1359 | } break; |
1360 | case RID: { |
1361 | // Not much need probably. |
1362 | // HACK: Can't seem to use destructor + scoping operator, so hack. |
1363 | typedef ::RID RID_Class; |
1364 | reinterpret_cast<RID_Class *>(_data._mem)->~RID_Class(); |
1365 | } break; |
1366 | case CALLABLE: { |
1367 | reinterpret_cast<Callable *>(_data._mem)->~Callable(); |
1368 | } break; |
1369 | case SIGNAL: { |
1370 | reinterpret_cast<Signal *>(_data._mem)->~Signal(); |
1371 | } break; |
1372 | case DICTIONARY: { |
1373 | reinterpret_cast<Dictionary *>(_data._mem)->~Dictionary(); |
1374 | } break; |
1375 | case ARRAY: { |
1376 | reinterpret_cast<Array *>(_data._mem)->~Array(); |
1377 | } break; |
1378 | |
1379 | // Arrays. |
1380 | case PACKED_BYTE_ARRAY: { |
1381 | PackedArrayRefBase::destroy(_data.packed_array); |
1382 | } break; |
1383 | case PACKED_INT32_ARRAY: { |
1384 | PackedArrayRefBase::destroy(_data.packed_array); |
1385 | } break; |
1386 | case PACKED_INT64_ARRAY: { |
1387 | PackedArrayRefBase::destroy(_data.packed_array); |
1388 | } break; |
1389 | case PACKED_FLOAT32_ARRAY: { |
1390 | PackedArrayRefBase::destroy(_data.packed_array); |
1391 | } break; |
1392 | case PACKED_FLOAT64_ARRAY: { |
1393 | PackedArrayRefBase::destroy(_data.packed_array); |
1394 | } break; |
1395 | case PACKED_STRING_ARRAY: { |
1396 | PackedArrayRefBase::destroy(_data.packed_array); |
1397 | } break; |
1398 | case PACKED_VECTOR2_ARRAY: { |
1399 | PackedArrayRefBase::destroy(_data.packed_array); |
1400 | } break; |
1401 | case PACKED_VECTOR3_ARRAY: { |
1402 | PackedArrayRefBase::destroy(_data.packed_array); |
1403 | } break; |
1404 | case PACKED_COLOR_ARRAY: { |
1405 | PackedArrayRefBase::destroy(_data.packed_array); |
1406 | } break; |
1407 | default: { |
1408 | // Not needed, there is no point. The following do not allocate memory: |
1409 | // VECTOR2, VECTOR3, RECT2, PLANE, QUATERNION, COLOR. |
1410 | } |
1411 | } |
1412 | } |
1413 | |
1414 | Variant::operator signed int() const { |
1415 | switch (type) { |
1416 | case NIL: |
1417 | return 0; |
1418 | case BOOL: |
1419 | return _data._bool ? 1 : 0; |
1420 | case INT: |
1421 | return _data._int; |
1422 | case FLOAT: |
1423 | return _data._float; |
1424 | case STRING: |
1425 | return operator String().to_int(); |
1426 | default: { |
1427 | return 0; |
1428 | } |
1429 | } |
1430 | } |
1431 | |
1432 | Variant::operator unsigned int() const { |
1433 | switch (type) { |
1434 | case NIL: |
1435 | return 0; |
1436 | case BOOL: |
1437 | return _data._bool ? 1 : 0; |
1438 | case INT: |
1439 | return _data._int; |
1440 | case FLOAT: |
1441 | return _data._float; |
1442 | case STRING: |
1443 | return operator String().to_int(); |
1444 | default: { |
1445 | return 0; |
1446 | } |
1447 | } |
1448 | } |
1449 | |
1450 | Variant::operator int64_t() const { |
1451 | switch (type) { |
1452 | case NIL: |
1453 | return 0; |
1454 | case BOOL: |
1455 | return _data._bool ? 1 : 0; |
1456 | case INT: |
1457 | return _data._int; |
1458 | case FLOAT: |
1459 | return _data._float; |
1460 | case STRING: |
1461 | return operator String().to_int(); |
1462 | default: { |
1463 | return 0; |
1464 | } |
1465 | } |
1466 | } |
1467 | |
1468 | Variant::operator uint64_t() const { |
1469 | switch (type) { |
1470 | case NIL: |
1471 | return 0; |
1472 | case BOOL: |
1473 | return _data._bool ? 1 : 0; |
1474 | case INT: |
1475 | return _data._int; |
1476 | case FLOAT: |
1477 | return _data._float; |
1478 | case STRING: |
1479 | return operator String().to_int(); |
1480 | default: { |
1481 | return 0; |
1482 | } |
1483 | } |
1484 | } |
1485 | |
1486 | Variant::operator ObjectID() const { |
1487 | if (type == INT) { |
1488 | return ObjectID(_data._int); |
1489 | } else if (type == OBJECT) { |
1490 | return _get_obj().id; |
1491 | } else { |
1492 | return ObjectID(); |
1493 | } |
1494 | } |
1495 | |
1496 | #ifdef NEED_LONG_INT |
1497 | Variant::operator signed long() const { |
1498 | switch (type) { |
1499 | case NIL: |
1500 | return 0; |
1501 | case BOOL: |
1502 | return _data._bool ? 1 : 0; |
1503 | case INT: |
1504 | return _data._int; |
1505 | case FLOAT: |
1506 | return _data._float; |
1507 | case STRING: |
1508 | return operator String().to_int(); |
1509 | default: { |
1510 | return 0; |
1511 | } |
1512 | } |
1513 | |
1514 | return 0; |
1515 | } |
1516 | |
1517 | Variant::operator unsigned long() const { |
1518 | switch (type) { |
1519 | case NIL: |
1520 | return 0; |
1521 | case BOOL: |
1522 | return _data._bool ? 1 : 0; |
1523 | case INT: |
1524 | return _data._int; |
1525 | case FLOAT: |
1526 | return _data._float; |
1527 | case STRING: |
1528 | return operator String().to_int(); |
1529 | default: { |
1530 | return 0; |
1531 | } |
1532 | } |
1533 | |
1534 | return 0; |
1535 | } |
1536 | #endif |
1537 | |
1538 | Variant::operator signed short() const { |
1539 | switch (type) { |
1540 | case NIL: |
1541 | return 0; |
1542 | case BOOL: |
1543 | return _data._bool ? 1 : 0; |
1544 | case INT: |
1545 | return _data._int; |
1546 | case FLOAT: |
1547 | return _data._float; |
1548 | case STRING: |
1549 | return operator String().to_int(); |
1550 | default: { |
1551 | return 0; |
1552 | } |
1553 | } |
1554 | } |
1555 | |
1556 | Variant::operator unsigned short() const { |
1557 | switch (type) { |
1558 | case NIL: |
1559 | return 0; |
1560 | case BOOL: |
1561 | return _data._bool ? 1 : 0; |
1562 | case INT: |
1563 | return _data._int; |
1564 | case FLOAT: |
1565 | return _data._float; |
1566 | case STRING: |
1567 | return operator String().to_int(); |
1568 | default: { |
1569 | return 0; |
1570 | } |
1571 | } |
1572 | } |
1573 | |
1574 | Variant::operator signed char() const { |
1575 | switch (type) { |
1576 | case NIL: |
1577 | return 0; |
1578 | case BOOL: |
1579 | return _data._bool ? 1 : 0; |
1580 | case INT: |
1581 | return _data._int; |
1582 | case FLOAT: |
1583 | return _data._float; |
1584 | case STRING: |
1585 | return operator String().to_int(); |
1586 | default: { |
1587 | return 0; |
1588 | } |
1589 | } |
1590 | } |
1591 | |
1592 | Variant::operator unsigned char() const { |
1593 | switch (type) { |
1594 | case NIL: |
1595 | return 0; |
1596 | case BOOL: |
1597 | return _data._bool ? 1 : 0; |
1598 | case INT: |
1599 | return _data._int; |
1600 | case FLOAT: |
1601 | return _data._float; |
1602 | case STRING: |
1603 | return operator String().to_int(); |
1604 | default: { |
1605 | return 0; |
1606 | } |
1607 | } |
1608 | } |
1609 | |
1610 | Variant::operator char32_t() const { |
1611 | return operator unsigned int(); |
1612 | } |
1613 | |
1614 | Variant::operator float() const { |
1615 | switch (type) { |
1616 | case NIL: |
1617 | return 0; |
1618 | case BOOL: |
1619 | return _data._bool ? 1.0 : 0.0; |
1620 | case INT: |
1621 | return (float)_data._int; |
1622 | case FLOAT: |
1623 | return _data._float; |
1624 | case STRING: |
1625 | return operator String().to_float(); |
1626 | default: { |
1627 | return 0; |
1628 | } |
1629 | } |
1630 | } |
1631 | |
1632 | Variant::operator double() const { |
1633 | switch (type) { |
1634 | case NIL: |
1635 | return 0; |
1636 | case BOOL: |
1637 | return _data._bool ? 1.0 : 0.0; |
1638 | case INT: |
1639 | return (double)_data._int; |
1640 | case FLOAT: |
1641 | return _data._float; |
1642 | case STRING: |
1643 | return operator String().to_float(); |
1644 | default: { |
1645 | return 0; |
1646 | } |
1647 | } |
1648 | } |
1649 | |
1650 | Variant::operator StringName() const { |
1651 | if (type == STRING_NAME) { |
1652 | return *reinterpret_cast<const StringName *>(_data._mem); |
1653 | } else if (type == STRING) { |
1654 | return *reinterpret_cast<const String *>(_data._mem); |
1655 | } |
1656 | |
1657 | return StringName(); |
1658 | } |
1659 | |
1660 | struct _VariantStrPair { |
1661 | String key; |
1662 | String value; |
1663 | |
1664 | bool operator<(const _VariantStrPair &p) const { |
1665 | return key < p.key; |
1666 | } |
1667 | }; |
1668 | |
1669 | Variant::operator String() const { |
1670 | return stringify(0); |
1671 | } |
1672 | |
1673 | String stringify_variant_clean(const Variant p_variant, int recursion_count) { |
1674 | String s = p_variant.stringify(recursion_count); |
1675 | |
1676 | // Wrap strings in quotes to avoid ambiguity. |
1677 | switch (p_variant.get_type()) { |
1678 | case Variant::STRING: { |
1679 | s = s.c_escape().quote(); |
1680 | } break; |
1681 | case Variant::STRING_NAME: { |
1682 | s = "&" + s.c_escape().quote(); |
1683 | } break; |
1684 | case Variant::NODE_PATH: { |
1685 | s = "^" + s.c_escape().quote(); |
1686 | } break; |
1687 | default: { |
1688 | } break; |
1689 | } |
1690 | |
1691 | return s; |
1692 | } |
1693 | |
1694 | template <class T> |
1695 | String stringify_vector(const T &vec, int recursion_count) { |
1696 | String str("[" ); |
1697 | for (int i = 0; i < vec.size(); i++) { |
1698 | if (i > 0) { |
1699 | str += ", " ; |
1700 | } |
1701 | |
1702 | str += stringify_variant_clean(vec[i], recursion_count); |
1703 | } |
1704 | str += "]" ; |
1705 | return str; |
1706 | } |
1707 | |
1708 | String Variant::stringify(int recursion_count) const { |
1709 | switch (type) { |
1710 | case NIL: |
1711 | return "<null>" ; |
1712 | case BOOL: |
1713 | return _data._bool ? "true" : "false" ; |
1714 | case INT: |
1715 | return itos(_data._int); |
1716 | case FLOAT: |
1717 | return rtos(_data._float); |
1718 | case STRING: |
1719 | return *reinterpret_cast<const String *>(_data._mem); |
1720 | case VECTOR2: |
1721 | return operator Vector2(); |
1722 | case VECTOR2I: |
1723 | return operator Vector2i(); |
1724 | case RECT2: |
1725 | return operator Rect2(); |
1726 | case RECT2I: |
1727 | return operator Rect2i(); |
1728 | case TRANSFORM2D: |
1729 | return operator Transform2D(); |
1730 | case VECTOR3: |
1731 | return operator Vector3(); |
1732 | case VECTOR3I: |
1733 | return operator Vector3i(); |
1734 | case VECTOR4: |
1735 | return operator Vector4(); |
1736 | case VECTOR4I: |
1737 | return operator Vector4i(); |
1738 | case PLANE: |
1739 | return operator Plane(); |
1740 | case AABB: |
1741 | return operator ::AABB(); |
1742 | case QUATERNION: |
1743 | return operator Quaternion(); |
1744 | case BASIS: |
1745 | return operator Basis(); |
1746 | case TRANSFORM3D: |
1747 | return operator Transform3D(); |
1748 | case PROJECTION: |
1749 | return operator Projection(); |
1750 | case STRING_NAME: |
1751 | return operator StringName(); |
1752 | case NODE_PATH: |
1753 | return operator NodePath(); |
1754 | case COLOR: |
1755 | return operator Color(); |
1756 | case DICTIONARY: { |
1757 | ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "{ ... }" , "Maximum dictionary recursion reached!" ); |
1758 | recursion_count++; |
1759 | |
1760 | const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem); |
1761 | |
1762 | // Add leading and trailing space to Dictionary printing. This distinguishes it |
1763 | // from array printing on fonts that have similar-looking {} and [] characters. |
1764 | String str("{ " ); |
1765 | List<Variant> keys; |
1766 | d.get_key_list(&keys); |
1767 | |
1768 | Vector<_VariantStrPair> pairs; |
1769 | |
1770 | for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { |
1771 | _VariantStrPair sp; |
1772 | sp.key = stringify_variant_clean(E->get(), recursion_count); |
1773 | sp.value = stringify_variant_clean(d[E->get()], recursion_count); |
1774 | |
1775 | pairs.push_back(sp); |
1776 | } |
1777 | |
1778 | for (int i = 0; i < pairs.size(); i++) { |
1779 | if (i > 0) { |
1780 | str += ", " ; |
1781 | } |
1782 | str += pairs[i].key + ": " + pairs[i].value; |
1783 | } |
1784 | str += " }" ; |
1785 | |
1786 | return str; |
1787 | } |
1788 | // Packed arrays cannot contain recursive structures, the recursion_count increment is not needed. |
1789 | case PACKED_VECTOR2_ARRAY: { |
1790 | return stringify_vector(operator Vector<Vector2>(), recursion_count); |
1791 | } |
1792 | case PACKED_VECTOR3_ARRAY: { |
1793 | return stringify_vector(operator Vector<Vector3>(), recursion_count); |
1794 | } |
1795 | case PACKED_COLOR_ARRAY: { |
1796 | return stringify_vector(operator Vector<Color>(), recursion_count); |
1797 | } |
1798 | case PACKED_STRING_ARRAY: { |
1799 | return stringify_vector(operator Vector<String>(), recursion_count); |
1800 | } |
1801 | case PACKED_BYTE_ARRAY: { |
1802 | return stringify_vector(operator Vector<uint8_t>(), recursion_count); |
1803 | } |
1804 | case PACKED_INT32_ARRAY: { |
1805 | return stringify_vector(operator Vector<int32_t>(), recursion_count); |
1806 | } |
1807 | case PACKED_INT64_ARRAY: { |
1808 | return stringify_vector(operator Vector<int64_t>(), recursion_count); |
1809 | } |
1810 | case PACKED_FLOAT32_ARRAY: { |
1811 | return stringify_vector(operator Vector<float>(), recursion_count); |
1812 | } |
1813 | case PACKED_FLOAT64_ARRAY: { |
1814 | return stringify_vector(operator Vector<double>(), recursion_count); |
1815 | } |
1816 | case ARRAY: { |
1817 | ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "[...]" , "Maximum array recursion reached!" ); |
1818 | recursion_count++; |
1819 | |
1820 | return stringify_vector(operator Array(), recursion_count); |
1821 | } |
1822 | case OBJECT: { |
1823 | if (_get_obj().obj) { |
1824 | if (!_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) { |
1825 | return "<Freed Object>" ; |
1826 | } |
1827 | |
1828 | return _get_obj().obj->to_string(); |
1829 | } else { |
1830 | return "<Object#null>" ; |
1831 | } |
1832 | } |
1833 | case CALLABLE: { |
1834 | const Callable &c = *reinterpret_cast<const Callable *>(_data._mem); |
1835 | return c; |
1836 | } |
1837 | case SIGNAL: { |
1838 | const Signal &s = *reinterpret_cast<const Signal *>(_data._mem); |
1839 | return s; |
1840 | } |
1841 | case RID: { |
1842 | const ::RID &s = *reinterpret_cast<const ::RID *>(_data._mem); |
1843 | return "RID(" + itos(s.get_id()) + ")" ; |
1844 | } |
1845 | default: { |
1846 | return "<" + get_type_name(type) + ">" ; |
1847 | } |
1848 | } |
1849 | } |
1850 | |
1851 | String Variant::to_json_string() const { |
1852 | return JSON::stringify(*this); |
1853 | } |
1854 | |
1855 | Variant::operator Vector2() const { |
1856 | if (type == VECTOR2) { |
1857 | return *reinterpret_cast<const Vector2 *>(_data._mem); |
1858 | } else if (type == VECTOR2I) { |
1859 | return *reinterpret_cast<const Vector2i *>(_data._mem); |
1860 | } else if (type == VECTOR3) { |
1861 | return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y); |
1862 | } else if (type == VECTOR3I) { |
1863 | return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y); |
1864 | } else if (type == VECTOR4) { |
1865 | return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y); |
1866 | } else if (type == VECTOR4I) { |
1867 | return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y); |
1868 | } else { |
1869 | return Vector2(); |
1870 | } |
1871 | } |
1872 | |
1873 | Variant::operator Vector2i() const { |
1874 | if (type == VECTOR2I) { |
1875 | return *reinterpret_cast<const Vector2i *>(_data._mem); |
1876 | } else if (type == VECTOR2) { |
1877 | return *reinterpret_cast<const Vector2 *>(_data._mem); |
1878 | } else if (type == VECTOR3) { |
1879 | return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y); |
1880 | } else if (type == VECTOR3I) { |
1881 | return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y); |
1882 | } else if (type == VECTOR4) { |
1883 | return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y); |
1884 | } else if (type == VECTOR4I) { |
1885 | return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y); |
1886 | } else { |
1887 | return Vector2i(); |
1888 | } |
1889 | } |
1890 | |
1891 | Variant::operator Rect2() const { |
1892 | if (type == RECT2) { |
1893 | return *reinterpret_cast<const Rect2 *>(_data._mem); |
1894 | } else if (type == RECT2I) { |
1895 | return *reinterpret_cast<const Rect2i *>(_data._mem); |
1896 | } else { |
1897 | return Rect2(); |
1898 | } |
1899 | } |
1900 | |
1901 | Variant::operator Rect2i() const { |
1902 | if (type == RECT2I) { |
1903 | return *reinterpret_cast<const Rect2i *>(_data._mem); |
1904 | } else if (type == RECT2) { |
1905 | return *reinterpret_cast<const Rect2 *>(_data._mem); |
1906 | } else { |
1907 | return Rect2i(); |
1908 | } |
1909 | } |
1910 | |
1911 | Variant::operator Vector3() const { |
1912 | if (type == VECTOR3) { |
1913 | return *reinterpret_cast<const Vector3 *>(_data._mem); |
1914 | } else if (type == VECTOR3I) { |
1915 | return *reinterpret_cast<const Vector3i *>(_data._mem); |
1916 | } else if (type == VECTOR2) { |
1917 | return Vector3(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0); |
1918 | } else if (type == VECTOR2I) { |
1919 | return Vector3(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0); |
1920 | } else if (type == VECTOR4) { |
1921 | return Vector3(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z); |
1922 | } else if (type == VECTOR4I) { |
1923 | return Vector3(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z); |
1924 | } else { |
1925 | return Vector3(); |
1926 | } |
1927 | } |
1928 | |
1929 | Variant::operator Vector3i() const { |
1930 | if (type == VECTOR3I) { |
1931 | return *reinterpret_cast<const Vector3i *>(_data._mem); |
1932 | } else if (type == VECTOR3) { |
1933 | return *reinterpret_cast<const Vector3 *>(_data._mem); |
1934 | } else if (type == VECTOR2) { |
1935 | return Vector3i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0); |
1936 | } else if (type == VECTOR2I) { |
1937 | return Vector3i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0); |
1938 | } else if (type == VECTOR4) { |
1939 | return Vector3i(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z); |
1940 | } else if (type == VECTOR4I) { |
1941 | return Vector3i(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z); |
1942 | } else { |
1943 | return Vector3i(); |
1944 | } |
1945 | } |
1946 | |
1947 | Variant::operator Vector4() const { |
1948 | if (type == VECTOR4) { |
1949 | return *reinterpret_cast<const Vector4 *>(_data._mem); |
1950 | } else if (type == VECTOR4I) { |
1951 | return *reinterpret_cast<const Vector4i *>(_data._mem); |
1952 | } else if (type == VECTOR2) { |
1953 | return Vector4(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0); |
1954 | } else if (type == VECTOR2I) { |
1955 | return Vector4(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0); |
1956 | } else if (type == VECTOR3) { |
1957 | return Vector4(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0); |
1958 | } else if (type == VECTOR3I) { |
1959 | return Vector4(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0); |
1960 | } else { |
1961 | return Vector4(); |
1962 | } |
1963 | } |
1964 | |
1965 | Variant::operator Vector4i() const { |
1966 | if (type == VECTOR4I) { |
1967 | return *reinterpret_cast<const Vector4i *>(_data._mem); |
1968 | } else if (type == VECTOR4) { |
1969 | const Vector4 &v4 = *reinterpret_cast<const Vector4 *>(_data._mem); |
1970 | return Vector4i(v4.x, v4.y, v4.z, v4.w); |
1971 | } else if (type == VECTOR2) { |
1972 | return Vector4i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0); |
1973 | } else if (type == VECTOR2I) { |
1974 | return Vector4i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0); |
1975 | } else if (type == VECTOR3) { |
1976 | return Vector4i(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0); |
1977 | } else if (type == VECTOR3I) { |
1978 | return Vector4i(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0); |
1979 | } else { |
1980 | return Vector4i(); |
1981 | } |
1982 | } |
1983 | |
1984 | Variant::operator Plane() const { |
1985 | if (type == PLANE) { |
1986 | return *reinterpret_cast<const Plane *>(_data._mem); |
1987 | } else { |
1988 | return Plane(); |
1989 | } |
1990 | } |
1991 | |
1992 | Variant::operator ::AABB() const { |
1993 | if (type == AABB) { |
1994 | return *_data._aabb; |
1995 | } else { |
1996 | return ::AABB(); |
1997 | } |
1998 | } |
1999 | |
2000 | Variant::operator Basis() const { |
2001 | if (type == BASIS) { |
2002 | return *_data._basis; |
2003 | } else if (type == QUATERNION) { |
2004 | return *reinterpret_cast<const Quaternion *>(_data._mem); |
2005 | } else if (type == TRANSFORM3D) { // unexposed in Variant::can_convert? |
2006 | return _data._transform3d->basis; |
2007 | } else { |
2008 | return Basis(); |
2009 | } |
2010 | } |
2011 | |
2012 | Variant::operator Quaternion() const { |
2013 | if (type == QUATERNION) { |
2014 | return *reinterpret_cast<const Quaternion *>(_data._mem); |
2015 | } else if (type == BASIS) { |
2016 | return *_data._basis; |
2017 | } else if (type == TRANSFORM3D) { |
2018 | return _data._transform3d->basis; |
2019 | } else { |
2020 | return Quaternion(); |
2021 | } |
2022 | } |
2023 | |
2024 | Variant::operator Transform3D() const { |
2025 | if (type == TRANSFORM3D) { |
2026 | return *_data._transform3d; |
2027 | } else if (type == BASIS) { |
2028 | return Transform3D(*_data._basis, Vector3()); |
2029 | } else if (type == QUATERNION) { |
2030 | return Transform3D(Basis(*reinterpret_cast<const Quaternion *>(_data._mem)), Vector3()); |
2031 | } else if (type == TRANSFORM2D) { |
2032 | const Transform2D &t = *_data._transform2d; |
2033 | Transform3D m; |
2034 | m.basis.rows[0][0] = t.columns[0][0]; |
2035 | m.basis.rows[1][0] = t.columns[0][1]; |
2036 | m.basis.rows[0][1] = t.columns[1][0]; |
2037 | m.basis.rows[1][1] = t.columns[1][1]; |
2038 | m.origin[0] = t.columns[2][0]; |
2039 | m.origin[1] = t.columns[2][1]; |
2040 | return m; |
2041 | } else if (type == PROJECTION) { |
2042 | return *_data._projection; |
2043 | } else { |
2044 | return Transform3D(); |
2045 | } |
2046 | } |
2047 | |
2048 | Variant::operator Projection() const { |
2049 | if (type == TRANSFORM3D) { |
2050 | return *_data._transform3d; |
2051 | } else if (type == BASIS) { |
2052 | return Transform3D(*_data._basis, Vector3()); |
2053 | } else if (type == QUATERNION) { |
2054 | return Transform3D(Basis(*reinterpret_cast<const Quaternion *>(_data._mem)), Vector3()); |
2055 | } else if (type == TRANSFORM2D) { |
2056 | const Transform2D &t = *_data._transform2d; |
2057 | Transform3D m; |
2058 | m.basis.rows[0][0] = t.columns[0][0]; |
2059 | m.basis.rows[1][0] = t.columns[0][1]; |
2060 | m.basis.rows[0][1] = t.columns[1][0]; |
2061 | m.basis.rows[1][1] = t.columns[1][1]; |
2062 | m.origin[0] = t.columns[2][0]; |
2063 | m.origin[1] = t.columns[2][1]; |
2064 | return m; |
2065 | } else if (type == PROJECTION) { |
2066 | return *_data._projection; |
2067 | } else { |
2068 | return Projection(); |
2069 | } |
2070 | } |
2071 | |
2072 | Variant::operator Transform2D() const { |
2073 | if (type == TRANSFORM2D) { |
2074 | return *_data._transform2d; |
2075 | } else if (type == TRANSFORM3D) { |
2076 | const Transform3D &t = *_data._transform3d; |
2077 | Transform2D m; |
2078 | m.columns[0][0] = t.basis.rows[0][0]; |
2079 | m.columns[0][1] = t.basis.rows[1][0]; |
2080 | m.columns[1][0] = t.basis.rows[0][1]; |
2081 | m.columns[1][1] = t.basis.rows[1][1]; |
2082 | m.columns[2][0] = t.origin[0]; |
2083 | m.columns[2][1] = t.origin[1]; |
2084 | return m; |
2085 | } else { |
2086 | return Transform2D(); |
2087 | } |
2088 | } |
2089 | |
2090 | Variant::operator Color() const { |
2091 | if (type == COLOR) { |
2092 | return *reinterpret_cast<const Color *>(_data._mem); |
2093 | } else if (type == STRING) { |
2094 | return Color(operator String()); |
2095 | } else if (type == INT) { |
2096 | return Color::hex(operator int()); |
2097 | } else { |
2098 | return Color(); |
2099 | } |
2100 | } |
2101 | |
2102 | Variant::operator NodePath() const { |
2103 | if (type == NODE_PATH) { |
2104 | return *reinterpret_cast<const NodePath *>(_data._mem); |
2105 | } else if (type == STRING) { |
2106 | return NodePath(operator String()); |
2107 | } else { |
2108 | return NodePath(); |
2109 | } |
2110 | } |
2111 | |
2112 | Variant::operator ::RID() const { |
2113 | if (type == RID) { |
2114 | return *reinterpret_cast<const ::RID *>(_data._mem); |
2115 | } else if (type == OBJECT && _get_obj().obj == nullptr) { |
2116 | return ::RID(); |
2117 | } else if (type == OBJECT && _get_obj().obj) { |
2118 | #ifdef DEBUG_ENABLED |
2119 | if (EngineDebugger::is_active()) { |
2120 | ERR_FAIL_COND_V_MSG(ObjectDB::get_instance(_get_obj().id) == nullptr, ::RID(), "Invalid pointer (object was freed)." ); |
2121 | } |
2122 | #endif |
2123 | Callable::CallError ce; |
2124 | Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce); |
2125 | if (ce.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::RID) { |
2126 | return ret; |
2127 | } |
2128 | return ::RID(); |
2129 | } else { |
2130 | return ::RID(); |
2131 | } |
2132 | } |
2133 | |
2134 | Variant::operator Object *() const { |
2135 | if (type == OBJECT) { |
2136 | return _get_obj().obj; |
2137 | } else { |
2138 | return nullptr; |
2139 | } |
2140 | } |
2141 | |
2142 | Object *Variant::get_validated_object_with_check(bool &r_previously_freed) const { |
2143 | if (type == OBJECT) { |
2144 | Object *instance = ObjectDB::get_instance(_get_obj().id); |
2145 | r_previously_freed = !instance && _get_obj().id != ObjectID(); |
2146 | return instance; |
2147 | } else { |
2148 | r_previously_freed = false; |
2149 | return nullptr; |
2150 | } |
2151 | } |
2152 | |
2153 | Object *Variant::get_validated_object() const { |
2154 | if (type == OBJECT) { |
2155 | return ObjectDB::get_instance(_get_obj().id); |
2156 | } else { |
2157 | return nullptr; |
2158 | } |
2159 | } |
2160 | |
2161 | Variant::operator Dictionary() const { |
2162 | if (type == DICTIONARY) { |
2163 | return *reinterpret_cast<const Dictionary *>(_data._mem); |
2164 | } else { |
2165 | return Dictionary(); |
2166 | } |
2167 | } |
2168 | |
2169 | Variant::operator Callable() const { |
2170 | if (type == CALLABLE) { |
2171 | return *reinterpret_cast<const Callable *>(_data._mem); |
2172 | } else { |
2173 | return Callable(); |
2174 | } |
2175 | } |
2176 | |
2177 | Variant::operator Signal() const { |
2178 | if (type == SIGNAL) { |
2179 | return *reinterpret_cast<const Signal *>(_data._mem); |
2180 | } else { |
2181 | return Signal(); |
2182 | } |
2183 | } |
2184 | |
2185 | template <class DA, class SA> |
2186 | inline DA _convert_array(const SA &p_array) { |
2187 | DA da; |
2188 | da.resize(p_array.size()); |
2189 | |
2190 | for (int i = 0; i < p_array.size(); i++) { |
2191 | da.set(i, Variant(p_array.get(i))); |
2192 | } |
2193 | |
2194 | return da; |
2195 | } |
2196 | |
2197 | template <class DA> |
2198 | inline DA _convert_array_from_variant(const Variant &p_variant) { |
2199 | switch (p_variant.get_type()) { |
2200 | case Variant::ARRAY: { |
2201 | return _convert_array<DA, Array>(p_variant.operator Array()); |
2202 | } |
2203 | case Variant::PACKED_BYTE_ARRAY: { |
2204 | return _convert_array<DA, Vector<uint8_t>>(p_variant.operator Vector<uint8_t>()); |
2205 | } |
2206 | case Variant::PACKED_INT32_ARRAY: { |
2207 | return _convert_array<DA, Vector<int32_t>>(p_variant.operator Vector<int32_t>()); |
2208 | } |
2209 | case Variant::PACKED_INT64_ARRAY: { |
2210 | return _convert_array<DA, Vector<int64_t>>(p_variant.operator Vector<int64_t>()); |
2211 | } |
2212 | case Variant::PACKED_FLOAT32_ARRAY: { |
2213 | return _convert_array<DA, Vector<float>>(p_variant.operator Vector<float>()); |
2214 | } |
2215 | case Variant::PACKED_FLOAT64_ARRAY: { |
2216 | return _convert_array<DA, Vector<double>>(p_variant.operator Vector<double>()); |
2217 | } |
2218 | case Variant::PACKED_STRING_ARRAY: { |
2219 | return _convert_array<DA, Vector<String>>(p_variant.operator Vector<String>()); |
2220 | } |
2221 | case Variant::PACKED_VECTOR2_ARRAY: { |
2222 | return _convert_array<DA, Vector<Vector2>>(p_variant.operator Vector<Vector2>()); |
2223 | } |
2224 | case Variant::PACKED_VECTOR3_ARRAY: { |
2225 | return _convert_array<DA, Vector<Vector3>>(p_variant.operator Vector<Vector3>()); |
2226 | } |
2227 | case Variant::PACKED_COLOR_ARRAY: { |
2228 | return _convert_array<DA, Vector<Color>>(p_variant.operator Vector<Color>()); |
2229 | } |
2230 | default: { |
2231 | return DA(); |
2232 | } |
2233 | } |
2234 | } |
2235 | |
2236 | Variant::operator Array() const { |
2237 | if (type == ARRAY) { |
2238 | return *reinterpret_cast<const Array *>(_data._mem); |
2239 | } else { |
2240 | return _convert_array_from_variant<Array>(*this); |
2241 | } |
2242 | } |
2243 | |
2244 | Variant::operator Vector<uint8_t>() const { |
2245 | if (type == PACKED_BYTE_ARRAY) { |
2246 | return static_cast<PackedArrayRef<uint8_t> *>(_data.packed_array)->array; |
2247 | } else { |
2248 | return _convert_array_from_variant<Vector<uint8_t>>(*this); |
2249 | } |
2250 | } |
2251 | |
2252 | Variant::operator Vector<int32_t>() const { |
2253 | if (type == PACKED_INT32_ARRAY) { |
2254 | return static_cast<PackedArrayRef<int32_t> *>(_data.packed_array)->array; |
2255 | } else { |
2256 | return _convert_array_from_variant<Vector<int>>(*this); |
2257 | } |
2258 | } |
2259 | |
2260 | Variant::operator Vector<int64_t>() const { |
2261 | if (type == PACKED_INT64_ARRAY) { |
2262 | return static_cast<PackedArrayRef<int64_t> *>(_data.packed_array)->array; |
2263 | } else { |
2264 | return _convert_array_from_variant<Vector<int64_t>>(*this); |
2265 | } |
2266 | } |
2267 | |
2268 | Variant::operator Vector<float>() const { |
2269 | if (type == PACKED_FLOAT32_ARRAY) { |
2270 | return static_cast<PackedArrayRef<float> *>(_data.packed_array)->array; |
2271 | } else { |
2272 | return _convert_array_from_variant<Vector<float>>(*this); |
2273 | } |
2274 | } |
2275 | |
2276 | Variant::operator Vector<double>() const { |
2277 | if (type == PACKED_FLOAT64_ARRAY) { |
2278 | return static_cast<PackedArrayRef<double> *>(_data.packed_array)->array; |
2279 | } else { |
2280 | return _convert_array_from_variant<Vector<double>>(*this); |
2281 | } |
2282 | } |
2283 | |
2284 | Variant::operator Vector<String>() const { |
2285 | if (type == PACKED_STRING_ARRAY) { |
2286 | return static_cast<PackedArrayRef<String> *>(_data.packed_array)->array; |
2287 | } else { |
2288 | return _convert_array_from_variant<Vector<String>>(*this); |
2289 | } |
2290 | } |
2291 | |
2292 | Variant::operator Vector<Vector3>() const { |
2293 | if (type == PACKED_VECTOR3_ARRAY) { |
2294 | return static_cast<PackedArrayRef<Vector3> *>(_data.packed_array)->array; |
2295 | } else { |
2296 | return _convert_array_from_variant<Vector<Vector3>>(*this); |
2297 | } |
2298 | } |
2299 | |
2300 | Variant::operator Vector<Vector2>() const { |
2301 | if (type == PACKED_VECTOR2_ARRAY) { |
2302 | return static_cast<PackedArrayRef<Vector2> *>(_data.packed_array)->array; |
2303 | } else { |
2304 | return _convert_array_from_variant<Vector<Vector2>>(*this); |
2305 | } |
2306 | } |
2307 | |
2308 | Variant::operator Vector<Color>() const { |
2309 | if (type == PACKED_COLOR_ARRAY) { |
2310 | return static_cast<PackedArrayRef<Color> *>(_data.packed_array)->array; |
2311 | } else { |
2312 | return _convert_array_from_variant<Vector<Color>>(*this); |
2313 | } |
2314 | } |
2315 | |
2316 | /* helpers */ |
2317 | |
2318 | Variant::operator Vector<::RID>() const { |
2319 | Array va = operator Array(); |
2320 | Vector<::RID> rids; |
2321 | rids.resize(va.size()); |
2322 | for (int i = 0; i < rids.size(); i++) { |
2323 | rids.write[i] = va[i]; |
2324 | } |
2325 | return rids; |
2326 | } |
2327 | |
2328 | Variant::operator Vector<Plane>() const { |
2329 | Array va = operator Array(); |
2330 | Vector<Plane> planes; |
2331 | int va_size = va.size(); |
2332 | if (va_size == 0) { |
2333 | return planes; |
2334 | } |
2335 | |
2336 | planes.resize(va_size); |
2337 | Plane *w = planes.ptrw(); |
2338 | |
2339 | for (int i = 0; i < va_size; i++) { |
2340 | w[i] = va[i]; |
2341 | } |
2342 | |
2343 | return planes; |
2344 | } |
2345 | |
2346 | Variant::operator Vector<Face3>() const { |
2347 | Vector<Vector3> va = operator Vector<Vector3>(); |
2348 | Vector<Face3> faces; |
2349 | int va_size = va.size(); |
2350 | if (va_size == 0) { |
2351 | return faces; |
2352 | } |
2353 | |
2354 | faces.resize(va_size / 3); |
2355 | Face3 *w = faces.ptrw(); |
2356 | const Vector3 *r = va.ptr(); |
2357 | |
2358 | for (int i = 0; i < va_size; i++) { |
2359 | w[i / 3].vertex[i % 3] = r[i]; |
2360 | } |
2361 | |
2362 | return faces; |
2363 | } |
2364 | |
2365 | Variant::operator Vector<Variant>() const { |
2366 | Array va = operator Array(); |
2367 | Vector<Variant> variants; |
2368 | int va_size = va.size(); |
2369 | if (va_size == 0) { |
2370 | return variants; |
2371 | } |
2372 | |
2373 | variants.resize(va_size); |
2374 | Variant *w = variants.ptrw(); |
2375 | for (int i = 0; i < va_size; i++) { |
2376 | w[i] = va[i]; |
2377 | } |
2378 | |
2379 | return variants; |
2380 | } |
2381 | |
2382 | Variant::operator Vector<StringName>() const { |
2383 | Vector<String> from = operator Vector<String>(); |
2384 | Vector<StringName> to; |
2385 | int len = from.size(); |
2386 | to.resize(len); |
2387 | for (int i = 0; i < len; i++) { |
2388 | to.write[i] = from[i]; |
2389 | } |
2390 | return to; |
2391 | } |
2392 | |
2393 | Variant::operator Side() const { |
2394 | return (Side) operator int(); |
2395 | } |
2396 | |
2397 | Variant::operator Orientation() const { |
2398 | return (Orientation) operator int(); |
2399 | } |
2400 | |
2401 | Variant::operator IPAddress() const { |
2402 | if (type == PACKED_FLOAT32_ARRAY || type == PACKED_INT32_ARRAY || type == PACKED_FLOAT64_ARRAY || type == PACKED_INT64_ARRAY || type == PACKED_BYTE_ARRAY) { |
2403 | Vector<int> addr = operator Vector<int>(); |
2404 | if (addr.size() == 4) { |
2405 | return IPAddress(addr.get(0), addr.get(1), addr.get(2), addr.get(3)); |
2406 | } |
2407 | } |
2408 | |
2409 | return IPAddress(operator String()); |
2410 | } |
2411 | |
2412 | Variant::Variant(bool p_bool) { |
2413 | type = BOOL; |
2414 | _data._bool = p_bool; |
2415 | } |
2416 | |
2417 | Variant::Variant(signed int p_int) { |
2418 | type = INT; |
2419 | _data._int = p_int; |
2420 | } |
2421 | |
2422 | Variant::Variant(unsigned int p_int) { |
2423 | type = INT; |
2424 | _data._int = p_int; |
2425 | } |
2426 | |
2427 | #ifdef NEED_LONG_INT |
2428 | |
2429 | Variant::Variant(signed long p_int) { |
2430 | type = INT; |
2431 | _data._int = p_int; |
2432 | } |
2433 | |
2434 | Variant::Variant(unsigned long p_int) { |
2435 | type = INT; |
2436 | _data._int = p_int; |
2437 | } |
2438 | #endif |
2439 | |
2440 | Variant::Variant(int64_t p_int) { |
2441 | type = INT; |
2442 | _data._int = p_int; |
2443 | } |
2444 | |
2445 | Variant::Variant(uint64_t p_int) { |
2446 | type = INT; |
2447 | _data._int = p_int; |
2448 | } |
2449 | |
2450 | Variant::Variant(signed short p_short) { |
2451 | type = INT; |
2452 | _data._int = p_short; |
2453 | } |
2454 | |
2455 | Variant::Variant(unsigned short p_short) { |
2456 | type = INT; |
2457 | _data._int = p_short; |
2458 | } |
2459 | |
2460 | Variant::Variant(signed char p_char) { |
2461 | type = INT; |
2462 | _data._int = p_char; |
2463 | } |
2464 | |
2465 | Variant::Variant(unsigned char p_char) { |
2466 | type = INT; |
2467 | _data._int = p_char; |
2468 | } |
2469 | |
2470 | Variant::Variant(float p_float) { |
2471 | type = FLOAT; |
2472 | _data._float = p_float; |
2473 | } |
2474 | |
2475 | Variant::Variant(double p_double) { |
2476 | type = FLOAT; |
2477 | _data._float = p_double; |
2478 | } |
2479 | |
2480 | Variant::Variant(const ObjectID &p_id) { |
2481 | type = INT; |
2482 | _data._int = p_id; |
2483 | } |
2484 | |
2485 | Variant::Variant(const StringName &p_string) { |
2486 | type = STRING_NAME; |
2487 | memnew_placement(_data._mem, StringName(p_string)); |
2488 | } |
2489 | |
2490 | Variant::Variant(const String &p_string) { |
2491 | type = STRING; |
2492 | memnew_placement(_data._mem, String(p_string)); |
2493 | } |
2494 | |
2495 | Variant::Variant(const char *const p_cstring) { |
2496 | type = STRING; |
2497 | memnew_placement(_data._mem, String((const char *)p_cstring)); |
2498 | } |
2499 | |
2500 | Variant::Variant(const char32_t *p_wstring) { |
2501 | type = STRING; |
2502 | memnew_placement(_data._mem, String(p_wstring)); |
2503 | } |
2504 | |
2505 | Variant::Variant(const Vector3 &p_vector3) { |
2506 | type = VECTOR3; |
2507 | memnew_placement(_data._mem, Vector3(p_vector3)); |
2508 | } |
2509 | |
2510 | Variant::Variant(const Vector3i &p_vector3i) { |
2511 | type = VECTOR3I; |
2512 | memnew_placement(_data._mem, Vector3i(p_vector3i)); |
2513 | } |
2514 | |
2515 | Variant::Variant(const Vector4 &p_vector4) { |
2516 | type = VECTOR4; |
2517 | memnew_placement(_data._mem, Vector4(p_vector4)); |
2518 | } |
2519 | |
2520 | Variant::Variant(const Vector4i &p_vector4i) { |
2521 | type = VECTOR4I; |
2522 | memnew_placement(_data._mem, Vector4i(p_vector4i)); |
2523 | } |
2524 | |
2525 | Variant::Variant(const Vector2 &p_vector2) { |
2526 | type = VECTOR2; |
2527 | memnew_placement(_data._mem, Vector2(p_vector2)); |
2528 | } |
2529 | |
2530 | Variant::Variant(const Vector2i &p_vector2i) { |
2531 | type = VECTOR2I; |
2532 | memnew_placement(_data._mem, Vector2i(p_vector2i)); |
2533 | } |
2534 | |
2535 | Variant::Variant(const Rect2 &p_rect2) { |
2536 | type = RECT2; |
2537 | memnew_placement(_data._mem, Rect2(p_rect2)); |
2538 | } |
2539 | |
2540 | Variant::Variant(const Rect2i &p_rect2i) { |
2541 | type = RECT2I; |
2542 | memnew_placement(_data._mem, Rect2i(p_rect2i)); |
2543 | } |
2544 | |
2545 | Variant::Variant(const Plane &p_plane) { |
2546 | type = PLANE; |
2547 | memnew_placement(_data._mem, Plane(p_plane)); |
2548 | } |
2549 | |
2550 | Variant::Variant(const ::AABB &p_aabb) { |
2551 | type = AABB; |
2552 | _data._aabb = (::AABB *)Pools::_bucket_small.alloc(); |
2553 | memnew_placement(_data._aabb, ::AABB(p_aabb)); |
2554 | } |
2555 | |
2556 | Variant::Variant(const Basis &p_matrix) { |
2557 | type = BASIS; |
2558 | _data._basis = (Basis *)Pools::_bucket_medium.alloc(); |
2559 | memnew_placement(_data._basis, Basis(p_matrix)); |
2560 | } |
2561 | |
2562 | Variant::Variant(const Quaternion &p_quaternion) { |
2563 | type = QUATERNION; |
2564 | memnew_placement(_data._mem, Quaternion(p_quaternion)); |
2565 | } |
2566 | |
2567 | Variant::Variant(const Transform3D &p_transform) { |
2568 | type = TRANSFORM3D; |
2569 | _data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc(); |
2570 | memnew_placement(_data._transform3d, Transform3D(p_transform)); |
2571 | } |
2572 | |
2573 | Variant::Variant(const Projection &pp_projection) { |
2574 | type = PROJECTION; |
2575 | _data._projection = (Projection *)Pools::_bucket_large.alloc(); |
2576 | memnew_placement(_data._projection, Projection(pp_projection)); |
2577 | } |
2578 | |
2579 | Variant::Variant(const Transform2D &p_transform) { |
2580 | type = TRANSFORM2D; |
2581 | _data._transform2d = (Transform2D *)Pools::_bucket_small.alloc(); |
2582 | memnew_placement(_data._transform2d, Transform2D(p_transform)); |
2583 | } |
2584 | |
2585 | Variant::Variant(const Color &p_color) { |
2586 | type = COLOR; |
2587 | memnew_placement(_data._mem, Color(p_color)); |
2588 | } |
2589 | |
2590 | Variant::Variant(const NodePath &p_node_path) { |
2591 | type = NODE_PATH; |
2592 | memnew_placement(_data._mem, NodePath(p_node_path)); |
2593 | } |
2594 | |
2595 | Variant::Variant(const ::RID &p_rid) { |
2596 | type = RID; |
2597 | memnew_placement(_data._mem, ::RID(p_rid)); |
2598 | } |
2599 | |
2600 | Variant::Variant(const Object *p_object) { |
2601 | type = OBJECT; |
2602 | |
2603 | memnew_placement(_data._mem, ObjData); |
2604 | |
2605 | if (p_object) { |
2606 | if (p_object->is_ref_counted()) { |
2607 | RefCounted *ref_counted = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_object)); |
2608 | if (!ref_counted->init_ref()) { |
2609 | _get_obj().obj = nullptr; |
2610 | _get_obj().id = ObjectID(); |
2611 | return; |
2612 | } |
2613 | } |
2614 | |
2615 | _get_obj().obj = const_cast<Object *>(p_object); |
2616 | _get_obj().id = p_object->get_instance_id(); |
2617 | } else { |
2618 | _get_obj().obj = nullptr; |
2619 | _get_obj().id = ObjectID(); |
2620 | } |
2621 | } |
2622 | |
2623 | Variant::Variant(const Callable &p_callable) { |
2624 | type = CALLABLE; |
2625 | memnew_placement(_data._mem, Callable(p_callable)); |
2626 | } |
2627 | |
2628 | Variant::Variant(const Signal &p_callable) { |
2629 | type = SIGNAL; |
2630 | memnew_placement(_data._mem, Signal(p_callable)); |
2631 | } |
2632 | |
2633 | Variant::Variant(const Dictionary &p_dictionary) { |
2634 | type = DICTIONARY; |
2635 | memnew_placement(_data._mem, Dictionary(p_dictionary)); |
2636 | } |
2637 | |
2638 | Variant::Variant(const Array &p_array) { |
2639 | type = ARRAY; |
2640 | memnew_placement(_data._mem, Array(p_array)); |
2641 | } |
2642 | |
2643 | Variant::Variant(const Vector<Plane> &p_array) { |
2644 | type = ARRAY; |
2645 | |
2646 | Array *plane_array = memnew_placement(_data._mem, Array); |
2647 | |
2648 | plane_array->resize(p_array.size()); |
2649 | |
2650 | for (int i = 0; i < p_array.size(); i++) { |
2651 | plane_array->operator[](i) = Variant(p_array[i]); |
2652 | } |
2653 | } |
2654 | |
2655 | Variant::Variant(const Vector<::RID> &p_array) { |
2656 | type = ARRAY; |
2657 | |
2658 | Array *rid_array = memnew_placement(_data._mem, Array); |
2659 | |
2660 | rid_array->resize(p_array.size()); |
2661 | |
2662 | for (int i = 0; i < p_array.size(); i++) { |
2663 | rid_array->set(i, Variant(p_array[i])); |
2664 | } |
2665 | } |
2666 | |
2667 | Variant::Variant(const Vector<uint8_t> &p_byte_array) { |
2668 | type = PACKED_BYTE_ARRAY; |
2669 | |
2670 | _data.packed_array = PackedArrayRef<uint8_t>::create(p_byte_array); |
2671 | } |
2672 | |
2673 | Variant::Variant(const Vector<int32_t> &p_int32_array) { |
2674 | type = PACKED_INT32_ARRAY; |
2675 | _data.packed_array = PackedArrayRef<int32_t>::create(p_int32_array); |
2676 | } |
2677 | |
2678 | Variant::Variant(const Vector<int64_t> &p_int64_array) { |
2679 | type = PACKED_INT64_ARRAY; |
2680 | _data.packed_array = PackedArrayRef<int64_t>::create(p_int64_array); |
2681 | } |
2682 | |
2683 | Variant::Variant(const Vector<float> &p_float32_array) { |
2684 | type = PACKED_FLOAT32_ARRAY; |
2685 | _data.packed_array = PackedArrayRef<float>::create(p_float32_array); |
2686 | } |
2687 | |
2688 | Variant::Variant(const Vector<double> &p_float64_array) { |
2689 | type = PACKED_FLOAT64_ARRAY; |
2690 | _data.packed_array = PackedArrayRef<double>::create(p_float64_array); |
2691 | } |
2692 | |
2693 | Variant::Variant(const Vector<String> &p_string_array) { |
2694 | type = PACKED_STRING_ARRAY; |
2695 | _data.packed_array = PackedArrayRef<String>::create(p_string_array); |
2696 | } |
2697 | |
2698 | Variant::Variant(const Vector<Vector3> &p_vector3_array) { |
2699 | type = PACKED_VECTOR3_ARRAY; |
2700 | _data.packed_array = PackedArrayRef<Vector3>::create(p_vector3_array); |
2701 | } |
2702 | |
2703 | Variant::Variant(const Vector<Vector2> &p_vector2_array) { |
2704 | type = PACKED_VECTOR2_ARRAY; |
2705 | _data.packed_array = PackedArrayRef<Vector2>::create(p_vector2_array); |
2706 | } |
2707 | |
2708 | Variant::Variant(const Vector<Color> &p_color_array) { |
2709 | type = PACKED_COLOR_ARRAY; |
2710 | _data.packed_array = PackedArrayRef<Color>::create(p_color_array); |
2711 | } |
2712 | |
2713 | Variant::Variant(const Vector<Face3> &p_face_array) { |
2714 | Vector<Vector3> vertices; |
2715 | int face_count = p_face_array.size(); |
2716 | vertices.resize(face_count * 3); |
2717 | |
2718 | if (face_count) { |
2719 | const Face3 *r = p_face_array.ptr(); |
2720 | Vector3 *w = vertices.ptrw(); |
2721 | |
2722 | for (int i = 0; i < face_count; i++) { |
2723 | for (int j = 0; j < 3; j++) { |
2724 | w[i * 3 + j] = r[i].vertex[j]; |
2725 | } |
2726 | } |
2727 | } |
2728 | |
2729 | type = NIL; |
2730 | |
2731 | *this = vertices; |
2732 | } |
2733 | |
2734 | /* helpers */ |
2735 | Variant::Variant(const Vector<Variant> &p_array) { |
2736 | type = NIL; |
2737 | Array arr; |
2738 | arr.resize(p_array.size()); |
2739 | for (int i = 0; i < p_array.size(); i++) { |
2740 | arr[i] = p_array[i]; |
2741 | } |
2742 | *this = arr; |
2743 | } |
2744 | |
2745 | Variant::Variant(const Vector<StringName> &p_array) { |
2746 | type = NIL; |
2747 | Vector<String> v; |
2748 | int len = p_array.size(); |
2749 | v.resize(len); |
2750 | for (int i = 0; i < len; i++) { |
2751 | v.set(i, p_array[i]); |
2752 | } |
2753 | *this = v; |
2754 | } |
2755 | |
2756 | void Variant::operator=(const Variant &p_variant) { |
2757 | if (unlikely(this == &p_variant)) { |
2758 | return; |
2759 | } |
2760 | |
2761 | if (unlikely(type != p_variant.type)) { |
2762 | reference(p_variant); |
2763 | return; |
2764 | } |
2765 | |
2766 | switch (p_variant.type) { |
2767 | case NIL: { |
2768 | // none |
2769 | } break; |
2770 | |
2771 | // atomic types |
2772 | case BOOL: { |
2773 | _data._bool = p_variant._data._bool; |
2774 | } break; |
2775 | case INT: { |
2776 | _data._int = p_variant._data._int; |
2777 | } break; |
2778 | case FLOAT: { |
2779 | _data._float = p_variant._data._float; |
2780 | } break; |
2781 | case STRING: { |
2782 | *reinterpret_cast<String *>(_data._mem) = *reinterpret_cast<const String *>(p_variant._data._mem); |
2783 | } break; |
2784 | |
2785 | // math types |
2786 | case VECTOR2: { |
2787 | *reinterpret_cast<Vector2 *>(_data._mem) = *reinterpret_cast<const Vector2 *>(p_variant._data._mem); |
2788 | } break; |
2789 | case VECTOR2I: { |
2790 | *reinterpret_cast<Vector2i *>(_data._mem) = *reinterpret_cast<const Vector2i *>(p_variant._data._mem); |
2791 | } break; |
2792 | case RECT2: { |
2793 | *reinterpret_cast<Rect2 *>(_data._mem) = *reinterpret_cast<const Rect2 *>(p_variant._data._mem); |
2794 | } break; |
2795 | case RECT2I: { |
2796 | *reinterpret_cast<Rect2i *>(_data._mem) = *reinterpret_cast<const Rect2i *>(p_variant._data._mem); |
2797 | } break; |
2798 | case TRANSFORM2D: { |
2799 | *_data._transform2d = *(p_variant._data._transform2d); |
2800 | } break; |
2801 | case VECTOR3: { |
2802 | *reinterpret_cast<Vector3 *>(_data._mem) = *reinterpret_cast<const Vector3 *>(p_variant._data._mem); |
2803 | } break; |
2804 | case VECTOR3I: { |
2805 | *reinterpret_cast<Vector3i *>(_data._mem) = *reinterpret_cast<const Vector3i *>(p_variant._data._mem); |
2806 | } break; |
2807 | case VECTOR4: { |
2808 | *reinterpret_cast<Vector4 *>(_data._mem) = *reinterpret_cast<const Vector4 *>(p_variant._data._mem); |
2809 | } break; |
2810 | case VECTOR4I: { |
2811 | *reinterpret_cast<Vector4i *>(_data._mem) = *reinterpret_cast<const Vector4i *>(p_variant._data._mem); |
2812 | } break; |
2813 | case PLANE: { |
2814 | *reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem); |
2815 | } break; |
2816 | |
2817 | case AABB: { |
2818 | *_data._aabb = *(p_variant._data._aabb); |
2819 | } break; |
2820 | case QUATERNION: { |
2821 | *reinterpret_cast<Quaternion *>(_data._mem) = *reinterpret_cast<const Quaternion *>(p_variant._data._mem); |
2822 | } break; |
2823 | case BASIS: { |
2824 | *_data._basis = *(p_variant._data._basis); |
2825 | } break; |
2826 | case TRANSFORM3D: { |
2827 | *_data._transform3d = *(p_variant._data._transform3d); |
2828 | } break; |
2829 | case PROJECTION: { |
2830 | *_data._projection = *(p_variant._data._projection); |
2831 | } break; |
2832 | |
2833 | // misc types |
2834 | case COLOR: { |
2835 | *reinterpret_cast<Color *>(_data._mem) = *reinterpret_cast<const Color *>(p_variant._data._mem); |
2836 | } break; |
2837 | case RID: { |
2838 | *reinterpret_cast<::RID *>(_data._mem) = *reinterpret_cast<const ::RID *>(p_variant._data._mem); |
2839 | } break; |
2840 | case OBJECT: { |
2841 | if (_get_obj().id.is_ref_counted()) { |
2842 | //we are safe that there is a reference here |
2843 | RefCounted *ref_counted = static_cast<RefCounted *>(_get_obj().obj); |
2844 | if (ref_counted->unreference()) { |
2845 | memdelete(ref_counted); |
2846 | } |
2847 | } |
2848 | |
2849 | if (p_variant._get_obj().obj && p_variant._get_obj().id.is_ref_counted()) { |
2850 | RefCounted *ref_counted = static_cast<RefCounted *>(p_variant._get_obj().obj); |
2851 | if (!ref_counted->reference()) { |
2852 | _get_obj().obj = nullptr; |
2853 | _get_obj().id = ObjectID(); |
2854 | break; |
2855 | } |
2856 | } |
2857 | |
2858 | _get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj); |
2859 | _get_obj().id = p_variant._get_obj().id; |
2860 | |
2861 | } break; |
2862 | case CALLABLE: { |
2863 | *reinterpret_cast<Callable *>(_data._mem) = *reinterpret_cast<const Callable *>(p_variant._data._mem); |
2864 | } break; |
2865 | case SIGNAL: { |
2866 | *reinterpret_cast<Signal *>(_data._mem) = *reinterpret_cast<const Signal *>(p_variant._data._mem); |
2867 | } break; |
2868 | |
2869 | case STRING_NAME: { |
2870 | *reinterpret_cast<StringName *>(_data._mem) = *reinterpret_cast<const StringName *>(p_variant._data._mem); |
2871 | } break; |
2872 | case NODE_PATH: { |
2873 | *reinterpret_cast<NodePath *>(_data._mem) = *reinterpret_cast<const NodePath *>(p_variant._data._mem); |
2874 | } break; |
2875 | case DICTIONARY: { |
2876 | *reinterpret_cast<Dictionary *>(_data._mem) = *reinterpret_cast<const Dictionary *>(p_variant._data._mem); |
2877 | } break; |
2878 | case ARRAY: { |
2879 | *reinterpret_cast<Array *>(_data._mem) = *reinterpret_cast<const Array *>(p_variant._data._mem); |
2880 | } break; |
2881 | |
2882 | // arrays |
2883 | case PACKED_BYTE_ARRAY: { |
2884 | _data.packed_array = PackedArrayRef<uint8_t>::reference_from(_data.packed_array, p_variant._data.packed_array); |
2885 | } break; |
2886 | case PACKED_INT32_ARRAY: { |
2887 | _data.packed_array = PackedArrayRef<int32_t>::reference_from(_data.packed_array, p_variant._data.packed_array); |
2888 | } break; |
2889 | case PACKED_INT64_ARRAY: { |
2890 | _data.packed_array = PackedArrayRef<int64_t>::reference_from(_data.packed_array, p_variant._data.packed_array); |
2891 | } break; |
2892 | case PACKED_FLOAT32_ARRAY: { |
2893 | _data.packed_array = PackedArrayRef<float>::reference_from(_data.packed_array, p_variant._data.packed_array); |
2894 | } break; |
2895 | case PACKED_FLOAT64_ARRAY: { |
2896 | _data.packed_array = PackedArrayRef<double>::reference_from(_data.packed_array, p_variant._data.packed_array); |
2897 | } break; |
2898 | case PACKED_STRING_ARRAY: { |
2899 | _data.packed_array = PackedArrayRef<String>::reference_from(_data.packed_array, p_variant._data.packed_array); |
2900 | } break; |
2901 | case PACKED_VECTOR2_ARRAY: { |
2902 | _data.packed_array = PackedArrayRef<Vector2>::reference_from(_data.packed_array, p_variant._data.packed_array); |
2903 | } break; |
2904 | case PACKED_VECTOR3_ARRAY: { |
2905 | _data.packed_array = PackedArrayRef<Vector3>::reference_from(_data.packed_array, p_variant._data.packed_array); |
2906 | } break; |
2907 | case PACKED_COLOR_ARRAY: { |
2908 | _data.packed_array = PackedArrayRef<Color>::reference_from(_data.packed_array, p_variant._data.packed_array); |
2909 | } break; |
2910 | default: { |
2911 | } |
2912 | } |
2913 | } |
2914 | |
2915 | Variant::Variant(const IPAddress &p_address) { |
2916 | type = STRING; |
2917 | memnew_placement(_data._mem, String(p_address)); |
2918 | } |
2919 | |
2920 | Variant::Variant(const Variant &p_variant) { |
2921 | reference(p_variant); |
2922 | } |
2923 | |
2924 | uint32_t Variant::hash() const { |
2925 | return recursive_hash(0); |
2926 | } |
2927 | |
2928 | uint32_t Variant::recursive_hash(int recursion_count) const { |
2929 | switch (type) { |
2930 | case NIL: { |
2931 | return 0; |
2932 | } break; |
2933 | case BOOL: { |
2934 | return _data._bool ? 1 : 0; |
2935 | } break; |
2936 | case INT: { |
2937 | return hash_one_uint64((uint64_t)_data._int); |
2938 | } break; |
2939 | case FLOAT: { |
2940 | return hash_murmur3_one_double(_data._float); |
2941 | } break; |
2942 | case STRING: { |
2943 | return reinterpret_cast<const String *>(_data._mem)->hash(); |
2944 | } break; |
2945 | |
2946 | // math types |
2947 | case VECTOR2: { |
2948 | return HashMapHasherDefault::hash(*reinterpret_cast<const Vector2 *>(_data._mem)); |
2949 | } break; |
2950 | case VECTOR2I: { |
2951 | return HashMapHasherDefault::hash(*reinterpret_cast<const Vector2i *>(_data._mem)); |
2952 | } break; |
2953 | case RECT2: { |
2954 | return HashMapHasherDefault::hash(*reinterpret_cast<const Rect2 *>(_data._mem)); |
2955 | } break; |
2956 | case RECT2I: { |
2957 | return HashMapHasherDefault::hash(*reinterpret_cast<const Rect2i *>(_data._mem)); |
2958 | } break; |
2959 | case TRANSFORM2D: { |
2960 | uint32_t h = HASH_MURMUR3_SEED; |
2961 | const Transform2D &t = *_data._transform2d; |
2962 | h = hash_murmur3_one_real(t[0].x, h); |
2963 | h = hash_murmur3_one_real(t[0].y, h); |
2964 | h = hash_murmur3_one_real(t[1].x, h); |
2965 | h = hash_murmur3_one_real(t[1].y, h); |
2966 | h = hash_murmur3_one_real(t[2].x, h); |
2967 | h = hash_murmur3_one_real(t[2].y, h); |
2968 | |
2969 | return hash_fmix32(h); |
2970 | } break; |
2971 | case VECTOR3: { |
2972 | return HashMapHasherDefault::hash(*reinterpret_cast<const Vector3 *>(_data._mem)); |
2973 | } break; |
2974 | case VECTOR3I: { |
2975 | return HashMapHasherDefault::hash(*reinterpret_cast<const Vector3i *>(_data._mem)); |
2976 | } break; |
2977 | case VECTOR4: { |
2978 | return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4 *>(_data._mem)); |
2979 | } break; |
2980 | case VECTOR4I: { |
2981 | return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4i *>(_data._mem)); |
2982 | } break; |
2983 | case PLANE: { |
2984 | uint32_t h = HASH_MURMUR3_SEED; |
2985 | const Plane &p = *reinterpret_cast<const Plane *>(_data._mem); |
2986 | h = hash_murmur3_one_real(p.normal.x, h); |
2987 | h = hash_murmur3_one_real(p.normal.y, h); |
2988 | h = hash_murmur3_one_real(p.normal.z, h); |
2989 | h = hash_murmur3_one_real(p.d, h); |
2990 | return hash_fmix32(h); |
2991 | } break; |
2992 | case AABB: { |
2993 | return HashMapHasherDefault::hash(*_data._aabb); |
2994 | } break; |
2995 | case QUATERNION: { |
2996 | uint32_t h = HASH_MURMUR3_SEED; |
2997 | const Quaternion &q = *reinterpret_cast<const Quaternion *>(_data._mem); |
2998 | h = hash_murmur3_one_real(q.x, h); |
2999 | h = hash_murmur3_one_real(q.y, h); |
3000 | h = hash_murmur3_one_real(q.z, h); |
3001 | h = hash_murmur3_one_real(q.w, h); |
3002 | return hash_fmix32(h); |
3003 | } break; |
3004 | case BASIS: { |
3005 | uint32_t h = HASH_MURMUR3_SEED; |
3006 | const Basis &b = *_data._basis; |
3007 | h = hash_murmur3_one_real(b[0].x, h); |
3008 | h = hash_murmur3_one_real(b[0].y, h); |
3009 | h = hash_murmur3_one_real(b[0].z, h); |
3010 | h = hash_murmur3_one_real(b[1].x, h); |
3011 | h = hash_murmur3_one_real(b[1].y, h); |
3012 | h = hash_murmur3_one_real(b[1].z, h); |
3013 | h = hash_murmur3_one_real(b[2].x, h); |
3014 | h = hash_murmur3_one_real(b[2].y, h); |
3015 | h = hash_murmur3_one_real(b[2].z, h); |
3016 | return hash_fmix32(h); |
3017 | } break; |
3018 | case TRANSFORM3D: { |
3019 | uint32_t h = HASH_MURMUR3_SEED; |
3020 | const Transform3D &t = *_data._transform3d; |
3021 | h = hash_murmur3_one_real(t.basis[0].x, h); |
3022 | h = hash_murmur3_one_real(t.basis[0].y, h); |
3023 | h = hash_murmur3_one_real(t.basis[0].z, h); |
3024 | h = hash_murmur3_one_real(t.basis[1].x, h); |
3025 | h = hash_murmur3_one_real(t.basis[1].y, h); |
3026 | h = hash_murmur3_one_real(t.basis[1].z, h); |
3027 | h = hash_murmur3_one_real(t.basis[2].x, h); |
3028 | h = hash_murmur3_one_real(t.basis[2].y, h); |
3029 | h = hash_murmur3_one_real(t.basis[2].z, h); |
3030 | h = hash_murmur3_one_real(t.origin.x, h); |
3031 | h = hash_murmur3_one_real(t.origin.y, h); |
3032 | h = hash_murmur3_one_real(t.origin.z, h); |
3033 | return hash_fmix32(h); |
3034 | } break; |
3035 | case PROJECTION: { |
3036 | uint32_t h = HASH_MURMUR3_SEED; |
3037 | const Projection &t = *_data._projection; |
3038 | h = hash_murmur3_one_real(t.columns[0].x, h); |
3039 | h = hash_murmur3_one_real(t.columns[0].y, h); |
3040 | h = hash_murmur3_one_real(t.columns[0].z, h); |
3041 | h = hash_murmur3_one_real(t.columns[0].w, h); |
3042 | h = hash_murmur3_one_real(t.columns[1].x, h); |
3043 | h = hash_murmur3_one_real(t.columns[1].y, h); |
3044 | h = hash_murmur3_one_real(t.columns[1].z, h); |
3045 | h = hash_murmur3_one_real(t.columns[1].w, h); |
3046 | h = hash_murmur3_one_real(t.columns[2].x, h); |
3047 | h = hash_murmur3_one_real(t.columns[2].y, h); |
3048 | h = hash_murmur3_one_real(t.columns[2].z, h); |
3049 | h = hash_murmur3_one_real(t.columns[2].w, h); |
3050 | h = hash_murmur3_one_real(t.columns[3].x, h); |
3051 | h = hash_murmur3_one_real(t.columns[3].y, h); |
3052 | h = hash_murmur3_one_real(t.columns[3].z, h); |
3053 | h = hash_murmur3_one_real(t.columns[3].w, h); |
3054 | return hash_fmix32(h); |
3055 | } break; |
3056 | // misc types |
3057 | case COLOR: { |
3058 | uint32_t h = HASH_MURMUR3_SEED; |
3059 | const Color &c = *reinterpret_cast<const Color *>(_data._mem); |
3060 | h = hash_murmur3_one_float(c.r, h); |
3061 | h = hash_murmur3_one_float(c.g, h); |
3062 | h = hash_murmur3_one_float(c.b, h); |
3063 | h = hash_murmur3_one_float(c.a, h); |
3064 | return hash_fmix32(h); |
3065 | } break; |
3066 | case RID: { |
3067 | return hash_one_uint64(reinterpret_cast<const ::RID *>(_data._mem)->get_id()); |
3068 | } break; |
3069 | case OBJECT: { |
3070 | return hash_one_uint64(hash_make_uint64_t(_get_obj().obj)); |
3071 | } break; |
3072 | case STRING_NAME: { |
3073 | return reinterpret_cast<const StringName *>(_data._mem)->hash(); |
3074 | } break; |
3075 | case NODE_PATH: { |
3076 | return reinterpret_cast<const NodePath *>(_data._mem)->hash(); |
3077 | } break; |
3078 | case DICTIONARY: { |
3079 | return reinterpret_cast<const Dictionary *>(_data._mem)->recursive_hash(recursion_count); |
3080 | |
3081 | } break; |
3082 | case CALLABLE: { |
3083 | return reinterpret_cast<const Callable *>(_data._mem)->hash(); |
3084 | |
3085 | } break; |
3086 | case SIGNAL: { |
3087 | const Signal &s = *reinterpret_cast<const Signal *>(_data._mem); |
3088 | uint32_t hash = s.get_name().hash(); |
3089 | return hash_murmur3_one_64(s.get_object_id(), hash); |
3090 | } break; |
3091 | case ARRAY: { |
3092 | const Array &arr = *reinterpret_cast<const Array *>(_data._mem); |
3093 | return arr.recursive_hash(recursion_count); |
3094 | |
3095 | } break; |
3096 | case PACKED_BYTE_ARRAY: { |
3097 | const Vector<uint8_t> &arr = PackedArrayRef<uint8_t>::get_array(_data.packed_array); |
3098 | int len = arr.size(); |
3099 | if (likely(len)) { |
3100 | const uint8_t *r = arr.ptr(); |
3101 | return hash_murmur3_buffer((uint8_t *)&r[0], len); |
3102 | } else { |
3103 | return hash_murmur3_one_64(0); |
3104 | } |
3105 | |
3106 | } break; |
3107 | case PACKED_INT32_ARRAY: { |
3108 | const Vector<int32_t> &arr = PackedArrayRef<int32_t>::get_array(_data.packed_array); |
3109 | int len = arr.size(); |
3110 | if (likely(len)) { |
3111 | const int32_t *r = arr.ptr(); |
3112 | return hash_murmur3_buffer((uint8_t *)&r[0], len * sizeof(int32_t)); |
3113 | } else { |
3114 | return hash_murmur3_one_64(0); |
3115 | } |
3116 | |
3117 | } break; |
3118 | case PACKED_INT64_ARRAY: { |
3119 | const Vector<int64_t> &arr = PackedArrayRef<int64_t>::get_array(_data.packed_array); |
3120 | int len = arr.size(); |
3121 | if (likely(len)) { |
3122 | const int64_t *r = arr.ptr(); |
3123 | return hash_murmur3_buffer((uint8_t *)&r[0], len * sizeof(int64_t)); |
3124 | } else { |
3125 | return hash_murmur3_one_64(0); |
3126 | } |
3127 | |
3128 | } break; |
3129 | case PACKED_FLOAT32_ARRAY: { |
3130 | const Vector<float> &arr = PackedArrayRef<float>::get_array(_data.packed_array); |
3131 | int len = arr.size(); |
3132 | |
3133 | if (likely(len)) { |
3134 | const float *r = arr.ptr(); |
3135 | uint32_t h = HASH_MURMUR3_SEED; |
3136 | for (int32_t i = 0; i < len; i++) { |
3137 | h = hash_murmur3_one_float(r[i], h); |
3138 | } |
3139 | return hash_fmix32(h); |
3140 | } else { |
3141 | return hash_murmur3_one_float(0.0); |
3142 | } |
3143 | |
3144 | } break; |
3145 | case PACKED_FLOAT64_ARRAY: { |
3146 | const Vector<double> &arr = PackedArrayRef<double>::get_array(_data.packed_array); |
3147 | int len = arr.size(); |
3148 | |
3149 | if (likely(len)) { |
3150 | const double *r = arr.ptr(); |
3151 | uint32_t h = HASH_MURMUR3_SEED; |
3152 | for (int32_t i = 0; i < len; i++) { |
3153 | h = hash_murmur3_one_double(r[i], h); |
3154 | } |
3155 | return hash_fmix32(h); |
3156 | } else { |
3157 | return hash_murmur3_one_double(0.0); |
3158 | } |
3159 | |
3160 | } break; |
3161 | case PACKED_STRING_ARRAY: { |
3162 | uint32_t hash = HASH_MURMUR3_SEED; |
3163 | const Vector<String> &arr = PackedArrayRef<String>::get_array(_data.packed_array); |
3164 | int len = arr.size(); |
3165 | |
3166 | if (likely(len)) { |
3167 | const String *r = arr.ptr(); |
3168 | |
3169 | for (int i = 0; i < len; i++) { |
3170 | hash = hash_murmur3_one_32(r[i].hash(), hash); |
3171 | } |
3172 | hash = hash_fmix32(hash); |
3173 | } |
3174 | |
3175 | return hash; |
3176 | } break; |
3177 | case PACKED_VECTOR2_ARRAY: { |
3178 | uint32_t hash = HASH_MURMUR3_SEED; |
3179 | const Vector<Vector2> &arr = PackedArrayRef<Vector2>::get_array(_data.packed_array); |
3180 | int len = arr.size(); |
3181 | |
3182 | if (likely(len)) { |
3183 | const Vector2 *r = arr.ptr(); |
3184 | |
3185 | for (int i = 0; i < len; i++) { |
3186 | hash = hash_murmur3_one_real(r[i].x, hash); |
3187 | hash = hash_murmur3_one_real(r[i].y, hash); |
3188 | } |
3189 | hash = hash_fmix32(hash); |
3190 | } |
3191 | |
3192 | return hash; |
3193 | } break; |
3194 | case PACKED_VECTOR3_ARRAY: { |
3195 | uint32_t hash = HASH_MURMUR3_SEED; |
3196 | const Vector<Vector3> &arr = PackedArrayRef<Vector3>::get_array(_data.packed_array); |
3197 | int len = arr.size(); |
3198 | |
3199 | if (likely(len)) { |
3200 | const Vector3 *r = arr.ptr(); |
3201 | |
3202 | for (int i = 0; i < len; i++) { |
3203 | hash = hash_murmur3_one_real(r[i].x, hash); |
3204 | hash = hash_murmur3_one_real(r[i].y, hash); |
3205 | hash = hash_murmur3_one_real(r[i].z, hash); |
3206 | } |
3207 | hash = hash_fmix32(hash); |
3208 | } |
3209 | |
3210 | return hash; |
3211 | } break; |
3212 | case PACKED_COLOR_ARRAY: { |
3213 | uint32_t hash = HASH_MURMUR3_SEED; |
3214 | const Vector<Color> &arr = PackedArrayRef<Color>::get_array(_data.packed_array); |
3215 | int len = arr.size(); |
3216 | |
3217 | if (likely(len)) { |
3218 | const Color *r = arr.ptr(); |
3219 | |
3220 | for (int i = 0; i < len; i++) { |
3221 | hash = hash_murmur3_one_float(r[i].r, hash); |
3222 | hash = hash_murmur3_one_float(r[i].g, hash); |
3223 | hash = hash_murmur3_one_float(r[i].b, hash); |
3224 | hash = hash_murmur3_one_float(r[i].a, hash); |
3225 | } |
3226 | hash = hash_fmix32(hash); |
3227 | } |
3228 | |
3229 | return hash; |
3230 | } break; |
3231 | default: { |
3232 | } |
3233 | } |
3234 | |
3235 | return 0; |
3236 | } |
3237 | |
3238 | #define hash_compare_scalar(p_lhs, p_rhs) \ |
3239 | (((p_lhs) == (p_rhs)) || (Math::is_nan(p_lhs) && Math::is_nan(p_rhs))) |
3240 | |
3241 | #define hash_compare_vector2(p_lhs, p_rhs) \ |
3242 | (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ |
3243 | hash_compare_scalar((p_lhs).y, (p_rhs).y)) |
3244 | |
3245 | #define hash_compare_vector3(p_lhs, p_rhs) \ |
3246 | (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ |
3247 | hash_compare_scalar((p_lhs).y, (p_rhs).y) && \ |
3248 | hash_compare_scalar((p_lhs).z, (p_rhs).z)) |
3249 | |
3250 | #define hash_compare_vector4(p_lhs, p_rhs) \ |
3251 | (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ |
3252 | hash_compare_scalar((p_lhs).y, (p_rhs).y) && \ |
3253 | hash_compare_scalar((p_lhs).z, (p_rhs).z) && \ |
3254 | hash_compare_scalar((p_lhs).w, (p_rhs).w)) |
3255 | |
3256 | #define hash_compare_quaternion(p_lhs, p_rhs) \ |
3257 | (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ |
3258 | hash_compare_scalar((p_lhs).y, (p_rhs).y) && \ |
3259 | hash_compare_scalar((p_lhs).z, (p_rhs).z) && \ |
3260 | hash_compare_scalar((p_lhs).w, (p_rhs).w)) |
3261 | |
3262 | #define hash_compare_color(p_lhs, p_rhs) \ |
3263 | (hash_compare_scalar((p_lhs).r, (p_rhs).r) && \ |
3264 | hash_compare_scalar((p_lhs).g, (p_rhs).g) && \ |
3265 | hash_compare_scalar((p_lhs).b, (p_rhs).b) && \ |
3266 | hash_compare_scalar((p_lhs).a, (p_rhs).a)) |
3267 | |
3268 | #define hash_compare_packed_array(p_lhs, p_rhs, p_type, p_compare_func) \ |
3269 | const Vector<p_type> &l = PackedArrayRef<p_type>::get_array(p_lhs); \ |
3270 | const Vector<p_type> &r = PackedArrayRef<p_type>::get_array(p_rhs); \ |
3271 | \ |
3272 | if (l.size() != r.size()) \ |
3273 | return false; \ |
3274 | \ |
3275 | const p_type *lr = l.ptr(); \ |
3276 | const p_type *rr = r.ptr(); \ |
3277 | \ |
3278 | for (int i = 0; i < l.size(); ++i) { \ |
3279 | if (!p_compare_func((lr[i]), (rr[i]))) \ |
3280 | return false; \ |
3281 | } \ |
3282 | \ |
3283 | return true |
3284 | |
3285 | bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const { |
3286 | if (type != p_variant.type) { |
3287 | return false; |
3288 | } |
3289 | |
3290 | switch (type) { |
3291 | case INT: { |
3292 | return _data._int == p_variant._data._int; |
3293 | } break; |
3294 | |
3295 | case FLOAT: { |
3296 | return hash_compare_scalar(_data._float, p_variant._data._float); |
3297 | } break; |
3298 | |
3299 | case STRING: { |
3300 | return *reinterpret_cast<const String *>(_data._mem) == *reinterpret_cast<const String *>(p_variant._data._mem); |
3301 | } break; |
3302 | |
3303 | case STRING_NAME: { |
3304 | return *reinterpret_cast<const StringName *>(_data._mem) == *reinterpret_cast<const StringName *>(p_variant._data._mem); |
3305 | } break; |
3306 | |
3307 | case VECTOR2: { |
3308 | const Vector2 *l = reinterpret_cast<const Vector2 *>(_data._mem); |
3309 | const Vector2 *r = reinterpret_cast<const Vector2 *>(p_variant._data._mem); |
3310 | |
3311 | return hash_compare_vector2(*l, *r); |
3312 | } break; |
3313 | case VECTOR2I: { |
3314 | const Vector2i *l = reinterpret_cast<const Vector2i *>(_data._mem); |
3315 | const Vector2i *r = reinterpret_cast<const Vector2i *>(p_variant._data._mem); |
3316 | return *l == *r; |
3317 | } break; |
3318 | |
3319 | case RECT2: { |
3320 | const Rect2 *l = reinterpret_cast<const Rect2 *>(_data._mem); |
3321 | const Rect2 *r = reinterpret_cast<const Rect2 *>(p_variant._data._mem); |
3322 | |
3323 | return hash_compare_vector2(l->position, r->position) && |
3324 | hash_compare_vector2(l->size, r->size); |
3325 | } break; |
3326 | case RECT2I: { |
3327 | const Rect2i *l = reinterpret_cast<const Rect2i *>(_data._mem); |
3328 | const Rect2i *r = reinterpret_cast<const Rect2i *>(p_variant._data._mem); |
3329 | |
3330 | return *l == *r; |
3331 | } break; |
3332 | |
3333 | case TRANSFORM2D: { |
3334 | Transform2D *l = _data._transform2d; |
3335 | Transform2D *r = p_variant._data._transform2d; |
3336 | |
3337 | for (int i = 0; i < 3; i++) { |
3338 | if (!hash_compare_vector2(l->columns[i], r->columns[i])) { |
3339 | return false; |
3340 | } |
3341 | } |
3342 | |
3343 | return true; |
3344 | } break; |
3345 | |
3346 | case VECTOR3: { |
3347 | const Vector3 *l = reinterpret_cast<const Vector3 *>(_data._mem); |
3348 | const Vector3 *r = reinterpret_cast<const Vector3 *>(p_variant._data._mem); |
3349 | |
3350 | return hash_compare_vector3(*l, *r); |
3351 | } break; |
3352 | case VECTOR3I: { |
3353 | const Vector3i *l = reinterpret_cast<const Vector3i *>(_data._mem); |
3354 | const Vector3i *r = reinterpret_cast<const Vector3i *>(p_variant._data._mem); |
3355 | |
3356 | return *l == *r; |
3357 | } break; |
3358 | case VECTOR4: { |
3359 | const Vector4 *l = reinterpret_cast<const Vector4 *>(_data._mem); |
3360 | const Vector4 *r = reinterpret_cast<const Vector4 *>(p_variant._data._mem); |
3361 | |
3362 | return hash_compare_vector4(*l, *r); |
3363 | } break; |
3364 | case VECTOR4I: { |
3365 | const Vector4i *l = reinterpret_cast<const Vector4i *>(_data._mem); |
3366 | const Vector4i *r = reinterpret_cast<const Vector4i *>(p_variant._data._mem); |
3367 | |
3368 | return *l == *r; |
3369 | } break; |
3370 | |
3371 | case PLANE: { |
3372 | const Plane *l = reinterpret_cast<const Plane *>(_data._mem); |
3373 | const Plane *r = reinterpret_cast<const Plane *>(p_variant._data._mem); |
3374 | |
3375 | return hash_compare_vector3(l->normal, r->normal) && |
3376 | hash_compare_scalar(l->d, r->d); |
3377 | } break; |
3378 | |
3379 | case AABB: { |
3380 | const ::AABB *l = _data._aabb; |
3381 | const ::AABB *r = p_variant._data._aabb; |
3382 | |
3383 | return hash_compare_vector3(l->position, r->position) && |
3384 | hash_compare_vector3(l->size, r->size); |
3385 | |
3386 | } break; |
3387 | |
3388 | case QUATERNION: { |
3389 | const Quaternion *l = reinterpret_cast<const Quaternion *>(_data._mem); |
3390 | const Quaternion *r = reinterpret_cast<const Quaternion *>(p_variant._data._mem); |
3391 | |
3392 | return hash_compare_quaternion(*l, *r); |
3393 | } break; |
3394 | |
3395 | case BASIS: { |
3396 | const Basis *l = _data._basis; |
3397 | const Basis *r = p_variant._data._basis; |
3398 | |
3399 | for (int i = 0; i < 3; i++) { |
3400 | if (!hash_compare_vector3(l->rows[i], r->rows[i])) { |
3401 | return false; |
3402 | } |
3403 | } |
3404 | |
3405 | return true; |
3406 | } break; |
3407 | |
3408 | case TRANSFORM3D: { |
3409 | const Transform3D *l = _data._transform3d; |
3410 | const Transform3D *r = p_variant._data._transform3d; |
3411 | |
3412 | for (int i = 0; i < 3; i++) { |
3413 | if (!hash_compare_vector3(l->basis.rows[i], r->basis.rows[i])) { |
3414 | return false; |
3415 | } |
3416 | } |
3417 | |
3418 | return hash_compare_vector3(l->origin, r->origin); |
3419 | } break; |
3420 | case PROJECTION: { |
3421 | const Projection *l = _data._projection; |
3422 | const Projection *r = p_variant._data._projection; |
3423 | |
3424 | for (int i = 0; i < 4; i++) { |
3425 | if (!hash_compare_vector4(l->columns[i], r->columns[i])) { |
3426 | return false; |
3427 | } |
3428 | } |
3429 | |
3430 | return true; |
3431 | } break; |
3432 | |
3433 | case COLOR: { |
3434 | const Color *l = reinterpret_cast<const Color *>(_data._mem); |
3435 | const Color *r = reinterpret_cast<const Color *>(p_variant._data._mem); |
3436 | |
3437 | return hash_compare_color(*l, *r); |
3438 | } break; |
3439 | |
3440 | case ARRAY: { |
3441 | const Array &l = *(reinterpret_cast<const Array *>(_data._mem)); |
3442 | const Array &r = *(reinterpret_cast<const Array *>(p_variant._data._mem)); |
3443 | |
3444 | if (!l.recursive_equal(r, recursion_count + 1)) { |
3445 | return false; |
3446 | } |
3447 | |
3448 | return true; |
3449 | } break; |
3450 | |
3451 | case DICTIONARY: { |
3452 | const Dictionary &l = *(reinterpret_cast<const Dictionary *>(_data._mem)); |
3453 | const Dictionary &r = *(reinterpret_cast<const Dictionary *>(p_variant._data._mem)); |
3454 | |
3455 | if (!l.recursive_equal(r, recursion_count + 1)) { |
3456 | return false; |
3457 | } |
3458 | |
3459 | return true; |
3460 | } break; |
3461 | |
3462 | // This is for floating point comparisons only. |
3463 | case PACKED_FLOAT32_ARRAY: { |
3464 | hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, float, hash_compare_scalar); |
3465 | } break; |
3466 | |
3467 | case PACKED_FLOAT64_ARRAY: { |
3468 | hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, double, hash_compare_scalar); |
3469 | } break; |
3470 | |
3471 | case PACKED_VECTOR2_ARRAY: { |
3472 | hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, Vector2, hash_compare_vector2); |
3473 | } break; |
3474 | |
3475 | case PACKED_VECTOR3_ARRAY: { |
3476 | hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, Vector3, hash_compare_vector3); |
3477 | } break; |
3478 | |
3479 | case PACKED_COLOR_ARRAY: { |
3480 | hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, Color, hash_compare_color); |
3481 | } break; |
3482 | |
3483 | default: |
3484 | bool v; |
3485 | Variant r; |
3486 | evaluate(OP_EQUAL, *this, p_variant, r, v); |
3487 | return r; |
3488 | } |
3489 | } |
3490 | |
3491 | bool Variant::identity_compare(const Variant &p_variant) const { |
3492 | if (type != p_variant.type) { |
3493 | return false; |
3494 | } |
3495 | |
3496 | switch (type) { |
3497 | case OBJECT: { |
3498 | return _get_obj().id == p_variant._get_obj().id; |
3499 | } break; |
3500 | |
3501 | case DICTIONARY: { |
3502 | const Dictionary &l = *(reinterpret_cast<const Dictionary *>(_data._mem)); |
3503 | const Dictionary &r = *(reinterpret_cast<const Dictionary *>(p_variant._data._mem)); |
3504 | return l.id() == r.id(); |
3505 | } break; |
3506 | |
3507 | case ARRAY: { |
3508 | const Array &l = *(reinterpret_cast<const Array *>(_data._mem)); |
3509 | const Array &r = *(reinterpret_cast<const Array *>(p_variant._data._mem)); |
3510 | return l.id() == r.id(); |
3511 | } break; |
3512 | |
3513 | case PACKED_BYTE_ARRAY: |
3514 | case PACKED_INT32_ARRAY: |
3515 | case PACKED_INT64_ARRAY: |
3516 | case PACKED_FLOAT32_ARRAY: |
3517 | case PACKED_FLOAT64_ARRAY: |
3518 | case PACKED_STRING_ARRAY: |
3519 | case PACKED_VECTOR2_ARRAY: |
3520 | case PACKED_VECTOR3_ARRAY: |
3521 | case PACKED_COLOR_ARRAY: { |
3522 | return _data.packed_array == p_variant._data.packed_array; |
3523 | } break; |
3524 | |
3525 | default: { |
3526 | return hash_compare(p_variant); |
3527 | } |
3528 | } |
3529 | } |
3530 | |
3531 | bool StringLikeVariantComparator::compare(const Variant &p_lhs, const Variant &p_rhs) { |
3532 | if (p_lhs.hash_compare(p_rhs)) { |
3533 | return true; |
3534 | } |
3535 | if (p_lhs.get_type() == Variant::STRING && p_rhs.get_type() == Variant::STRING_NAME) { |
3536 | return *VariantInternal::get_string(&p_lhs) == *VariantInternal::get_string_name(&p_rhs); |
3537 | } |
3538 | if (p_lhs.get_type() == Variant::STRING_NAME && p_rhs.get_type() == Variant::STRING) { |
3539 | return *VariantInternal::get_string_name(&p_lhs) == *VariantInternal::get_string(&p_rhs); |
3540 | } |
3541 | return false; |
3542 | } |
3543 | |
3544 | bool Variant::is_ref_counted() const { |
3545 | return type == OBJECT && _get_obj().id.is_ref_counted(); |
3546 | } |
3547 | |
3548 | Vector<Variant> varray() { |
3549 | return Vector<Variant>(); |
3550 | } |
3551 | |
3552 | Vector<Variant> varray(const Variant &p_arg1) { |
3553 | Vector<Variant> v; |
3554 | v.push_back(p_arg1); |
3555 | return v; |
3556 | } |
3557 | |
3558 | Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2) { |
3559 | Vector<Variant> v; |
3560 | v.push_back(p_arg1); |
3561 | v.push_back(p_arg2); |
3562 | return v; |
3563 | } |
3564 | |
3565 | Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3) { |
3566 | Vector<Variant> v; |
3567 | v.push_back(p_arg1); |
3568 | v.push_back(p_arg2); |
3569 | v.push_back(p_arg3); |
3570 | return v; |
3571 | } |
3572 | |
3573 | Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4) { |
3574 | Vector<Variant> v; |
3575 | v.push_back(p_arg1); |
3576 | v.push_back(p_arg2); |
3577 | v.push_back(p_arg3); |
3578 | v.push_back(p_arg4); |
3579 | return v; |
3580 | } |
3581 | |
3582 | Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5) { |
3583 | Vector<Variant> v; |
3584 | v.push_back(p_arg1); |
3585 | v.push_back(p_arg2); |
3586 | v.push_back(p_arg3); |
3587 | v.push_back(p_arg4); |
3588 | v.push_back(p_arg5); |
3589 | return v; |
3590 | } |
3591 | |
3592 | void Variant::static_assign(const Variant &p_variant) { |
3593 | } |
3594 | |
3595 | bool Variant::is_type_shared(Variant::Type p_type) { |
3596 | switch (p_type) { |
3597 | case OBJECT: |
3598 | case ARRAY: |
3599 | case DICTIONARY: |
3600 | return true; |
3601 | default: { |
3602 | } |
3603 | } |
3604 | |
3605 | return false; |
3606 | } |
3607 | |
3608 | bool Variant::is_shared() const { |
3609 | return is_type_shared(type); |
3610 | } |
3611 | |
3612 | void Variant::_variant_call_error(const String &p_method, Callable::CallError &error) { |
3613 | switch (error.error) { |
3614 | case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: { |
3615 | String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(Variant::Type(error.expected)) + "'." ; |
3616 | ERR_PRINT(err.utf8().get_data()); |
3617 | |
3618 | } break; |
3619 | case Callable::CallError::CALL_ERROR_INVALID_METHOD: { |
3620 | String err = "Invalid method '" + p_method + "' for type '" + Variant::get_type_name(type) + "'." ; |
3621 | ERR_PRINT(err.utf8().get_data()); |
3622 | } break; |
3623 | case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: { |
3624 | String err = "Too many arguments for method '" + p_method + "'" ; |
3625 | ERR_PRINT(err.utf8().get_data()); |
3626 | } break; |
3627 | default: { |
3628 | } |
3629 | } |
3630 | } |
3631 | |
3632 | void Variant::construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct, void *p_construct_ud) { |
3633 | r_value = Variant(); |
3634 | } |
3635 | |
3636 | String Variant::get_construct_string() const { |
3637 | String vars; |
3638 | VariantWriter::write_to_string(*this, vars); |
3639 | |
3640 | return vars; |
3641 | } |
3642 | |
3643 | String Variant::get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { |
3644 | return get_call_error_text(nullptr, p_method, p_argptrs, p_argcount, ce); |
3645 | } |
3646 | |
3647 | String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { |
3648 | String err_text; |
3649 | |
3650 | if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { |
3651 | int errorarg = ce.argument; |
3652 | if (p_argptrs) { |
3653 | err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)); |
3654 | } else { |
3655 | err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)); |
3656 | } |
3657 | } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { |
3658 | err_text = "Method expected " + itos(ce.expected) + " arguments, but called with " + itos(p_argcount); |
3659 | } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { |
3660 | err_text = "Method expected " + itos(ce.expected) + " arguments, but called with " + itos(p_argcount); |
3661 | } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { |
3662 | err_text = "Method not found" ; |
3663 | } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { |
3664 | err_text = "Instance is null" ; |
3665 | } else if (ce.error == Callable::CallError::CALL_ERROR_METHOD_NOT_CONST) { |
3666 | err_text = "Method not const in const instance" ; |
3667 | } else if (ce.error == Callable::CallError::CALL_OK) { |
3668 | return "Call OK" ; |
3669 | } |
3670 | |
3671 | String base_text; |
3672 | if (p_base) { |
3673 | base_text = p_base->get_class(); |
3674 | Ref<Resource> script = p_base->get_script(); |
3675 | if (script.is_valid() && script->get_path().is_resource_file()) { |
3676 | base_text += "(" + script->get_path().get_file() + ")" ; |
3677 | } |
3678 | base_text += "::" ; |
3679 | } |
3680 | return "'" + base_text + String(p_method) + "': " + err_text; |
3681 | } |
3682 | |
3683 | String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { |
3684 | Vector<Variant> binds; |
3685 | int args_bound; |
3686 | p_callable.get_bound_arguments_ref(binds, args_bound); |
3687 | if (args_bound <= 0) { |
3688 | return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, MAX(0, p_argcount + args_bound), ce); |
3689 | } else { |
3690 | Vector<const Variant *> argptrs; |
3691 | argptrs.resize(p_argcount + binds.size()); |
3692 | for (int i = 0; i < p_argcount; i++) { |
3693 | argptrs.write[i] = p_argptrs[i]; |
3694 | } |
3695 | for (int i = 0; i < binds.size(); i++) { |
3696 | argptrs.write[i + p_argcount] = &binds[i]; |
3697 | } |
3698 | return get_call_error_text(p_callable.get_object(), p_callable.get_method(), (const Variant **)argptrs.ptr(), argptrs.size(), ce); |
3699 | } |
3700 | } |
3701 | |
3702 | void Variant::register_types() { |
3703 | _register_variant_operators(); |
3704 | _register_variant_methods(); |
3705 | _register_variant_setters_getters(); |
3706 | _register_variant_constructors(); |
3707 | _register_variant_destructors(); |
3708 | _register_variant_utility_functions(); |
3709 | } |
3710 | void Variant::unregister_types() { |
3711 | _unregister_variant_operators(); |
3712 | _unregister_variant_methods(); |
3713 | _unregister_variant_setters_getters(); |
3714 | _unregister_variant_destructors(); |
3715 | _unregister_variant_utility_functions(); |
3716 | } |
3717 | |