Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/variant/variant_setget.cpp
9903 views
1
/**************************************************************************/
2
/* variant_setget.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "variant_setget.h"
32
#include "variant_callable.h"
33
34
#include "core/io/resource.h"
35
36
struct VariantSetterGetterInfo {
37
void (*setter)(Variant *base, const Variant *value, bool &valid);
38
void (*getter)(const Variant *base, Variant *value);
39
Variant::ValidatedSetter validated_setter;
40
Variant::ValidatedGetter validated_getter;
41
Variant::PTRSetter ptr_setter;
42
Variant::PTRGetter ptr_getter;
43
Variant::Type member_type;
44
};
45
46
static LocalVector<VariantSetterGetterInfo> variant_setters_getters[Variant::VARIANT_MAX];
47
static LocalVector<StringName> variant_setters_getters_names[Variant::VARIANT_MAX]; //one next to another to make it cache friendly
48
49
template <typename T>
50
static void register_member(Variant::Type p_type, const StringName &p_member) {
51
VariantSetterGetterInfo sgi;
52
sgi.setter = T::set;
53
sgi.validated_setter = T::validated_set;
54
sgi.ptr_setter = T::ptr_set;
55
56
sgi.getter = T::get;
57
sgi.validated_getter = T::validated_get;
58
sgi.ptr_getter = T::ptr_get;
59
60
sgi.member_type = T::get_type();
61
62
variant_setters_getters[p_type].push_back(sgi);
63
variant_setters_getters_names[p_type].push_back(p_member);
64
}
65
66
void register_named_setters_getters() {
67
#define REGISTER_MEMBER(m_base_type, m_member) register_member<VariantSetGet_##m_base_type##_##m_member>(GetTypeInfo<m_base_type>::VARIANT_TYPE, #m_member)
68
69
REGISTER_MEMBER(Vector2, x);
70
REGISTER_MEMBER(Vector2, y);
71
72
REGISTER_MEMBER(Vector2i, x);
73
REGISTER_MEMBER(Vector2i, y);
74
75
REGISTER_MEMBER(Vector3, x);
76
REGISTER_MEMBER(Vector3, y);
77
REGISTER_MEMBER(Vector3, z);
78
79
REGISTER_MEMBER(Vector3i, x);
80
REGISTER_MEMBER(Vector3i, y);
81
REGISTER_MEMBER(Vector3i, z);
82
83
REGISTER_MEMBER(Vector4, x);
84
REGISTER_MEMBER(Vector4, y);
85
REGISTER_MEMBER(Vector4, z);
86
REGISTER_MEMBER(Vector4, w);
87
88
REGISTER_MEMBER(Vector4i, x);
89
REGISTER_MEMBER(Vector4i, y);
90
REGISTER_MEMBER(Vector4i, z);
91
REGISTER_MEMBER(Vector4i, w);
92
93
REGISTER_MEMBER(Rect2, position);
94
REGISTER_MEMBER(Rect2, size);
95
REGISTER_MEMBER(Rect2, end);
96
97
REGISTER_MEMBER(Rect2i, position);
98
REGISTER_MEMBER(Rect2i, size);
99
REGISTER_MEMBER(Rect2i, end);
100
101
REGISTER_MEMBER(AABB, position);
102
REGISTER_MEMBER(AABB, size);
103
REGISTER_MEMBER(AABB, end);
104
105
REGISTER_MEMBER(Transform2D, x);
106
REGISTER_MEMBER(Transform2D, y);
107
REGISTER_MEMBER(Transform2D, origin);
108
109
REGISTER_MEMBER(Plane, x);
110
REGISTER_MEMBER(Plane, y);
111
REGISTER_MEMBER(Plane, z);
112
REGISTER_MEMBER(Plane, d);
113
REGISTER_MEMBER(Plane, normal);
114
115
REGISTER_MEMBER(Quaternion, x);
116
REGISTER_MEMBER(Quaternion, y);
117
REGISTER_MEMBER(Quaternion, z);
118
REGISTER_MEMBER(Quaternion, w);
119
120
REGISTER_MEMBER(Basis, x);
121
REGISTER_MEMBER(Basis, y);
122
REGISTER_MEMBER(Basis, z);
123
124
REGISTER_MEMBER(Transform3D, basis);
125
REGISTER_MEMBER(Transform3D, origin);
126
127
REGISTER_MEMBER(Projection, x);
128
REGISTER_MEMBER(Projection, y);
129
REGISTER_MEMBER(Projection, z);
130
REGISTER_MEMBER(Projection, w);
131
132
REGISTER_MEMBER(Color, r);
133
REGISTER_MEMBER(Color, g);
134
REGISTER_MEMBER(Color, b);
135
REGISTER_MEMBER(Color, a);
136
137
REGISTER_MEMBER(Color, r8);
138
REGISTER_MEMBER(Color, g8);
139
REGISTER_MEMBER(Color, b8);
140
REGISTER_MEMBER(Color, a8);
141
142
REGISTER_MEMBER(Color, h);
143
REGISTER_MEMBER(Color, s);
144
REGISTER_MEMBER(Color, v);
145
146
REGISTER_MEMBER(Color, ok_hsl_h);
147
REGISTER_MEMBER(Color, ok_hsl_s);
148
REGISTER_MEMBER(Color, ok_hsl_l);
149
}
150
151
void unregister_named_setters_getters() {
152
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
153
variant_setters_getters[i].clear();
154
variant_setters_getters_names[i].clear();
155
}
156
}
157
158
bool Variant::has_member(Variant::Type p_type, const StringName &p_member) {
159
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false);
160
161
for (const StringName &member : variant_setters_getters_names[p_type]) {
162
if (member == p_member) {
163
return true;
164
}
165
}
166
return false;
167
}
168
169
Variant::Type Variant::get_member_type(Variant::Type p_type, const StringName &p_member) {
170
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::VARIANT_MAX);
171
172
for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) {
173
if (variant_setters_getters_names[p_type][i] == p_member) {
174
return variant_setters_getters[p_type][i].member_type;
175
}
176
}
177
178
return Variant::NIL;
179
}
180
181
void Variant::get_member_list(Variant::Type p_type, List<StringName> *r_members) {
182
for (const StringName &member : variant_setters_getters_names[p_type]) {
183
r_members->push_back(member);
184
}
185
}
186
187
int Variant::get_member_count(Type p_type) {
188
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1);
189
return variant_setters_getters_names[p_type].size();
190
}
191
192
Variant::ValidatedSetter Variant::get_member_validated_setter(Variant::Type p_type, const StringName &p_member) {
193
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
194
195
for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) {
196
if (variant_setters_getters_names[p_type][i] == p_member) {
197
return variant_setters_getters[p_type][i].validated_setter;
198
}
199
}
200
201
return nullptr;
202
}
203
Variant::ValidatedGetter Variant::get_member_validated_getter(Variant::Type p_type, const StringName &p_member) {
204
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
205
206
for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) {
207
if (variant_setters_getters_names[p_type][i] == p_member) {
208
return variant_setters_getters[p_type][i].validated_getter;
209
}
210
}
211
212
return nullptr;
213
}
214
215
Variant::PTRSetter Variant::get_member_ptr_setter(Variant::Type p_type, const StringName &p_member) {
216
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
217
218
for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) {
219
if (variant_setters_getters_names[p_type][i] == p_member) {
220
return variant_setters_getters[p_type][i].ptr_setter;
221
}
222
}
223
224
return nullptr;
225
}
226
227
Variant::PTRGetter Variant::get_member_ptr_getter(Variant::Type p_type, const StringName &p_member) {
228
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
229
230
for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) {
231
if (variant_setters_getters_names[p_type][i] == p_member) {
232
return variant_setters_getters[p_type][i].ptr_getter;
233
}
234
}
235
236
return nullptr;
237
}
238
239
void Variant::set_named(const StringName &p_member, const Variant &p_value, bool &r_valid) {
240
uint32_t s = variant_setters_getters[type].size();
241
if (s) {
242
for (uint32_t i = 0; i < s; i++) {
243
if (variant_setters_getters_names[type][i] == p_member) {
244
variant_setters_getters[type][i].setter(this, &p_value, r_valid);
245
return;
246
}
247
}
248
r_valid = false;
249
250
} else if (type == Variant::OBJECT) {
251
Object *obj = get_validated_object();
252
if (!obj) {
253
r_valid = false;
254
} else {
255
obj->set(p_member, p_value, &r_valid);
256
return;
257
}
258
} else if (type == Variant::DICTIONARY) {
259
Dictionary &dict = *VariantGetInternalPtr<Dictionary>::get_ptr(this);
260
r_valid = dict.set(p_member, p_value);
261
} else {
262
r_valid = false;
263
}
264
}
265
266
Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
267
uint32_t s = variant_setters_getters[type].size();
268
if (s) {
269
for (uint32_t i = 0; i < s; i++) {
270
if (variant_setters_getters_names[type][i] == p_member) {
271
Variant ret;
272
variant_setters_getters[type][i].getter(this, &ret);
273
r_valid = true;
274
return ret;
275
}
276
}
277
}
278
279
switch (type) {
280
case Variant::OBJECT: {
281
Object *obj = get_validated_object();
282
if (!obj) {
283
r_valid = false;
284
return "Instance base is null.";
285
} else {
286
return obj->get(p_member, &r_valid);
287
}
288
} break;
289
case Variant::DICTIONARY: {
290
const Variant *v = VariantGetInternalPtr<Dictionary>::get_ptr(this)->getptr(p_member);
291
if (v) {
292
r_valid = true;
293
return *v;
294
}
295
} break;
296
default: {
297
if (Variant::has_builtin_method(type, p_member)) {
298
r_valid = true;
299
return Callable(memnew(VariantCallable(*this, p_member)));
300
}
301
} break;
302
}
303
304
r_valid = false;
305
return Variant();
306
}
307
308
/**** INDEXED SETTERS AND GETTERS ****/
309
310
#ifdef DEBUG_ENABLED
311
312
#define OOB_TEST(m_idx, m_v) \
313
ERR_FAIL_INDEX(m_idx, m_v)
314
315
#else
316
317
#define OOB_TEST(m_idx, m_v)
318
319
#endif
320
321
#ifdef DEBUG_ENABLED
322
323
#define NULL_TEST(m_key) \
324
ERR_FAIL_NULL(m_key)
325
326
#else
327
328
#define NULL_TEST(m_key)
329
330
#endif
331
332
#define INDEXED_SETGET_STRUCT_TYPED(m_base_type, m_elem_type) \
333
struct VariantIndexedSetGet_##m_base_type { \
334
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \
335
int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
336
if (index < 0) { \
337
index += size; \
338
} \
339
if (index < 0 || index >= size) { \
340
*oob = true; \
341
return; \
342
} \
343
VariantTypeAdjust<m_elem_type>::adjust(value); \
344
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
345
*oob = false; \
346
} \
347
static void ptr_get(const void *base, int64_t index, void *member) { \
348
/* avoid ptrconvert for performance*/ \
349
const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \
350
if (index < 0) \
351
index += v.size(); \
352
OOB_TEST(index, v.size()); \
353
PtrToArg<m_elem_type>::encode(v[index], member); \
354
} \
355
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) { \
356
if (value->get_type() != GetTypeInfo<m_elem_type>::VARIANT_TYPE) { \
357
*oob = false; \
358
*valid = false; \
359
return; \
360
} \
361
int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
362
if (index < 0) { \
363
index += size; \
364
} \
365
if (index < 0 || index >= size) { \
366
*oob = true; \
367
*valid = false; \
368
return; \
369
} \
370
(*VariantGetInternalPtr<m_base_type>::get_ptr(base)).write[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \
371
*oob = false; \
372
*valid = true; \
373
} \
374
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) { \
375
int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
376
if (index < 0) { \
377
index += size; \
378
} \
379
if (index < 0 || index >= size) { \
380
*oob = true; \
381
return; \
382
} \
383
(*VariantGetInternalPtr<m_base_type>::get_ptr(base)).write[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \
384
*oob = false; \
385
} \
386
static void ptr_set(void *base, int64_t index, const void *member) { \
387
/* avoid ptrconvert for performance*/ \
388
m_base_type &v = *reinterpret_cast<m_base_type *>(base); \
389
if (index < 0) \
390
index += v.size(); \
391
OOB_TEST(index, v.size()); \
392
v.write[index] = PtrToArg<m_elem_type>::convert(member); \
393
} \
394
static Variant::Type get_index_type() { \
395
return GetTypeInfo<m_elem_type>::VARIANT_TYPE; \
396
} \
397
static uint32_t get_index_usage() { \
398
return GetTypeInfo<m_elem_type>::get_class_info().usage; \
399
} \
400
static uint64_t get_indexed_size(const Variant *base) { \
401
return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
402
} \
403
};
404
405
#define INDEXED_SETGET_STRUCT_TYPED_NUMERIC(m_base_type, m_elem_type, m_assign_type) \
406
struct VariantIndexedSetGet_##m_base_type { \
407
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \
408
int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
409
if (index < 0) { \
410
index += size; \
411
} \
412
if (index < 0 || index >= size) { \
413
*oob = true; \
414
return; \
415
} \
416
VariantTypeAdjust<m_elem_type>::adjust(value); \
417
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
418
*oob = false; \
419
} \
420
static void ptr_get(const void *base, int64_t index, void *member) { \
421
/* avoid ptrconvert for performance*/ \
422
const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \
423
if (index < 0) \
424
index += v.size(); \
425
OOB_TEST(index, v.size()); \
426
PtrToArg<m_elem_type>::encode(v[index], member); \
427
} \
428
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) { \
429
int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
430
if (index < 0) { \
431
index += size; \
432
} \
433
if (index < 0 || index >= size) { \
434
*oob = true; \
435
*valid = false; \
436
return; \
437
} \
438
m_assign_type num; \
439
if (value->get_type() == Variant::INT) { \
440
num = (m_assign_type) * VariantGetInternalPtr<int64_t>::get_ptr(value); \
441
} else if (value->get_type() == Variant::FLOAT) { \
442
num = (m_assign_type) * VariantGetInternalPtr<double>::get_ptr(value); \
443
} else { \
444
*oob = false; \
445
*valid = false; \
446
return; \
447
} \
448
(*VariantGetInternalPtr<m_base_type>::get_ptr(base)).write[index] = num; \
449
*oob = false; \
450
*valid = true; \
451
} \
452
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) { \
453
int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
454
if (index < 0) { \
455
index += size; \
456
} \
457
if (index < 0 || index >= size) { \
458
*oob = true; \
459
return; \
460
} \
461
(*VariantGetInternalPtr<m_base_type>::get_ptr(base)).write[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \
462
*oob = false; \
463
} \
464
static void ptr_set(void *base, int64_t index, const void *member) { \
465
/* avoid ptrconvert for performance*/ \
466
m_base_type &v = *reinterpret_cast<m_base_type *>(base); \
467
if (index < 0) \
468
index += v.size(); \
469
OOB_TEST(index, v.size()); \
470
v.write[index] = PtrToArg<m_elem_type>::convert(member); \
471
} \
472
static Variant::Type get_index_type() { \
473
return GetTypeInfo<m_elem_type>::VARIANT_TYPE; \
474
} \
475
static uint32_t get_index_usage() { \
476
return GetTypeInfo<m_elem_type>::get_class_info().usage; \
477
} \
478
static uint64_t get_indexed_size(const Variant *base) { \
479
return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
480
} \
481
};
482
483
#define INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(m_base_type, m_elem_type, m_assign_type, m_max) \
484
struct VariantIndexedSetGet_##m_base_type { \
485
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \
486
if (index < 0 || index >= m_max) { \
487
*oob = true; \
488
return; \
489
} \
490
VariantTypeAdjust<m_elem_type>::adjust(value); \
491
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
492
*oob = false; \
493
} \
494
static void ptr_get(const void *base, int64_t index, void *member) { \
495
/* avoid ptrconvert for performance*/ \
496
const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \
497
OOB_TEST(index, m_max); \
498
PtrToArg<m_elem_type>::encode(v[index], member); \
499
} \
500
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) { \
501
if (index < 0 || index >= m_max) { \
502
*oob = true; \
503
*valid = false; \
504
return; \
505
} \
506
m_assign_type num; \
507
if (value->get_type() == Variant::INT) { \
508
num = (m_assign_type) * VariantGetInternalPtr<int64_t>::get_ptr(value); \
509
} else if (value->get_type() == Variant::FLOAT) { \
510
num = (m_assign_type) * VariantGetInternalPtr<double>::get_ptr(value); \
511
} else { \
512
*oob = false; \
513
*valid = false; \
514
return; \
515
} \
516
(*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = num; \
517
*oob = false; \
518
*valid = true; \
519
} \
520
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) { \
521
if (index < 0 || index >= m_max) { \
522
*oob = true; \
523
return; \
524
} \
525
(*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \
526
*oob = false; \
527
} \
528
static void ptr_set(void *base, int64_t index, const void *member) { \
529
/* avoid ptrconvert for performance*/ \
530
m_base_type &v = *reinterpret_cast<m_base_type *>(base); \
531
OOB_TEST(index, m_max); \
532
v[index] = PtrToArg<m_elem_type>::convert(member); \
533
} \
534
static Variant::Type get_index_type() { \
535
return GetTypeInfo<m_elem_type>::VARIANT_TYPE; \
536
} \
537
static uint32_t get_index_usage() { \
538
return GetTypeInfo<m_elem_type>::get_class_info().usage; \
539
} \
540
static uint64_t get_indexed_size(const Variant *base) { \
541
return m_max; \
542
} \
543
};
544
545
#define INDEXED_SETGET_STRUCT_BUILTIN_ACCESSOR(m_base_type, m_elem_type, m_accessor, m_max) \
546
struct VariantIndexedSetGet_##m_base_type { \
547
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \
548
if (index < 0 || index >= m_max) { \
549
*oob = true; \
550
return; \
551
} \
552
VariantTypeAdjust<m_elem_type>::adjust(value); \
553
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))m_accessor[index]; \
554
*oob = false; \
555
} \
556
static void ptr_get(const void *base, int64_t index, void *member) { \
557
/* avoid ptrconvert for performance*/ \
558
const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \
559
OOB_TEST(index, m_max); \
560
PtrToArg<m_elem_type>::encode(v m_accessor[index], member); \
561
} \
562
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) { \
563
if (value->get_type() != GetTypeInfo<m_elem_type>::VARIANT_TYPE) { \
564
*oob = false; \
565
*valid = false; \
566
} \
567
if (index < 0 || index >= m_max) { \
568
*oob = true; \
569
*valid = false; \
570
return; \
571
} \
572
(*VariantGetInternalPtr<m_base_type>::get_ptr(base)) m_accessor[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \
573
*oob = false; \
574
*valid = true; \
575
} \
576
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) { \
577
if (index < 0 || index >= m_max) { \
578
*oob = true; \
579
return; \
580
} \
581
(*VariantGetInternalPtr<m_base_type>::get_ptr(base)) m_accessor[index] = *VariantGetInternalPtr<m_elem_type>::get_ptr(value); \
582
*oob = false; \
583
} \
584
static void ptr_set(void *base, int64_t index, const void *member) { \
585
/* avoid ptrconvert for performance*/ \
586
m_base_type &v = *reinterpret_cast<m_base_type *>(base); \
587
OOB_TEST(index, m_max); \
588
v m_accessor[index] = PtrToArg<m_elem_type>::convert(member); \
589
} \
590
static Variant::Type get_index_type() { \
591
return GetTypeInfo<m_elem_type>::VARIANT_TYPE; \
592
} \
593
static uint32_t get_index_usage() { \
594
return GetTypeInfo<m_elem_type>::get_class_info().usage; \
595
} \
596
static uint64_t get_indexed_size(const Variant *base) { \
597
return m_max; \
598
} \
599
};
600
601
#define INDEXED_SETGET_STRUCT_BUILTIN_FUNC(m_base_type, m_elem_type, m_set, m_get, m_max) \
602
struct VariantIndexedSetGet_##m_base_type { \
603
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \
604
if (index < 0 || index >= m_max) { \
605
*oob = true; \
606
return; \
607
} \
608
VariantTypeAdjust<m_elem_type>::adjust(value); \
609
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_get(index); \
610
*oob = false; \
611
} \
612
static void ptr_get(const void *base, int64_t index, void *member) { \
613
/* avoid ptrconvert for performance*/ \
614
const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \
615
OOB_TEST(index, m_max); \
616
PtrToArg<m_elem_type>::encode(v.m_get(index), member); \
617
} \
618
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) { \
619
if (value->get_type() != GetTypeInfo<m_elem_type>::VARIANT_TYPE) { \
620
*oob = false; \
621
*valid = false; \
622
} \
623
if (index < 0 || index >= m_max) { \
624
*oob = true; \
625
*valid = false; \
626
return; \
627
} \
628
VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_set(index, *VariantGetInternalPtr<m_elem_type>::get_ptr(value)); \
629
*oob = false; \
630
*valid = true; \
631
} \
632
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) { \
633
if (index < 0 || index >= m_max) { \
634
*oob = true; \
635
return; \
636
} \
637
VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_set(index, *VariantGetInternalPtr<m_elem_type>::get_ptr(value)); \
638
*oob = false; \
639
} \
640
static void ptr_set(void *base, int64_t index, const void *member) { \
641
/* avoid ptrconvert for performance*/ \
642
m_base_type &v = *reinterpret_cast<m_base_type *>(base); \
643
OOB_TEST(index, m_max); \
644
v.m_set(index, PtrToArg<m_elem_type>::convert(member)); \
645
} \
646
static Variant::Type get_index_type() { \
647
return GetTypeInfo<m_elem_type>::VARIANT_TYPE; \
648
} \
649
static uint32_t get_index_usage() { \
650
return GetTypeInfo<m_elem_type>::get_class_info().usage; \
651
} \
652
static uint64_t get_indexed_size(const Variant *base) { \
653
return m_max; \
654
} \
655
};
656
657
struct VariantIndexedSetGet_Array {
658
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) {
659
int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size();
660
if (index < 0) {
661
index += size;
662
}
663
if (index < 0 || index >= size) {
664
*oob = true;
665
return;
666
}
667
*value = (*VariantGetInternalPtr<Array>::get_ptr(base))[index];
668
*oob = false;
669
}
670
static void ptr_get(const void *base, int64_t index, void *member) {
671
/* avoid ptrconvert for performance*/
672
const Array &v = *reinterpret_cast<const Array *>(base);
673
if (index < 0) {
674
index += v.size();
675
}
676
OOB_TEST(index, v.size());
677
PtrToArg<Variant>::encode(v[index], member);
678
}
679
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) {
680
if (VariantGetInternalPtr<Array>::get_ptr(base)->is_read_only()) {
681
*valid = false;
682
*oob = true;
683
return;
684
}
685
int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size();
686
if (index < 0) {
687
index += size;
688
}
689
if (index < 0 || index >= size) {
690
*oob = true;
691
*valid = false;
692
return;
693
}
694
VariantGetInternalPtr<Array>::get_ptr(base)->set(index, *value);
695
*oob = false;
696
*valid = true;
697
}
698
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) {
699
if (VariantGetInternalPtr<Array>::get_ptr(base)->is_read_only()) {
700
*oob = true;
701
return;
702
}
703
int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size();
704
if (index < 0) {
705
index += size;
706
}
707
if (index < 0 || index >= size) {
708
*oob = true;
709
return;
710
}
711
VariantGetInternalPtr<Array>::get_ptr(base)->set(index, *value);
712
*oob = false;
713
}
714
static void ptr_set(void *base, int64_t index, const void *member) {
715
/* avoid ptrconvert for performance*/
716
Array &v = *reinterpret_cast<Array *>(base);
717
if (index < 0) {
718
index += v.size();
719
}
720
OOB_TEST(index, v.size());
721
v.set(index, PtrToArg<Variant>::convert(member));
722
}
723
static Variant::Type get_index_type() { return Variant::NIL; }
724
static uint32_t get_index_usage() { return PROPERTY_USAGE_NIL_IS_VARIANT; }
725
static uint64_t get_indexed_size(const Variant *base) { return 0; }
726
};
727
728
struct VariantIndexedSetGet_Dictionary {
729
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) {
730
const Variant *ptr = VariantGetInternalPtr<Dictionary>::get_ptr(base)->getptr(index);
731
if (!ptr) {
732
*oob = true;
733
return;
734
}
735
*value = *ptr;
736
*oob = false;
737
}
738
static void ptr_get(const void *base, int64_t index, void *member) {
739
// Avoid ptrconvert for performance.
740
const Dictionary &v = *reinterpret_cast<const Dictionary *>(base);
741
const Variant *ptr = v.getptr(index);
742
NULL_TEST(ptr);
743
PtrToArg<Variant>::encode(*ptr, member);
744
}
745
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) {
746
*valid = VariantGetInternalPtr<Dictionary>::get_ptr(base)->set(index, *value);
747
*oob = VariantGetInternalPtr<Dictionary>::get_ptr(base)->is_read_only();
748
}
749
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) {
750
VariantGetInternalPtr<Dictionary>::get_ptr(base)->set(index, *value);
751
*oob = VariantGetInternalPtr<Dictionary>::get_ptr(base)->is_read_only();
752
}
753
static void ptr_set(void *base, int64_t index, const void *member) {
754
Dictionary &v = *reinterpret_cast<Dictionary *>(base);
755
v.set(index, PtrToArg<Variant>::convert(member));
756
}
757
static Variant::Type get_index_type() { return Variant::NIL; }
758
static uint32_t get_index_usage() { return PROPERTY_USAGE_DEFAULT; }
759
static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<Dictionary>::get_ptr(base)->size(); }
760
};
761
762
struct VariantIndexedSetGet_String {
763
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) {
764
int64_t length = VariantGetInternalPtr<String>::get_ptr(base)->length();
765
if (index < 0) {
766
index += length;
767
}
768
if (index < 0 || index >= length) {
769
*oob = true;
770
return;
771
}
772
*value = String::chr((*VariantGetInternalPtr<String>::get_ptr(base))[index]);
773
*oob = false;
774
}
775
static void ptr_get(const void *base, int64_t index, void *member) {
776
/* avoid ptrconvert for performance*/
777
const String &v = *reinterpret_cast<const String *>(base);
778
if (index < 0) {
779
index += v.length();
780
}
781
OOB_TEST(index, v.length());
782
PtrToArg<String>::encode(String::chr(v[index]), member);
783
}
784
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) {
785
if (value->get_type() != Variant::STRING) {
786
*oob = false;
787
*valid = false;
788
return;
789
}
790
int64_t length = VariantGetInternalPtr<String>::get_ptr(base)->length();
791
if (index < 0) {
792
index += length;
793
}
794
if (index < 0 || index >= length) {
795
*oob = true;
796
*valid = false;
797
return;
798
}
799
String *b = VariantGetInternalPtr<String>::get_ptr(base);
800
const String *v = VariantInternal::get_string(value);
801
if (v->length() == 0) {
802
b->remove_at(index);
803
} else {
804
b->set(index, v->get(0));
805
}
806
*oob = false;
807
*valid = true;
808
}
809
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) {
810
int64_t length = VariantGetInternalPtr<String>::get_ptr(base)->length();
811
if (index < 0) {
812
index += length;
813
}
814
if (index < 0 || index >= length) {
815
*oob = true;
816
return;
817
}
818
String *b = VariantGetInternalPtr<String>::get_ptr(base);
819
const String *v = VariantInternal::get_string(value);
820
if (v->length() == 0) {
821
b->remove_at(index);
822
} else {
823
b->set(index, v->get(0));
824
}
825
*oob = false;
826
}
827
static void ptr_set(void *base, int64_t index, const void *member) {
828
/* avoid ptrconvert for performance*/
829
String &v = *reinterpret_cast<String *>(base);
830
if (index < 0) {
831
index += v.length();
832
}
833
OOB_TEST(index, v.length());
834
const String &m = *reinterpret_cast<const String *>(member);
835
if (unlikely(m.length() == 0)) {
836
v.remove_at(index);
837
} else {
838
v.set(index, m.unicode_at(0));
839
}
840
}
841
static Variant::Type get_index_type() { return Variant::STRING; }
842
static uint32_t get_index_usage() { return PROPERTY_USAGE_DEFAULT; }
843
static uint64_t get_indexed_size(const Variant *base) { return VariantInternal::get_string(base)->length(); }
844
};
845
846
INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector2, double, real_t, 2)
847
INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector2i, int64_t, int32_t, 2)
848
INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector3, double, real_t, 3)
849
INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector3i, int64_t, int32_t, 3)
850
INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector4, double, real_t, 4)
851
INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Vector4i, int64_t, int32_t, 4)
852
INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Quaternion, double, real_t, 4)
853
INDEXED_SETGET_STRUCT_BUILTIN_NUMERIC(Color, double, float, 4)
854
855
INDEXED_SETGET_STRUCT_BUILTIN_ACCESSOR(Transform2D, Vector2, .columns, 3)
856
INDEXED_SETGET_STRUCT_BUILTIN_FUNC(Basis, Vector3, set_column, get_column, 3)
857
INDEXED_SETGET_STRUCT_BUILTIN_ACCESSOR(Projection, Vector4, .columns, 4)
858
859
INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedByteArray, int64_t, uint8_t)
860
INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt32Array, int64_t, int32_t)
861
INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt64Array, int64_t, int64_t)
862
INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedFloat32Array, double, float)
863
INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedFloat64Array, double, double)
864
INDEXED_SETGET_STRUCT_TYPED(PackedVector2Array, Vector2)
865
INDEXED_SETGET_STRUCT_TYPED(PackedVector3Array, Vector3)
866
INDEXED_SETGET_STRUCT_TYPED(PackedStringArray, String)
867
INDEXED_SETGET_STRUCT_TYPED(PackedColorArray, Color)
868
INDEXED_SETGET_STRUCT_TYPED(PackedVector4Array, Vector4)
869
870
struct VariantIndexedSetterGetterInfo {
871
void (*setter)(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) = nullptr;
872
void (*getter)(const Variant *base, int64_t index, Variant *value, bool *oob) = nullptr;
873
874
Variant::ValidatedIndexedSetter validated_setter = nullptr;
875
Variant::ValidatedIndexedGetter validated_getter = nullptr;
876
877
Variant::PTRIndexedSetter ptr_setter = nullptr;
878
Variant::PTRIndexedGetter ptr_getter = nullptr;
879
880
uint64_t (*get_indexed_size)(const Variant *base) = nullptr;
881
882
Variant::Type index_type = Variant::NIL;
883
uint32_t index_usage = PROPERTY_USAGE_DEFAULT;
884
885
bool valid = false;
886
};
887
888
static VariantIndexedSetterGetterInfo variant_indexed_setters_getters[Variant::VARIANT_MAX];
889
890
template <typename T>
891
static void register_indexed_member(Variant::Type p_type) {
892
VariantIndexedSetterGetterInfo &sgi = variant_indexed_setters_getters[p_type];
893
894
sgi.setter = T::set;
895
sgi.validated_setter = T::validated_set;
896
sgi.ptr_setter = T::ptr_set;
897
898
sgi.getter = T::get;
899
sgi.validated_getter = T::get;
900
sgi.ptr_getter = T::ptr_get;
901
902
sgi.index_type = T::get_index_type();
903
sgi.index_usage = T::get_index_usage();
904
sgi.get_indexed_size = T::get_indexed_size;
905
906
sgi.valid = true;
907
}
908
909
void register_indexed_setters_getters() {
910
#define REGISTER_INDEXED_MEMBER(m_base_type) register_indexed_member<VariantIndexedSetGet_##m_base_type>(GetTypeInfo<m_base_type>::VARIANT_TYPE)
911
912
REGISTER_INDEXED_MEMBER(String);
913
REGISTER_INDEXED_MEMBER(Vector2);
914
REGISTER_INDEXED_MEMBER(Vector2i);
915
REGISTER_INDEXED_MEMBER(Vector3);
916
REGISTER_INDEXED_MEMBER(Vector3i);
917
REGISTER_INDEXED_MEMBER(Vector4);
918
REGISTER_INDEXED_MEMBER(Vector4i);
919
REGISTER_INDEXED_MEMBER(Quaternion);
920
REGISTER_INDEXED_MEMBER(Color);
921
REGISTER_INDEXED_MEMBER(Transform2D);
922
REGISTER_INDEXED_MEMBER(Basis);
923
REGISTER_INDEXED_MEMBER(Projection);
924
925
REGISTER_INDEXED_MEMBER(PackedByteArray);
926
REGISTER_INDEXED_MEMBER(PackedInt32Array);
927
REGISTER_INDEXED_MEMBER(PackedInt64Array);
928
REGISTER_INDEXED_MEMBER(PackedFloat32Array);
929
REGISTER_INDEXED_MEMBER(PackedFloat64Array);
930
REGISTER_INDEXED_MEMBER(PackedVector2Array);
931
REGISTER_INDEXED_MEMBER(PackedVector3Array);
932
REGISTER_INDEXED_MEMBER(PackedStringArray);
933
REGISTER_INDEXED_MEMBER(PackedColorArray);
934
REGISTER_INDEXED_MEMBER(PackedVector4Array);
935
936
REGISTER_INDEXED_MEMBER(Array);
937
REGISTER_INDEXED_MEMBER(Dictionary);
938
}
939
940
static void unregister_indexed_setters_getters() {
941
}
942
943
bool Variant::has_indexing(Variant::Type p_type) {
944
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false);
945
return variant_indexed_setters_getters[p_type].valid;
946
}
947
948
Variant::Type Variant::get_indexed_element_type(Variant::Type p_type) {
949
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::VARIANT_MAX);
950
return variant_indexed_setters_getters[p_type].index_type;
951
}
952
953
uint32_t Variant::get_indexed_element_usage(Variant::Type p_type) {
954
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, PROPERTY_USAGE_DEFAULT);
955
return variant_indexed_setters_getters[p_type].index_usage;
956
}
957
958
Variant::ValidatedIndexedSetter Variant::get_member_validated_indexed_setter(Variant::Type p_type) {
959
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
960
return variant_indexed_setters_getters[p_type].validated_setter;
961
}
962
Variant::ValidatedIndexedGetter Variant::get_member_validated_indexed_getter(Variant::Type p_type) {
963
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
964
return variant_indexed_setters_getters[p_type].validated_getter;
965
}
966
967
Variant::PTRIndexedSetter Variant::get_member_ptr_indexed_setter(Variant::Type p_type) {
968
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
969
return variant_indexed_setters_getters[p_type].ptr_setter;
970
}
971
Variant::PTRIndexedGetter Variant::get_member_ptr_indexed_getter(Variant::Type p_type) {
972
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
973
return variant_indexed_setters_getters[p_type].ptr_getter;
974
}
975
976
void Variant::set_indexed(int64_t p_index, const Variant &p_value, bool &r_valid, bool &r_oob) {
977
if (likely(variant_indexed_setters_getters[type].valid)) {
978
variant_indexed_setters_getters[type].setter(this, p_index, &p_value, &r_valid, &r_oob);
979
} else {
980
r_valid = false;
981
r_oob = false;
982
}
983
}
984
Variant Variant::get_indexed(int64_t p_index, bool &r_valid, bool &r_oob) const {
985
if (likely(variant_indexed_setters_getters[type].valid)) {
986
Variant ret;
987
variant_indexed_setters_getters[type].getter(this, p_index, &ret, &r_oob);
988
r_valid = !r_oob;
989
return ret;
990
} else {
991
r_valid = false;
992
r_oob = false;
993
return Variant();
994
}
995
}
996
997
uint64_t Variant::get_indexed_size() const {
998
if (likely(variant_indexed_setters_getters[type].valid && variant_indexed_setters_getters[type].get_indexed_size)) {
999
return variant_indexed_setters_getters[type].get_indexed_size(this);
1000
} else {
1001
return 0;
1002
}
1003
}
1004
1005
struct VariantKeyedSetGetDictionary {
1006
static void get(const Variant *base, const Variant *key, Variant *value, bool *r_valid) {
1007
const Variant *ptr = VariantGetInternalPtr<Dictionary>::get_ptr(base)->getptr(*key);
1008
if (!ptr) {
1009
*r_valid = false;
1010
return;
1011
}
1012
*value = *ptr;
1013
*r_valid = true;
1014
}
1015
static void ptr_get(const void *base, const void *key, void *value) {
1016
/* avoid ptrconvert for performance*/
1017
const Dictionary &v = *reinterpret_cast<const Dictionary *>(base);
1018
const Variant *ptr = v.getptr(PtrToArg<Variant>::convert(key));
1019
NULL_TEST(ptr);
1020
PtrToArg<Variant>::encode(*ptr, value);
1021
}
1022
static void set(Variant *base, const Variant *key, const Variant *value, bool *r_valid) {
1023
*r_valid = VariantGetInternalPtr<Dictionary>::get_ptr(base)->set(*key, *value);
1024
}
1025
static void ptr_set(void *base, const void *key, const void *value) {
1026
Dictionary &v = *reinterpret_cast<Dictionary *>(base);
1027
v.set(PtrToArg<Variant>::convert(key), PtrToArg<Variant>::convert(value));
1028
}
1029
1030
static bool has(const Variant *base, const Variant *key, bool *r_valid) {
1031
*r_valid = true;
1032
return VariantGetInternalPtr<Dictionary>::get_ptr(base)->has(*key);
1033
}
1034
static uint32_t ptr_has(const void *base, const void *key) {
1035
/* avoid ptrconvert for performance*/
1036
const Dictionary &v = *reinterpret_cast<const Dictionary *>(base);
1037
return v.has(PtrToArg<Variant>::convert(key));
1038
}
1039
};
1040
1041
struct VariantKeyedSetGetObject {
1042
static void get(const Variant *base, const Variant *key, Variant *value, bool *r_valid) {
1043
Object *obj = base->get_validated_object();
1044
1045
if (!obj) {
1046
*r_valid = false;
1047
*value = Variant();
1048
return;
1049
}
1050
*value = obj->getvar(*key, r_valid);
1051
}
1052
static void ptr_get(const void *base, const void *key, void *value) {
1053
const Object *obj = PtrToArg<Object *>::convert(base);
1054
NULL_TEST(obj);
1055
Variant v = obj->getvar(PtrToArg<Variant>::convert(key));
1056
PtrToArg<Variant>::encode(v, value);
1057
}
1058
static void set(Variant *base, const Variant *key, const Variant *value, bool *r_valid) {
1059
Object *obj = base->get_validated_object();
1060
1061
if (!obj) {
1062
*r_valid = false;
1063
return;
1064
}
1065
obj->setvar(*key, *value, r_valid);
1066
}
1067
static void ptr_set(void *base, const void *key, const void *value) {
1068
Object *obj = PtrToArg<Object *>::convert(base);
1069
NULL_TEST(obj);
1070
obj->setvar(PtrToArg<Variant>::convert(key), PtrToArg<Variant>::convert(value));
1071
}
1072
1073
static bool has(const Variant *base, const Variant *key, bool *r_valid) {
1074
Object *obj = base->get_validated_object();
1075
if (!obj) {
1076
*r_valid = false;
1077
return false;
1078
}
1079
*r_valid = true;
1080
bool exists;
1081
obj->getvar(*key, &exists);
1082
return exists;
1083
}
1084
static uint32_t ptr_has(const void *base, const void *key) {
1085
const Object *obj = PtrToArg<Object *>::convert(base);
1086
ERR_FAIL_NULL_V(obj, false);
1087
bool valid;
1088
obj->getvar(PtrToArg<Variant>::convert(key), &valid);
1089
return valid;
1090
}
1091
};
1092
1093
struct VariantKeyedSetterGetterInfo {
1094
Variant::ValidatedKeyedSetter validated_setter = nullptr;
1095
Variant::ValidatedKeyedGetter validated_getter = nullptr;
1096
Variant::ValidatedKeyedChecker validated_checker = nullptr;
1097
1098
Variant::PTRKeyedSetter ptr_setter = nullptr;
1099
Variant::PTRKeyedGetter ptr_getter = nullptr;
1100
Variant::PTRKeyedChecker ptr_checker = nullptr;
1101
1102
bool valid = false;
1103
};
1104
1105
static VariantKeyedSetterGetterInfo variant_keyed_setters_getters[Variant::VARIANT_MAX];
1106
1107
template <typename T>
1108
static void register_keyed_member(Variant::Type p_type) {
1109
VariantKeyedSetterGetterInfo &sgi = variant_keyed_setters_getters[p_type];
1110
1111
sgi.validated_setter = T::set;
1112
sgi.ptr_setter = T::ptr_set;
1113
1114
sgi.validated_getter = T::get;
1115
sgi.ptr_getter = T::ptr_get;
1116
1117
sgi.validated_checker = T::has;
1118
sgi.ptr_checker = T::ptr_has;
1119
1120
sgi.valid = true;
1121
}
1122
1123
static void register_keyed_setters_getters() {
1124
register_keyed_member<VariantKeyedSetGetDictionary>(Variant::DICTIONARY);
1125
register_keyed_member<VariantKeyedSetGetObject>(Variant::OBJECT);
1126
}
1127
bool Variant::is_keyed(Variant::Type p_type) {
1128
ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, false);
1129
return variant_keyed_setters_getters[p_type].valid;
1130
}
1131
1132
Variant::ValidatedKeyedSetter Variant::get_member_validated_keyed_setter(Variant::Type p_type) {
1133
ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr);
1134
return variant_keyed_setters_getters[p_type].validated_setter;
1135
}
1136
Variant::ValidatedKeyedGetter Variant::get_member_validated_keyed_getter(Variant::Type p_type) {
1137
ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr);
1138
return variant_keyed_setters_getters[p_type].validated_getter;
1139
}
1140
Variant::ValidatedKeyedChecker Variant::get_member_validated_keyed_checker(Variant::Type p_type) {
1141
ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr);
1142
return variant_keyed_setters_getters[p_type].validated_checker;
1143
}
1144
1145
Variant::PTRKeyedSetter Variant::get_member_ptr_keyed_setter(Variant::Type p_type) {
1146
ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr);
1147
return variant_keyed_setters_getters[p_type].ptr_setter;
1148
}
1149
Variant::PTRKeyedGetter Variant::get_member_ptr_keyed_getter(Variant::Type p_type) {
1150
ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr);
1151
return variant_keyed_setters_getters[p_type].ptr_getter;
1152
}
1153
Variant::PTRKeyedChecker Variant::get_member_ptr_keyed_checker(Variant::Type p_type) {
1154
ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, nullptr);
1155
return variant_keyed_setters_getters[p_type].ptr_checker;
1156
}
1157
1158
void Variant::set_keyed(const Variant &p_key, const Variant &p_value, bool &r_valid) {
1159
if (likely(variant_keyed_setters_getters[type].valid)) {
1160
variant_keyed_setters_getters[type].validated_setter(this, &p_key, &p_value, &r_valid);
1161
} else {
1162
r_valid = false;
1163
}
1164
}
1165
Variant Variant::get_keyed(const Variant &p_key, bool &r_valid) const {
1166
if (likely(variant_keyed_setters_getters[type].valid)) {
1167
Variant ret;
1168
variant_keyed_setters_getters[type].validated_getter(this, &p_key, &ret, &r_valid);
1169
return ret;
1170
} else {
1171
r_valid = false;
1172
return Variant();
1173
}
1174
}
1175
bool Variant::has_key(const Variant &p_key, bool &r_valid) const {
1176
if (likely(variant_keyed_setters_getters[type].valid)) {
1177
return variant_keyed_setters_getters[type].validated_checker(this, &p_key, &r_valid);
1178
} else {
1179
r_valid = false;
1180
return false;
1181
}
1182
}
1183
1184
void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid, VariantSetError *err_code) {
1185
if (err_code) {
1186
*err_code = VariantSetError::SET_OK;
1187
}
1188
if (type == DICTIONARY || type == OBJECT) {
1189
bool valid;
1190
set_keyed(p_index, p_value, valid);
1191
if (r_valid) {
1192
*r_valid = valid;
1193
if (!valid && err_code) {
1194
*err_code = VariantSetError::SET_KEYED_ERR;
1195
}
1196
}
1197
} else {
1198
bool valid = false;
1199
if (p_index.get_type() == STRING_NAME) {
1200
set_named(*VariantGetInternalPtr<StringName>::get_ptr(&p_index), p_value, valid);
1201
if (!valid && err_code) {
1202
*err_code = VariantSetError::SET_NAMED_ERR;
1203
}
1204
} else if (p_index.get_type() == INT) {
1205
bool obb;
1206
set_indexed(*VariantGetInternalPtr<int64_t>::get_ptr(&p_index), p_value, valid, obb);
1207
if (obb) {
1208
valid = false;
1209
if (err_code) {
1210
*err_code = VariantSetError::SET_INDEXED_ERR;
1211
}
1212
}
1213
} else if (p_index.get_type() == STRING) { // less efficient version of named
1214
set_named(*VariantGetInternalPtr<String>::get_ptr(&p_index), p_value, valid);
1215
if (!valid && err_code) {
1216
*err_code = VariantSetError::SET_NAMED_ERR;
1217
}
1218
} else if (p_index.get_type() == FLOAT) { // less efficient version of indexed
1219
bool obb;
1220
set_indexed(*VariantGetInternalPtr<double>::get_ptr(&p_index), p_value, valid, obb);
1221
if (obb) {
1222
valid = false;
1223
if (err_code) {
1224
*err_code = VariantSetError::SET_INDEXED_ERR;
1225
}
1226
}
1227
}
1228
if (r_valid) {
1229
*r_valid = valid;
1230
}
1231
}
1232
}
1233
1234
Variant Variant::get(const Variant &p_index, bool *r_valid, VariantGetError *err_code) const {
1235
if (err_code) {
1236
*err_code = VariantGetError::GET_OK;
1237
}
1238
Variant ret;
1239
if (type == DICTIONARY || type == OBJECT) {
1240
bool valid;
1241
ret = get_keyed(p_index, valid);
1242
if (r_valid) {
1243
*r_valid = valid;
1244
if (!valid && err_code) {
1245
*err_code = VariantGetError::GET_KEYED_ERR;
1246
}
1247
}
1248
} else {
1249
bool valid = false;
1250
if (p_index.get_type() == STRING_NAME) {
1251
ret = get_named(*VariantGetInternalPtr<StringName>::get_ptr(&p_index), valid);
1252
if (!valid && err_code) {
1253
*err_code = VariantGetError::GET_NAMED_ERR;
1254
}
1255
} else if (p_index.get_type() == INT) {
1256
bool obb;
1257
ret = get_indexed(*VariantGetInternalPtr<int64_t>::get_ptr(&p_index), valid, obb);
1258
if (obb) {
1259
valid = false;
1260
if (err_code) {
1261
*err_code = VariantGetError::GET_INDEXED_ERR;
1262
}
1263
}
1264
} else if (p_index.get_type() == STRING) { // less efficient version of named
1265
ret = get_named(*VariantGetInternalPtr<String>::get_ptr(&p_index), valid);
1266
if (!valid && err_code) {
1267
*err_code = VariantGetError::GET_NAMED_ERR;
1268
}
1269
} else if (p_index.get_type() == FLOAT) { // less efficient version of indexed
1270
bool obb;
1271
ret = get_indexed(*VariantGetInternalPtr<double>::get_ptr(&p_index), valid, obb);
1272
if (obb) {
1273
valid = false;
1274
if (err_code) {
1275
*err_code = VariantGetError::GET_INDEXED_ERR;
1276
}
1277
}
1278
}
1279
if (r_valid) {
1280
*r_valid = valid;
1281
}
1282
}
1283
1284
return ret;
1285
}
1286
1287
void Variant::get_property_list(List<PropertyInfo> *p_list) const {
1288
if (type == DICTIONARY) {
1289
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
1290
for (const KeyValue<Variant, Variant> &kv : *dic) {
1291
if (kv.key.is_string()) {
1292
p_list->push_back(PropertyInfo(dic->get_valid(kv.key).get_type(), kv.key));
1293
}
1294
}
1295
} else if (type == OBJECT) {
1296
Object *obj = get_validated_object();
1297
ERR_FAIL_NULL(obj);
1298
obj->get_property_list(p_list);
1299
1300
} else {
1301
List<StringName> members;
1302
get_member_list(type, &members);
1303
for (const StringName &E : members) {
1304
PropertyInfo pi;
1305
pi.name = E;
1306
pi.type = get_member_type(type, E);
1307
p_list->push_back(pi);
1308
}
1309
}
1310
}
1311
1312
bool Variant::iter_init(Variant &r_iter, bool &valid) const {
1313
valid = true;
1314
switch (type) {
1315
case INT: {
1316
r_iter = 0;
1317
return _data._int > 0;
1318
} break;
1319
case FLOAT: {
1320
r_iter = 0.0;
1321
return _data._float > 0.0;
1322
} break;
1323
case VECTOR2: {
1324
double from = reinterpret_cast<const Vector2 *>(_data._mem)->x;
1325
double to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
1326
1327
r_iter = from;
1328
1329
return from < to;
1330
} break;
1331
case VECTOR2I: {
1332
int64_t from = reinterpret_cast<const Vector2i *>(_data._mem)->x;
1333
int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y;
1334
1335
r_iter = from;
1336
1337
return from < to;
1338
} break;
1339
case VECTOR3: {
1340
double from = reinterpret_cast<const Vector3 *>(_data._mem)->x;
1341
double to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
1342
double step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
1343
1344
r_iter = from;
1345
1346
if (from == to) {
1347
return false;
1348
} else if (from < to) {
1349
return step > 0;
1350
}
1351
return step < 0;
1352
} break;
1353
case VECTOR3I: {
1354
int64_t from = reinterpret_cast<const Vector3i *>(_data._mem)->x;
1355
int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y;
1356
int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z;
1357
1358
r_iter = from;
1359
1360
if (from == to) {
1361
return false;
1362
} else if (from < to) {
1363
return step > 0;
1364
}
1365
return step < 0;
1366
} break;
1367
case OBJECT: {
1368
if (!_get_obj().obj) {
1369
valid = false;
1370
return false;
1371
}
1372
1373
#ifdef DEBUG_ENABLED
1374
1375
if (EngineDebugger::is_active() && !_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
1376
valid = false;
1377
return false;
1378
}
1379
1380
#endif
1381
Callable::CallError ce;
1382
ce.error = Callable::CallError::CALL_OK;
1383
Array ref = { r_iter };
1384
Variant vref = ref;
1385
const Variant *refp[] = { &vref };
1386
Variant ret = _get_obj().obj->callp(CoreStringName(_iter_init), refp, 1, ce);
1387
1388
if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
1389
valid = false;
1390
return false;
1391
}
1392
1393
r_iter = ref[0];
1394
return ret;
1395
} break;
1396
1397
case STRING: {
1398
const String *str = reinterpret_cast<const String *>(_data._mem);
1399
if (str->is_empty()) {
1400
return false;
1401
}
1402
r_iter = 0;
1403
return true;
1404
} break;
1405
case DICTIONARY: {
1406
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
1407
if (dic->is_empty()) {
1408
return false;
1409
}
1410
1411
const Variant *next = dic->next(nullptr);
1412
r_iter = *next;
1413
return true;
1414
1415
} break;
1416
case ARRAY: {
1417
const Array *arr = reinterpret_cast<const Array *>(_data._mem);
1418
if (arr->is_empty()) {
1419
return false;
1420
}
1421
r_iter = 0;
1422
return true;
1423
} break;
1424
case PACKED_BYTE_ARRAY: {
1425
const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
1426
if (arr->size() == 0) {
1427
return false;
1428
}
1429
r_iter = 0;
1430
return true;
1431
1432
} break;
1433
case PACKED_INT32_ARRAY: {
1434
const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
1435
if (arr->size() == 0) {
1436
return false;
1437
}
1438
r_iter = 0;
1439
return true;
1440
1441
} break;
1442
case PACKED_INT64_ARRAY: {
1443
const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
1444
if (arr->size() == 0) {
1445
return false;
1446
}
1447
r_iter = 0;
1448
return true;
1449
1450
} break;
1451
case PACKED_FLOAT32_ARRAY: {
1452
const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
1453
if (arr->size() == 0) {
1454
return false;
1455
}
1456
r_iter = 0;
1457
return true;
1458
1459
} break;
1460
case PACKED_FLOAT64_ARRAY: {
1461
const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
1462
if (arr->size() == 0) {
1463
return false;
1464
}
1465
r_iter = 0;
1466
return true;
1467
1468
} break;
1469
case PACKED_STRING_ARRAY: {
1470
const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
1471
if (arr->size() == 0) {
1472
return false;
1473
}
1474
r_iter = 0;
1475
return true;
1476
} break;
1477
case PACKED_VECTOR2_ARRAY: {
1478
const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
1479
if (arr->size() == 0) {
1480
return false;
1481
}
1482
r_iter = 0;
1483
return true;
1484
} break;
1485
case PACKED_VECTOR3_ARRAY: {
1486
const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
1487
if (arr->size() == 0) {
1488
return false;
1489
}
1490
r_iter = 0;
1491
return true;
1492
} break;
1493
case PACKED_COLOR_ARRAY: {
1494
const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
1495
if (arr->size() == 0) {
1496
return false;
1497
}
1498
r_iter = 0;
1499
return true;
1500
1501
} break;
1502
case PACKED_VECTOR4_ARRAY: {
1503
const Vector<Vector4> *arr = &PackedArrayRef<Vector4>::get_array(_data.packed_array);
1504
if (arr->size() == 0) {
1505
return false;
1506
}
1507
r_iter = 0;
1508
return true;
1509
} break;
1510
default: {
1511
}
1512
}
1513
1514
valid = false;
1515
return false;
1516
}
1517
1518
bool Variant::iter_next(Variant &r_iter, bool &valid) const {
1519
valid = true;
1520
switch (type) {
1521
case INT: {
1522
int64_t idx = r_iter;
1523
idx++;
1524
if (idx >= _data._int) {
1525
return false;
1526
}
1527
r_iter = idx;
1528
return true;
1529
} break;
1530
case FLOAT: {
1531
double idx = r_iter;
1532
idx++;
1533
if (idx >= _data._float) {
1534
return false;
1535
}
1536
r_iter = idx;
1537
return true;
1538
} break;
1539
case VECTOR2: {
1540
double to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
1541
1542
double idx = r_iter;
1543
idx++;
1544
1545
if (idx >= to) {
1546
return false;
1547
}
1548
1549
r_iter = idx;
1550
return true;
1551
} break;
1552
case VECTOR2I: {
1553
int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y;
1554
1555
int64_t idx = r_iter;
1556
idx++;
1557
1558
if (idx >= to) {
1559
return false;
1560
}
1561
1562
r_iter = idx;
1563
return true;
1564
} break;
1565
case VECTOR3: {
1566
double to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
1567
double step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
1568
1569
double idx = r_iter;
1570
idx += step;
1571
1572
if (step < 0 && idx <= to) {
1573
return false;
1574
}
1575
1576
if (step > 0 && idx >= to) {
1577
return false;
1578
}
1579
1580
r_iter = idx;
1581
return true;
1582
} break;
1583
case VECTOR3I: {
1584
int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y;
1585
int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z;
1586
1587
int64_t idx = r_iter;
1588
idx += step;
1589
1590
if (step < 0 && idx <= to) {
1591
return false;
1592
}
1593
1594
if (step > 0 && idx >= to) {
1595
return false;
1596
}
1597
1598
r_iter = idx;
1599
return true;
1600
} break;
1601
case OBJECT: {
1602
if (!_get_obj().obj) {
1603
valid = false;
1604
return false;
1605
}
1606
1607
#ifdef DEBUG_ENABLED
1608
1609
if (EngineDebugger::is_active() && !_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
1610
valid = false;
1611
return false;
1612
}
1613
1614
#endif
1615
Callable::CallError ce;
1616
ce.error = Callable::CallError::CALL_OK;
1617
Array ref = { r_iter };
1618
Variant vref = ref;
1619
const Variant *refp[] = { &vref };
1620
Variant ret = _get_obj().obj->callp(CoreStringName(_iter_next), refp, 1, ce);
1621
1622
if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
1623
valid = false;
1624
return false;
1625
}
1626
1627
r_iter = ref[0];
1628
1629
return ret;
1630
} break;
1631
1632
case STRING: {
1633
const String *str = reinterpret_cast<const String *>(_data._mem);
1634
int idx = r_iter;
1635
idx++;
1636
if (idx >= str->length()) {
1637
return false;
1638
}
1639
r_iter = idx;
1640
return true;
1641
} break;
1642
case DICTIONARY: {
1643
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
1644
const Variant *next = dic->next(&r_iter);
1645
if (!next) {
1646
return false;
1647
}
1648
1649
r_iter = *next;
1650
return true;
1651
1652
} break;
1653
case ARRAY: {
1654
const Array *arr = reinterpret_cast<const Array *>(_data._mem);
1655
int idx = r_iter;
1656
idx++;
1657
if (idx >= arr->size()) {
1658
return false;
1659
}
1660
r_iter = idx;
1661
return true;
1662
} break;
1663
case PACKED_BYTE_ARRAY: {
1664
const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
1665
int idx = r_iter;
1666
idx++;
1667
if (idx >= arr->size()) {
1668
return false;
1669
}
1670
r_iter = idx;
1671
return true;
1672
1673
} break;
1674
case PACKED_INT32_ARRAY: {
1675
const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
1676
int32_t idx = r_iter;
1677
idx++;
1678
if (idx >= arr->size()) {
1679
return false;
1680
}
1681
r_iter = idx;
1682
return true;
1683
1684
} break;
1685
case PACKED_INT64_ARRAY: {
1686
const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
1687
int64_t idx = r_iter;
1688
idx++;
1689
if (idx >= arr->size()) {
1690
return false;
1691
}
1692
r_iter = idx;
1693
return true;
1694
1695
} break;
1696
case PACKED_FLOAT32_ARRAY: {
1697
const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
1698
int idx = r_iter;
1699
idx++;
1700
if (idx >= arr->size()) {
1701
return false;
1702
}
1703
r_iter = idx;
1704
return true;
1705
1706
} break;
1707
case PACKED_FLOAT64_ARRAY: {
1708
const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
1709
int idx = r_iter;
1710
idx++;
1711
if (idx >= arr->size()) {
1712
return false;
1713
}
1714
r_iter = idx;
1715
return true;
1716
1717
} break;
1718
case PACKED_STRING_ARRAY: {
1719
const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
1720
int idx = r_iter;
1721
idx++;
1722
if (idx >= arr->size()) {
1723
return false;
1724
}
1725
r_iter = idx;
1726
return true;
1727
} break;
1728
case PACKED_VECTOR2_ARRAY: {
1729
const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
1730
int idx = r_iter;
1731
idx++;
1732
if (idx >= arr->size()) {
1733
return false;
1734
}
1735
r_iter = idx;
1736
return true;
1737
} break;
1738
case PACKED_VECTOR3_ARRAY: {
1739
const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
1740
int idx = r_iter;
1741
idx++;
1742
if (idx >= arr->size()) {
1743
return false;
1744
}
1745
r_iter = idx;
1746
return true;
1747
} break;
1748
case PACKED_COLOR_ARRAY: {
1749
const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
1750
int idx = r_iter;
1751
idx++;
1752
if (idx >= arr->size()) {
1753
return false;
1754
}
1755
r_iter = idx;
1756
return true;
1757
} break;
1758
case PACKED_VECTOR4_ARRAY: {
1759
const Vector<Vector4> *arr = &PackedArrayRef<Vector4>::get_array(_data.packed_array);
1760
int idx = r_iter;
1761
idx++;
1762
if (idx >= arr->size()) {
1763
return false;
1764
}
1765
r_iter = idx;
1766
return true;
1767
} break;
1768
default: {
1769
}
1770
}
1771
1772
valid = false;
1773
return false;
1774
}
1775
1776
Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
1777
r_valid = true;
1778
switch (type) {
1779
case INT: {
1780
return r_iter;
1781
} break;
1782
case FLOAT: {
1783
return r_iter;
1784
} break;
1785
case VECTOR2: {
1786
return r_iter;
1787
} break;
1788
case VECTOR2I: {
1789
return r_iter;
1790
} break;
1791
case VECTOR3: {
1792
return r_iter;
1793
} break;
1794
case VECTOR3I: {
1795
return r_iter;
1796
} break;
1797
case OBJECT: {
1798
if (!_get_obj().obj) {
1799
r_valid = false;
1800
return Variant();
1801
}
1802
#ifdef DEBUG_ENABLED
1803
if (EngineDebugger::is_active() && !_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
1804
r_valid = false;
1805
return Variant();
1806
}
1807
1808
#endif
1809
Callable::CallError ce;
1810
ce.error = Callable::CallError::CALL_OK;
1811
const Variant *refp[] = { &r_iter };
1812
Variant ret = _get_obj().obj->callp(CoreStringName(_iter_get), refp, 1, ce);
1813
1814
if (ce.error != Callable::CallError::CALL_OK) {
1815
r_valid = false;
1816
return Variant();
1817
}
1818
1819
//r_iter=ref[0];
1820
1821
return ret;
1822
} break;
1823
1824
case STRING: {
1825
const String *str = reinterpret_cast<const String *>(_data._mem);
1826
return str->substr(r_iter, 1);
1827
} break;
1828
case DICTIONARY: {
1829
return r_iter; //iterator is the same as the key
1830
1831
} break;
1832
case ARRAY: {
1833
const Array *arr = reinterpret_cast<const Array *>(_data._mem);
1834
int idx = r_iter;
1835
#ifdef DEBUG_ENABLED
1836
if (idx < 0 || idx >= arr->size()) {
1837
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for Array of size %d.", idx, arr->size()));
1838
r_valid = false;
1839
return Variant();
1840
}
1841
#endif
1842
return arr->get(idx);
1843
} break;
1844
case PACKED_BYTE_ARRAY: {
1845
const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
1846
int idx = r_iter;
1847
#ifdef DEBUG_ENABLED
1848
if (idx < 0 || idx >= arr->size()) {
1849
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedByteArray of size %d.", idx, arr->size()));
1850
r_valid = false;
1851
return Variant();
1852
}
1853
#endif
1854
return arr->get(idx);
1855
} break;
1856
case PACKED_INT32_ARRAY: {
1857
const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
1858
int32_t idx = r_iter;
1859
#ifdef DEBUG_ENABLED
1860
if (idx < 0 || idx >= arr->size()) {
1861
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedInt32Array of size %d.", idx, arr->size()));
1862
r_valid = false;
1863
return Variant();
1864
}
1865
#endif
1866
return arr->get(idx);
1867
} break;
1868
case PACKED_INT64_ARRAY: {
1869
const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
1870
int64_t idx = r_iter;
1871
#ifdef DEBUG_ENABLED
1872
if (idx < 0 || idx >= arr->size()) {
1873
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedInt64Array of size %d.", idx, arr->size()));
1874
r_valid = false;
1875
return Variant();
1876
}
1877
#endif
1878
return arr->get(idx);
1879
} break;
1880
case PACKED_FLOAT32_ARRAY: {
1881
const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
1882
int idx = r_iter;
1883
#ifdef DEBUG_ENABLED
1884
if (idx < 0 || idx >= arr->size()) {
1885
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedFloat32Array of size %d.", idx, arr->size()));
1886
r_valid = false;
1887
return Variant();
1888
}
1889
#endif
1890
return arr->get(idx);
1891
} break;
1892
case PACKED_FLOAT64_ARRAY: {
1893
const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
1894
int idx = r_iter;
1895
#ifdef DEBUG_ENABLED
1896
if (idx < 0 || idx >= arr->size()) {
1897
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedFloat64Array of size %d.", idx, arr->size()));
1898
r_valid = false;
1899
return Variant();
1900
}
1901
#endif
1902
return arr->get(idx);
1903
} break;
1904
case PACKED_STRING_ARRAY: {
1905
const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
1906
int idx = r_iter;
1907
#ifdef DEBUG_ENABLED
1908
if (idx < 0 || idx >= arr->size()) {
1909
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedStringArray of size %d.", idx, arr->size()));
1910
r_valid = false;
1911
return Variant();
1912
}
1913
#endif
1914
return arr->get(idx);
1915
} break;
1916
case PACKED_VECTOR2_ARRAY: {
1917
const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
1918
int idx = r_iter;
1919
#ifdef DEBUG_ENABLED
1920
if (idx < 0 || idx >= arr->size()) {
1921
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedVector2Array of size %d.", idx, arr->size()));
1922
r_valid = false;
1923
return Variant();
1924
}
1925
#endif
1926
return arr->get(idx);
1927
} break;
1928
case PACKED_VECTOR3_ARRAY: {
1929
const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
1930
int idx = r_iter;
1931
#ifdef DEBUG_ENABLED
1932
if (idx < 0 || idx >= arr->size()) {
1933
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedVector3Array of size %d.", idx, arr->size()));
1934
r_valid = false;
1935
return Variant();
1936
}
1937
#endif
1938
return arr->get(idx);
1939
} break;
1940
case PACKED_COLOR_ARRAY: {
1941
const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
1942
int idx = r_iter;
1943
#ifdef DEBUG_ENABLED
1944
if (idx < 0 || idx >= arr->size()) {
1945
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedColorArray of size %d.", idx, arr->size()));
1946
r_valid = false;
1947
return Variant();
1948
}
1949
#endif
1950
return arr->get(idx);
1951
} break;
1952
case PACKED_VECTOR4_ARRAY: {
1953
const Vector<Vector4> *arr = &PackedArrayRef<Vector4>::get_array(_data.packed_array);
1954
int idx = r_iter;
1955
#ifdef DEBUG_ENABLED
1956
if (idx < 0 || idx >= arr->size()) {
1957
ERR_PRINT(vformat("iter_get: Index %d is out of bounds for PackedVector4Array of size %d.", idx, arr->size()));
1958
r_valid = false;
1959
return Variant();
1960
}
1961
#endif
1962
return arr->get(idx);
1963
} break;
1964
default: {
1965
}
1966
}
1967
1968
r_valid = false;
1969
return Variant();
1970
}
1971
1972
Variant Variant::duplicate(bool p_deep) const {
1973
return recursive_duplicate(p_deep, RESOURCE_DEEP_DUPLICATE_NONE, 0);
1974
}
1975
1976
Variant Variant::duplicate_deep(ResourceDeepDuplicateMode p_deep_subresources_mode) const {
1977
ERR_FAIL_INDEX_V(p_deep_subresources_mode, RESOURCE_DEEP_DUPLICATE_MAX, Variant());
1978
return recursive_duplicate(true, p_deep_subresources_mode, 0);
1979
}
1980
1981
Variant Variant::recursive_duplicate(bool p_deep, ResourceDeepDuplicateMode p_deep_subresources_mode, int recursion_count) const {
1982
switch (type) {
1983
case OBJECT: {
1984
// If the root target of duplicate() is a Resource, we can't early-reject because that
1985
// resource itself must be duplicated, much as if Resource::duplicate() had been called.
1986
if (p_deep_subresources_mode == RESOURCE_DEEP_DUPLICATE_NONE && recursion_count > 0) {
1987
return *this;
1988
}
1989
Resource *res = Object::cast_to<Resource>(_get_obj().obj);
1990
if (res) {
1991
return res->_duplicate_from_variant(p_deep, p_deep_subresources_mode, recursion_count);
1992
} else {
1993
return *this;
1994
}
1995
} break;
1996
case DICTIONARY:
1997
return operator Dictionary().recursive_duplicate(p_deep, p_deep_subresources_mode, recursion_count);
1998
case ARRAY:
1999
return operator Array().recursive_duplicate(p_deep, p_deep_subresources_mode, recursion_count);
2000
case PACKED_BYTE_ARRAY:
2001
return operator Vector<uint8_t>().duplicate();
2002
case PACKED_INT32_ARRAY:
2003
return operator Vector<int32_t>().duplicate();
2004
case PACKED_INT64_ARRAY:
2005
return operator Vector<int64_t>().duplicate();
2006
case PACKED_FLOAT32_ARRAY:
2007
return operator Vector<float>().duplicate();
2008
case PACKED_FLOAT64_ARRAY:
2009
return operator Vector<double>().duplicate();
2010
case PACKED_STRING_ARRAY:
2011
return operator Vector<String>().duplicate();
2012
case PACKED_VECTOR2_ARRAY:
2013
return operator Vector<Vector2>().duplicate();
2014
case PACKED_VECTOR3_ARRAY:
2015
return operator Vector<Vector3>().duplicate();
2016
case PACKED_COLOR_ARRAY:
2017
return operator Vector<Color>().duplicate();
2018
case PACKED_VECTOR4_ARRAY:
2019
return operator Vector<Vector4>().duplicate();
2020
default:
2021
return *this;
2022
}
2023
}
2024
2025
void Variant::_register_variant_setters_getters() {
2026
register_named_setters_getters();
2027
register_indexed_setters_getters();
2028
register_keyed_setters_getters();
2029
}
2030
void Variant::_unregister_variant_setters_getters() {
2031
unregister_named_setters_getters();
2032
unregister_indexed_setters_getters();
2033
}
2034
2035