1/**************************************************************************/
2/* variant_construct.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef VARIANT_CONSTRUCT_H
32#define VARIANT_CONSTRUCT_H
33
34#include "variant.h"
35
36#include "core/core_string_names.h"
37#include "core/crypto/crypto_core.h"
38#include "core/debugger/engine_debugger.h"
39#include "core/io/compression.h"
40#include "core/object/class_db.h"
41#include "core/os/os.h"
42#include "core/templates/local_vector.h"
43#include "core/templates/oa_hash_map.h"
44
45template <class T>
46struct PtrConstruct {};
47
48#define MAKE_PTRCONSTRUCT(m_type) \
49 template <> \
50 struct PtrConstruct<m_type> { \
51 _FORCE_INLINE_ static void construct(const m_type &p_value, void *p_ptr) { \
52 memnew_placement(p_ptr, m_type(p_value)); \
53 } \
54 };
55
56MAKE_PTRCONSTRUCT(bool);
57MAKE_PTRCONSTRUCT(int64_t);
58MAKE_PTRCONSTRUCT(double);
59MAKE_PTRCONSTRUCT(String);
60MAKE_PTRCONSTRUCT(Vector2);
61MAKE_PTRCONSTRUCT(Vector2i);
62MAKE_PTRCONSTRUCT(Rect2);
63MAKE_PTRCONSTRUCT(Rect2i);
64MAKE_PTRCONSTRUCT(Vector3);
65MAKE_PTRCONSTRUCT(Vector3i);
66MAKE_PTRCONSTRUCT(Vector4);
67MAKE_PTRCONSTRUCT(Vector4i);
68MAKE_PTRCONSTRUCT(Transform2D);
69MAKE_PTRCONSTRUCT(Plane);
70MAKE_PTRCONSTRUCT(Quaternion);
71MAKE_PTRCONSTRUCT(AABB);
72MAKE_PTRCONSTRUCT(Basis);
73MAKE_PTRCONSTRUCT(Transform3D);
74MAKE_PTRCONSTRUCT(Projection);
75MAKE_PTRCONSTRUCT(Color);
76MAKE_PTRCONSTRUCT(StringName);
77MAKE_PTRCONSTRUCT(NodePath);
78MAKE_PTRCONSTRUCT(RID);
79
80template <>
81struct PtrConstruct<Object *> {
82 _FORCE_INLINE_ static void construct(Object *p_value, void *p_ptr) {
83 *((Object **)p_ptr) = p_value;
84 }
85};
86
87MAKE_PTRCONSTRUCT(Callable);
88MAKE_PTRCONSTRUCT(Signal);
89MAKE_PTRCONSTRUCT(Dictionary);
90MAKE_PTRCONSTRUCT(Array);
91MAKE_PTRCONSTRUCT(PackedByteArray);
92MAKE_PTRCONSTRUCT(PackedInt32Array);
93MAKE_PTRCONSTRUCT(PackedInt64Array);
94MAKE_PTRCONSTRUCT(PackedFloat32Array);
95MAKE_PTRCONSTRUCT(PackedFloat64Array);
96MAKE_PTRCONSTRUCT(PackedStringArray);
97MAKE_PTRCONSTRUCT(PackedVector2Array);
98MAKE_PTRCONSTRUCT(PackedVector3Array);
99MAKE_PTRCONSTRUCT(PackedColorArray);
100MAKE_PTRCONSTRUCT(Variant);
101
102template <class T, class... P>
103class VariantConstructor {
104 template <size_t... Is>
105 static _FORCE_INLINE_ void construct_helper(T &base, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
106 r_error.error = Callable::CallError::CALL_OK;
107
108#ifdef DEBUG_METHODS_ENABLED
109 base = T(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
110#else
111 base = T(VariantCaster<P>::cast(*p_args[Is])...);
112#endif
113 }
114
115 template <size_t... Is>
116 static _FORCE_INLINE_ void validated_construct_helper(T &base, const Variant **p_args, IndexSequence<Is...>) {
117 base = T((*VariantGetInternalPtr<P>::get_ptr(p_args[Is]))...);
118 }
119
120 template <size_t... Is>
121 static _FORCE_INLINE_ void ptr_construct_helper(void *base, const void **p_args, IndexSequence<Is...>) {
122 PtrConstruct<T>::construct(T(PtrToArg<P>::convert(p_args[Is])...), base);
123 }
124
125public:
126 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
127 r_error.error = Callable::CallError::CALL_OK;
128 VariantTypeChanger<T>::change(&r_ret);
129 construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
130 }
131
132 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
133 VariantTypeChanger<T>::change(r_ret);
134 validated_construct_helper(*VariantGetInternalPtr<T>::get_ptr(r_ret), p_args, BuildIndexSequence<sizeof...(P)>{});
135 }
136 static void ptr_construct(void *base, const void **p_args) {
137 ptr_construct_helper(base, p_args, BuildIndexSequence<sizeof...(P)>{});
138 }
139
140 static int get_argument_count() {
141 return sizeof...(P);
142 }
143
144 static Variant::Type get_argument_type(int p_arg) {
145 return call_get_argument_type<P...>(p_arg);
146 }
147
148 static Variant::Type get_base_type() {
149 return GetTypeInfo<T>::VARIANT_TYPE;
150 }
151};
152
153class VariantConstructorObject {
154public:
155 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
156 VariantInternal::clear(&r_ret);
157 if (p_args[0]->get_type() == Variant::NIL) {
158 VariantInternal::object_assign_null(&r_ret);
159 r_error.error = Callable::CallError::CALL_OK;
160 } else if (p_args[0]->get_type() == Variant::OBJECT) {
161 VariantInternal::object_assign(&r_ret, p_args[0]);
162 r_error.error = Callable::CallError::CALL_OK;
163 } else {
164 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
165 r_error.argument = 0;
166 r_error.expected = Variant::OBJECT;
167 }
168 }
169
170 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
171 VariantInternal::clear(r_ret);
172 VariantInternal::object_assign(r_ret, p_args[0]);
173 }
174 static void ptr_construct(void *base, const void **p_args) {
175 PtrConstruct<Object *>::construct(PtrToArg<Object *>::convert(p_args[0]), base);
176 }
177
178 static int get_argument_count() {
179 return 1;
180 }
181
182 static Variant::Type get_argument_type(int p_arg) {
183 return Variant::OBJECT;
184 }
185
186 static Variant::Type get_base_type() {
187 return Variant::OBJECT;
188 }
189};
190
191class VariantConstructorNilObject {
192public:
193 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
194 if (p_args[0]->get_type() != Variant::NIL) {
195 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
196 r_error.argument = 0;
197 r_error.expected = Variant::NIL;
198 }
199
200 VariantInternal::clear(&r_ret);
201 VariantInternal::object_assign_null(&r_ret);
202 }
203
204 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
205 VariantInternal::clear(r_ret);
206 VariantInternal::object_assign_null(r_ret);
207 }
208 static void ptr_construct(void *base, const void **p_args) {
209 PtrConstruct<Object *>::construct(nullptr, base);
210 }
211
212 static int get_argument_count() {
213 return 1;
214 }
215
216 static Variant::Type get_argument_type(int p_arg) {
217 return Variant::NIL;
218 }
219
220 static Variant::Type get_base_type() {
221 return Variant::OBJECT;
222 }
223};
224
225template <class T>
226class VariantConstructorFromString {
227public:
228 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
229 if (p_args[0]->get_type() != Variant::STRING) {
230 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
231 r_error.argument = 0;
232 r_error.expected = Variant::STRING;
233 return;
234 }
235
236 VariantTypeChanger<T>::change(&r_ret);
237 const String &src_str = *VariantGetInternalPtr<String>::get_ptr(p_args[0]);
238
239 if (r_ret.get_type() == Variant::Type::INT) {
240 r_ret = src_str.to_int();
241 } else if (r_ret.get_type() == Variant::Type::FLOAT) {
242 r_ret = src_str.to_float();
243 }
244 }
245
246 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
247 VariantTypeChanger<T>::change(r_ret);
248 const String &src_str = *VariantGetInternalPtr<String>::get_ptr(p_args[0]);
249 T ret = Variant();
250 if (r_ret->get_type() == Variant::Type::INT) {
251 ret = src_str.to_int();
252 } else if (r_ret->get_type() == Variant::Type::FLOAT) {
253 ret = src_str.to_float();
254 }
255 *r_ret = ret;
256 }
257
258 static void ptr_construct(void *base, const void **p_args) {
259 String src_str = PtrToArg<String>::convert(p_args[0]);
260 T dst_var = Variant();
261 Variant type_test = Variant(dst_var);
262 if (type_test.get_type() == Variant::Type::INT) {
263 dst_var = src_str.to_int();
264 } else if (type_test.get_type() == Variant::Type::FLOAT) {
265 dst_var = src_str.to_float();
266 }
267 PtrConstruct<T>::construct(dst_var, base);
268 }
269
270 static int get_argument_count() {
271 return 1;
272 }
273
274 static Variant::Type get_argument_type(int p_arg) {
275 return Variant::STRING;
276 }
277
278 static Variant::Type get_base_type() {
279 return GetTypeInfo<T>::VARIANT_TYPE;
280 }
281};
282
283class VariantConstructorCallableArgs {
284public:
285 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
286 ObjectID object_id;
287 StringName method;
288
289 if (p_args[0]->get_type() == Variant::NIL) {
290 // leave as is
291 } else if (p_args[0]->get_type() == Variant::OBJECT) {
292 object_id = VariantInternal::get_object_id(p_args[0]);
293 } else {
294 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
295 r_error.argument = 0;
296 r_error.expected = Variant::OBJECT;
297 return;
298 }
299
300 if (p_args[1]->get_type() == Variant::STRING_NAME) {
301 method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]);
302 } else if (p_args[1]->get_type() == Variant::STRING) {
303 method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]);
304 } else {
305 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
306 r_error.argument = 1;
307 r_error.expected = Variant::STRING_NAME;
308 return;
309 }
310
311 VariantTypeChanger<Callable>::change(&r_ret);
312 *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(object_id, method);
313 }
314
315 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
316 VariantTypeChanger<Callable>::change(r_ret);
317 *VariantGetInternalPtr<Callable>::get_ptr(r_ret) = Callable(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]));
318 }
319 static void ptr_construct(void *base, const void **p_args) {
320 PtrConstruct<Callable>::construct(Callable(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base);
321 }
322
323 static int get_argument_count() {
324 return 2;
325 }
326
327 static Variant::Type get_argument_type(int p_arg) {
328 if (p_arg == 0) {
329 return Variant::OBJECT;
330 } else {
331 return Variant::STRING_NAME;
332 }
333 }
334
335 static Variant::Type get_base_type() {
336 return Variant::CALLABLE;
337 }
338};
339
340class VariantConstructorSignalArgs {
341public:
342 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
343 ObjectID object_id;
344 StringName method;
345
346 if (p_args[0]->get_type() == Variant::NIL) {
347 // leave as is
348 } else if (p_args[0]->get_type() == Variant::OBJECT) {
349 object_id = VariantInternal::get_object_id(p_args[0]);
350 } else {
351 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
352 r_error.argument = 0;
353 r_error.expected = Variant::OBJECT;
354 return;
355 }
356
357 if (p_args[1]->get_type() == Variant::STRING_NAME) {
358 method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]);
359 } else if (p_args[1]->get_type() == Variant::STRING) {
360 method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]);
361 } else {
362 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
363 r_error.argument = 1;
364 r_error.expected = Variant::STRING_NAME;
365 return;
366 }
367
368 VariantTypeChanger<Signal>::change(&r_ret);
369 *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(object_id, method);
370 }
371
372 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
373 VariantTypeChanger<Signal>::change(r_ret);
374 *VariantGetInternalPtr<Signal>::get_ptr(r_ret) = Signal(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]));
375 }
376 static void ptr_construct(void *base, const void **p_args) {
377 PtrConstruct<Signal>::construct(Signal(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base);
378 }
379
380 static int get_argument_count() {
381 return 2;
382 }
383
384 static Variant::Type get_argument_type(int p_arg) {
385 if (p_arg == 0) {
386 return Variant::OBJECT;
387 } else {
388 return Variant::STRING_NAME;
389 }
390 }
391
392 static Variant::Type get_base_type() {
393 return Variant::SIGNAL;
394 }
395};
396
397class VariantConstructorTypedArray {
398public:
399 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
400 if (p_args[0]->get_type() != Variant::ARRAY) {
401 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
402 r_error.argument = 0;
403 r_error.expected = Variant::ARRAY;
404 return;
405 }
406
407 if (p_args[1]->get_type() != Variant::INT) {
408 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
409 r_error.argument = 1;
410 r_error.expected = Variant::INT;
411 return;
412 }
413
414 if (p_args[2]->get_type() != Variant::STRING_NAME) {
415 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
416 r_error.argument = 2;
417 r_error.expected = Variant::STRING_NAME;
418 return;
419 }
420
421 const Array &base_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]);
422 const uint32_t type = p_args[1]->operator uint32_t();
423 const StringName &class_name = *VariantGetInternalPtr<StringName>::get_ptr(p_args[2]);
424 r_ret = Array(base_arr, type, class_name, *p_args[3]);
425 }
426
427 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
428 const Array &base_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]);
429 const uint32_t type = p_args[1]->operator uint32_t();
430 const StringName &class_name = *VariantGetInternalPtr<StringName>::get_ptr(p_args[2]);
431 *r_ret = Array(base_arr, type, class_name, *p_args[3]);
432 }
433
434 static void ptr_construct(void *base, const void **p_args) {
435 const Array &base_arr = PtrToArg<Array>::convert(p_args[0]);
436 const uint32_t type = PtrToArg<uint32_t>::convert(p_args[1]);
437 const StringName &class_name = PtrToArg<StringName>::convert(p_args[2]);
438 const Variant &script = PtrToArg<Variant>::convert(p_args[3]);
439 Array dst_arr = Array(base_arr, type, class_name, script);
440
441 PtrConstruct<Array>::construct(dst_arr, base);
442 }
443
444 static int get_argument_count() {
445 return 4;
446 }
447
448 static Variant::Type get_argument_type(int p_arg) {
449 switch (p_arg) {
450 case 0: {
451 return Variant::ARRAY;
452 } break;
453 case 1: {
454 return Variant::INT;
455 } break;
456 case 2: {
457 return Variant::STRING_NAME;
458 } break;
459 case 3: {
460 return Variant::NIL;
461 } break;
462 default: {
463 return Variant::NIL;
464 } break;
465 }
466 }
467
468 static Variant::Type get_base_type() {
469 return Variant::ARRAY;
470 }
471};
472
473template <class T>
474class VariantConstructorToArray {
475public:
476 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
477 if (p_args[0]->get_type() != GetTypeInfo<T>::VARIANT_TYPE) {
478 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
479 r_error.argument = 0;
480 r_error.expected = GetTypeInfo<T>::VARIANT_TYPE;
481 return;
482 }
483
484 r_ret = Array();
485 Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret);
486 const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]);
487
488 int size = src_arr.size();
489 dst_arr.resize(size);
490 for (int i = 0; i < size; i++) {
491 dst_arr[i] = src_arr[i];
492 }
493 }
494
495 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
496 *r_ret = Array();
497 Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(r_ret);
498 const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]);
499
500 int size = src_arr.size();
501 dst_arr.resize(size);
502 for (int i = 0; i < size; i++) {
503 dst_arr[i] = src_arr[i];
504 }
505 }
506 static void ptr_construct(void *base, const void **p_args) {
507 Array dst_arr;
508 T src_arr = PtrToArg<T>::convert(p_args[0]);
509
510 int size = src_arr.size();
511 dst_arr.resize(size);
512 for (int i = 0; i < size; i++) {
513 dst_arr[i] = src_arr[i];
514 }
515
516 PtrConstruct<Array>::construct(dst_arr, base);
517 }
518
519 static int get_argument_count() {
520 return 1;
521 }
522
523 static Variant::Type get_argument_type(int p_arg) {
524 return GetTypeInfo<T>::VARIANT_TYPE;
525 }
526
527 static Variant::Type get_base_type() {
528 return Variant::ARRAY;
529 }
530};
531
532template <class T>
533class VariantConstructorFromArray {
534public:
535 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
536 if (p_args[0]->get_type() != Variant::ARRAY) {
537 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
538 r_error.argument = 0;
539 r_error.expected = Variant::ARRAY;
540 return;
541 }
542
543 VariantTypeChanger<T>::change(&r_ret);
544 const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]);
545 T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret);
546
547 int size = src_arr.size();
548 dst_arr.resize(size);
549 for (int i = 0; i < size; i++) {
550 dst_arr.write[i] = src_arr[i];
551 }
552 }
553
554 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
555 VariantTypeChanger<T>::change(r_ret);
556 const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]);
557 T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(r_ret);
558
559 int size = src_arr.size();
560 dst_arr.resize(size);
561 for (int i = 0; i < size; i++) {
562 dst_arr.write[i] = src_arr[i];
563 }
564 }
565 static void ptr_construct(void *base, const void **p_args) {
566 Array src_arr = PtrToArg<Array>::convert(p_args[0]);
567 T dst_arr;
568
569 int size = src_arr.size();
570 dst_arr.resize(size);
571 for (int i = 0; i < size; i++) {
572 dst_arr.write[i] = src_arr[i];
573 }
574
575 PtrConstruct<T>::construct(dst_arr, base);
576 }
577
578 static int get_argument_count() {
579 return 1;
580 }
581
582 static Variant::Type get_argument_type(int p_arg) {
583 return Variant::ARRAY;
584 }
585
586 static Variant::Type get_base_type() {
587 return GetTypeInfo<T>::VARIANT_TYPE;
588 }
589};
590
591class VariantConstructorNil {
592public:
593 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
594 if (p_args[0]->get_type() != Variant::NIL) {
595 r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
596 r_error.argument = 0;
597 r_error.expected = Variant::NIL;
598 return;
599 }
600
601 r_error.error = Callable::CallError::CALL_OK;
602 VariantInternal::clear(&r_ret);
603 }
604
605 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
606 VariantInternal::clear(r_ret);
607 }
608 static void ptr_construct(void *base, const void **p_args) {
609 PtrConstruct<Variant>::construct(Variant(), base);
610 }
611
612 static int get_argument_count() {
613 return 1;
614 }
615
616 static Variant::Type get_argument_type(int p_arg) {
617 return Variant::NIL;
618 }
619
620 static Variant::Type get_base_type() {
621 return Variant::NIL;
622 }
623};
624
625template <class T>
626class VariantConstructNoArgs {
627public:
628 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
629 VariantTypeChanger<T>::change_and_reset(&r_ret);
630 r_error.error = Callable::CallError::CALL_OK;
631 }
632
633 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
634 VariantTypeChanger<T>::change_and_reset(r_ret);
635 }
636 static void ptr_construct(void *base, const void **p_args) {
637 PtrConstruct<T>::construct(T(), base);
638 }
639
640 static int get_argument_count() {
641 return 0;
642 }
643
644 static Variant::Type get_argument_type(int p_arg) {
645 return Variant::NIL;
646 }
647
648 static Variant::Type get_base_type() {
649 return GetTypeInfo<T>::VARIANT_TYPE;
650 }
651};
652
653class VariantConstructNoArgsNil {
654public:
655 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
656 VariantInternal::clear(&r_ret);
657 r_error.error = Callable::CallError::CALL_OK;
658 }
659
660 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
661 VariantInternal::clear(r_ret);
662 }
663 static void ptr_construct(void *base, const void **p_args) {
664 ERR_FAIL_MSG("can't ptrcall nil constructor");
665 }
666
667 static int get_argument_count() {
668 return 0;
669 }
670
671 static Variant::Type get_argument_type(int p_arg) {
672 return Variant::NIL;
673 }
674
675 static Variant::Type get_base_type() {
676 return Variant::NIL;
677 }
678};
679
680class VariantConstructNoArgsObject {
681public:
682 static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
683 r_ret = (Object *)nullptr; // Must construct a TYPE_OBJECT containing nullptr.
684 r_error.error = Callable::CallError::CALL_OK;
685 }
686
687 static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
688 *r_ret = (Object *)nullptr; // Must construct a TYPE_OBJECT containing nullptr.
689 }
690 static void ptr_construct(void *base, const void **p_args) {
691 PtrConstruct<Object *>::construct(nullptr, base);
692 }
693
694 static int get_argument_count() {
695 return 0;
696 }
697
698 static Variant::Type get_argument_type(int p_arg) {
699 return Variant::NIL;
700 }
701
702 static Variant::Type get_base_type() {
703 return Variant::OBJECT;
704 }
705};
706
707#endif // VARIANT_CONSTRUCT_H
708