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