1/**************************************************************************/
2/* variant_construct.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_construct.h"
32
33struct VariantConstructData {
34 void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error) = nullptr;
35 Variant::ValidatedConstructor validated_construct = nullptr;
36 Variant::PTRConstructor ptr_construct = nullptr;
37 Variant::Type (*get_argument_type)(int) = nullptr;
38 int argument_count = 0;
39 Vector<String> arg_names;
40};
41
42static LocalVector<VariantConstructData> construct_data[Variant::VARIANT_MAX];
43
44template <class T>
45static void add_constructor(const Vector<String> &arg_names) {
46 ERR_FAIL_COND_MSG(arg_names.size() != T::get_argument_count(), "Argument names size mismatch for " + Variant::get_type_name(T::get_base_type()) + ".");
47
48 VariantConstructData cd;
49 cd.construct = T::construct;
50 cd.validated_construct = T::validated_construct;
51 cd.ptr_construct = T::ptr_construct;
52 cd.get_argument_type = T::get_argument_type;
53 cd.argument_count = T::get_argument_count();
54 cd.arg_names = arg_names;
55 construct_data[T::get_base_type()].push_back(cd);
56}
57
58void Variant::_register_variant_constructors() {
59 add_constructor<VariantConstructNoArgsNil>(sarray());
60 add_constructor<VariantConstructorNil>(sarray("from"));
61
62 add_constructor<VariantConstructNoArgs<bool>>(sarray());
63 add_constructor<VariantConstructor<bool, bool>>(sarray("from"));
64 add_constructor<VariantConstructor<bool, int64_t>>(sarray("from"));
65 add_constructor<VariantConstructor<bool, double>>(sarray("from"));
66
67 add_constructor<VariantConstructNoArgs<int64_t>>(sarray());
68 add_constructor<VariantConstructor<int64_t, int64_t>>(sarray("from"));
69 add_constructor<VariantConstructor<int64_t, double>>(sarray("from"));
70 add_constructor<VariantConstructor<int64_t, bool>>(sarray("from"));
71 add_constructor<VariantConstructorFromString<int64_t>>(sarray("from"));
72
73 add_constructor<VariantConstructNoArgs<double>>(sarray());
74 add_constructor<VariantConstructor<double, double>>(sarray("from"));
75 add_constructor<VariantConstructor<double, int64_t>>(sarray("from"));
76 add_constructor<VariantConstructor<double, bool>>(sarray("from"));
77 add_constructor<VariantConstructorFromString<double>>(sarray("from"));
78
79 add_constructor<VariantConstructNoArgs<String>>(sarray());
80 add_constructor<VariantConstructor<String, String>>(sarray("from"));
81 add_constructor<VariantConstructor<String, StringName>>(sarray("from"));
82 add_constructor<VariantConstructor<String, NodePath>>(sarray("from"));
83
84 add_constructor<VariantConstructNoArgs<Vector2>>(sarray());
85 add_constructor<VariantConstructor<Vector2, Vector2>>(sarray("from"));
86 add_constructor<VariantConstructor<Vector2, Vector2i>>(sarray("from"));
87 add_constructor<VariantConstructor<Vector2, double, double>>(sarray("x", "y"));
88
89 add_constructor<VariantConstructNoArgs<Vector2i>>(sarray());
90 add_constructor<VariantConstructor<Vector2i, Vector2i>>(sarray("from"));
91 add_constructor<VariantConstructor<Vector2i, Vector2>>(sarray("from"));
92 add_constructor<VariantConstructor<Vector2i, int64_t, int64_t>>(sarray("x", "y"));
93
94 add_constructor<VariantConstructNoArgs<Rect2>>(sarray());
95 add_constructor<VariantConstructor<Rect2, Rect2>>(sarray("from"));
96 add_constructor<VariantConstructor<Rect2, Rect2i>>(sarray("from"));
97 add_constructor<VariantConstructor<Rect2, Vector2, Vector2>>(sarray("position", "size"));
98 add_constructor<VariantConstructor<Rect2, double, double, double, double>>(sarray("x", "y", "width", "height"));
99
100 add_constructor<VariantConstructNoArgs<Rect2i>>(sarray());
101 add_constructor<VariantConstructor<Rect2i, Rect2i>>(sarray("from"));
102 add_constructor<VariantConstructor<Rect2i, Rect2>>(sarray("from"));
103 add_constructor<VariantConstructor<Rect2i, Vector2i, Vector2i>>(sarray("position", "size"));
104 add_constructor<VariantConstructor<Rect2i, int64_t, int64_t, int64_t, int64_t>>(sarray("x", "y", "width", "height"));
105
106 add_constructor<VariantConstructNoArgs<Vector3>>(sarray());
107 add_constructor<VariantConstructor<Vector3, Vector3>>(sarray("from"));
108 add_constructor<VariantConstructor<Vector3, Vector3i>>(sarray("from"));
109 add_constructor<VariantConstructor<Vector3, double, double, double>>(sarray("x", "y", "z"));
110
111 add_constructor<VariantConstructNoArgs<Vector3i>>(sarray());
112 add_constructor<VariantConstructor<Vector3i, Vector3i>>(sarray("from"));
113 add_constructor<VariantConstructor<Vector3i, Vector3>>(sarray("from"));
114 add_constructor<VariantConstructor<Vector3i, int64_t, int64_t, int64_t>>(sarray("x", "y", "z"));
115
116 add_constructor<VariantConstructNoArgs<Vector4>>(sarray());
117 add_constructor<VariantConstructor<Vector4, Vector4>>(sarray("from"));
118 add_constructor<VariantConstructor<Vector4, Vector4i>>(sarray("from"));
119 add_constructor<VariantConstructor<Vector4, double, double, double, double>>(sarray("x", "y", "z", "w"));
120
121 add_constructor<VariantConstructNoArgs<Vector4i>>(sarray());
122 add_constructor<VariantConstructor<Vector4i, Vector4i>>(sarray("from"));
123 add_constructor<VariantConstructor<Vector4i, Vector4>>(sarray("from"));
124 add_constructor<VariantConstructor<Vector4i, int64_t, int64_t, int64_t, int64_t>>(sarray("x", "y", "z", "w"));
125
126 add_constructor<VariantConstructNoArgs<Transform2D>>(sarray());
127 add_constructor<VariantConstructor<Transform2D, Transform2D>>(sarray("from"));
128 add_constructor<VariantConstructor<Transform2D, float, Vector2>>(sarray("rotation", "position"));
129 add_constructor<VariantConstructor<Transform2D, float, Size2, float, Vector2>>(sarray("rotation", "scale", "skew", "position"));
130 add_constructor<VariantConstructor<Transform2D, Vector2, Vector2, Vector2>>(sarray("x_axis", "y_axis", "origin"));
131
132 add_constructor<VariantConstructNoArgs<Plane>>(sarray());
133 add_constructor<VariantConstructor<Plane, Plane>>(sarray("from"));
134 add_constructor<VariantConstructor<Plane, Vector3>>(sarray("normal"));
135 add_constructor<VariantConstructor<Plane, Vector3, double>>(sarray("normal", "d"));
136 add_constructor<VariantConstructor<Plane, Vector3, Vector3>>(sarray("normal", "point"));
137 add_constructor<VariantConstructor<Plane, Vector3, Vector3, Vector3>>(sarray("point1", "point2", "point3"));
138 add_constructor<VariantConstructor<Plane, double, double, double, double>>(sarray("a", "b", "c", "d"));
139
140 add_constructor<VariantConstructNoArgs<Quaternion>>(sarray());
141 add_constructor<VariantConstructor<Quaternion, Quaternion>>(sarray("from"));
142 add_constructor<VariantConstructor<Quaternion, Basis>>(sarray("from"));
143 add_constructor<VariantConstructor<Quaternion, Vector3, double>>(sarray("axis", "angle"));
144 add_constructor<VariantConstructor<Quaternion, Vector3, Vector3>>(sarray("arc_from", "arc_to"));
145 add_constructor<VariantConstructor<Quaternion, double, double, double, double>>(sarray("x", "y", "z", "w"));
146
147 add_constructor<VariantConstructNoArgs<::AABB>>(sarray());
148 add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from"));
149 add_constructor<VariantConstructor<::AABB, Vector3, Vector3>>(sarray("position", "size"));
150
151 add_constructor<VariantConstructNoArgs<Basis>>(sarray());
152 add_constructor<VariantConstructor<Basis, Basis>>(sarray("from"));
153 add_constructor<VariantConstructor<Basis, Quaternion>>(sarray("from"));
154 add_constructor<VariantConstructor<Basis, Vector3, double>>(sarray("axis", "angle"));
155 add_constructor<VariantConstructor<Basis, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis"));
156
157 add_constructor<VariantConstructNoArgs<Transform3D>>(sarray());
158 add_constructor<VariantConstructor<Transform3D, Transform3D>>(sarray("from"));
159 add_constructor<VariantConstructor<Transform3D, Basis, Vector3>>(sarray("basis", "origin"));
160 add_constructor<VariantConstructor<Transform3D, Vector3, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis", "origin"));
161 add_constructor<VariantConstructor<Transform3D, Projection>>(sarray("from"));
162
163 add_constructor<VariantConstructNoArgs<Projection>>(sarray());
164 add_constructor<VariantConstructor<Projection, Projection>>(sarray("from"));
165 add_constructor<VariantConstructor<Projection, Transform3D>>(sarray("from"));
166 add_constructor<VariantConstructor<Projection, Vector4, Vector4, Vector4, Vector4>>(sarray("x_axis", "y_axis", "z_axis", "w_axis"));
167
168 add_constructor<VariantConstructNoArgs<Color>>(sarray());
169 add_constructor<VariantConstructor<Color, Color>>(sarray("from"));
170 add_constructor<VariantConstructor<Color, Color, double>>(sarray("from", "alpha"));
171 add_constructor<VariantConstructor<Color, double, double, double>>(sarray("r", "g", "b"));
172 add_constructor<VariantConstructor<Color, double, double, double, double>>(sarray("r", "g", "b", "a"));
173 add_constructor<VariantConstructor<Color, String>>(sarray("code"));
174 add_constructor<VariantConstructor<Color, String, double>>(sarray("code", "alpha"));
175
176 add_constructor<VariantConstructNoArgs<StringName>>(sarray());
177 add_constructor<VariantConstructor<StringName, StringName>>(sarray("from"));
178 add_constructor<VariantConstructor<StringName, String>>(sarray("from"));
179
180 add_constructor<VariantConstructNoArgs<NodePath>>(sarray());
181 add_constructor<VariantConstructor<NodePath, NodePath>>(sarray("from"));
182 add_constructor<VariantConstructor<NodePath, String>>(sarray("from"));
183
184 add_constructor<VariantConstructNoArgs<::RID>>(sarray());
185 add_constructor<VariantConstructor<::RID, ::RID>>(sarray("from"));
186
187 add_constructor<VariantConstructNoArgsObject>(sarray());
188 add_constructor<VariantConstructorObject>(sarray("from"));
189 add_constructor<VariantConstructorNilObject>(sarray("from"));
190
191 add_constructor<VariantConstructNoArgs<Callable>>(sarray());
192 add_constructor<VariantConstructor<Callable, Callable>>(sarray("from"));
193 add_constructor<VariantConstructorCallableArgs>(sarray("object", "method"));
194
195 add_constructor<VariantConstructNoArgs<Signal>>(sarray());
196 add_constructor<VariantConstructor<Signal, Signal>>(sarray("from"));
197 add_constructor<VariantConstructorSignalArgs>(sarray("object", "signal"));
198
199 add_constructor<VariantConstructNoArgs<Dictionary>>(sarray());
200 add_constructor<VariantConstructor<Dictionary, Dictionary>>(sarray("from"));
201
202 add_constructor<VariantConstructNoArgs<Array>>(sarray());
203 add_constructor<VariantConstructor<Array, Array>>(sarray("from"));
204 add_constructor<VariantConstructorTypedArray>(sarray("base", "type", "class_name", "script"));
205 add_constructor<VariantConstructorToArray<PackedByteArray>>(sarray("from"));
206 add_constructor<VariantConstructorToArray<PackedInt32Array>>(sarray("from"));
207 add_constructor<VariantConstructorToArray<PackedInt64Array>>(sarray("from"));
208 add_constructor<VariantConstructorToArray<PackedFloat32Array>>(sarray("from"));
209 add_constructor<VariantConstructorToArray<PackedFloat64Array>>(sarray("from"));
210 add_constructor<VariantConstructorToArray<PackedStringArray>>(sarray("from"));
211 add_constructor<VariantConstructorToArray<PackedVector2Array>>(sarray("from"));
212 add_constructor<VariantConstructorToArray<PackedVector3Array>>(sarray("from"));
213 add_constructor<VariantConstructorToArray<PackedColorArray>>(sarray("from"));
214
215 add_constructor<VariantConstructNoArgs<PackedByteArray>>(sarray());
216 add_constructor<VariantConstructor<PackedByteArray, PackedByteArray>>(sarray("from"));
217 add_constructor<VariantConstructorFromArray<PackedByteArray>>(sarray("from"));
218
219 add_constructor<VariantConstructNoArgs<PackedInt32Array>>(sarray());
220 add_constructor<VariantConstructor<PackedInt32Array, PackedInt32Array>>(sarray("from"));
221 add_constructor<VariantConstructorFromArray<PackedInt32Array>>(sarray("from"));
222
223 add_constructor<VariantConstructNoArgs<PackedInt64Array>>(sarray());
224 add_constructor<VariantConstructor<PackedInt64Array, PackedInt64Array>>(sarray("from"));
225 add_constructor<VariantConstructorFromArray<PackedInt64Array>>(sarray("from"));
226
227 add_constructor<VariantConstructNoArgs<PackedFloat32Array>>(sarray());
228 add_constructor<VariantConstructor<PackedFloat32Array, PackedFloat32Array>>(sarray("from"));
229 add_constructor<VariantConstructorFromArray<PackedFloat32Array>>(sarray("from"));
230
231 add_constructor<VariantConstructNoArgs<PackedFloat64Array>>(sarray());
232 add_constructor<VariantConstructor<PackedFloat64Array, PackedFloat64Array>>(sarray("from"));
233 add_constructor<VariantConstructorFromArray<PackedFloat64Array>>(sarray("from"));
234
235 add_constructor<VariantConstructNoArgs<PackedStringArray>>(sarray());
236 add_constructor<VariantConstructor<PackedStringArray, PackedStringArray>>(sarray("from"));
237 add_constructor<VariantConstructorFromArray<PackedStringArray>>(sarray("from"));
238
239 add_constructor<VariantConstructNoArgs<PackedVector2Array>>(sarray());
240 add_constructor<VariantConstructor<PackedVector2Array, PackedVector2Array>>(sarray("from"));
241 add_constructor<VariantConstructorFromArray<PackedVector2Array>>(sarray("from"));
242
243 add_constructor<VariantConstructNoArgs<PackedVector3Array>>(sarray());
244 add_constructor<VariantConstructor<PackedVector3Array, PackedVector3Array>>(sarray("from"));
245 add_constructor<VariantConstructorFromArray<PackedVector3Array>>(sarray("from"));
246
247 add_constructor<VariantConstructNoArgs<PackedColorArray>>(sarray());
248 add_constructor<VariantConstructor<PackedColorArray, PackedColorArray>>(sarray("from"));
249 add_constructor<VariantConstructorFromArray<PackedColorArray>>(sarray("from"));
250}
251
252void Variant::_unregister_variant_constructors() {
253 for (int i = 0; i < Variant::VARIANT_MAX; i++) {
254 construct_data[i].clear();
255 }
256}
257
258void Variant::construct(Variant::Type p_type, Variant &base, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
259 ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX);
260 uint32_t s = construct_data[p_type].size();
261 for (uint32_t i = 0; i < s; i++) {
262 int argc = construct_data[p_type][i].argument_count;
263 if (argc != p_argcount) {
264 continue;
265 }
266 bool args_match = true;
267 for (int j = 0; j < argc; j++) {
268 if (!Variant::can_convert_strict(p_args[j]->get_type(), construct_data[p_type][i].get_argument_type(j))) {
269 args_match = false;
270 break;
271 }
272 }
273
274 if (!args_match) {
275 continue;
276 }
277
278 construct_data[p_type][i].construct(base, p_args, r_error);
279 return;
280 }
281
282 r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
283}
284
285int Variant::get_constructor_count(Variant::Type p_type) {
286 ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1);
287 return construct_data[p_type].size();
288}
289
290Variant::ValidatedConstructor Variant::get_validated_constructor(Variant::Type p_type, int p_constructor) {
291 ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
292 ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), nullptr);
293 return construct_data[p_type][p_constructor].validated_construct;
294}
295
296Variant::PTRConstructor Variant::get_ptr_constructor(Variant::Type p_type, int p_constructor) {
297 ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
298 ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), nullptr);
299 return construct_data[p_type][p_constructor].ptr_construct;
300}
301
302int Variant::get_constructor_argument_count(Variant::Type p_type, int p_constructor) {
303 ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1);
304 ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), -1);
305 return construct_data[p_type][p_constructor].argument_count;
306}
307
308Variant::Type Variant::get_constructor_argument_type(Variant::Type p_type, int p_constructor, int p_argument) {
309 ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::VARIANT_MAX);
310 ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), Variant::VARIANT_MAX);
311 return construct_data[p_type][p_constructor].get_argument_type(p_argument);
312}
313
314String Variant::get_constructor_argument_name(Variant::Type p_type, int p_constructor, int p_argument) {
315 ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, String());
316 ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), String());
317 return construct_data[p_type][p_constructor].arg_names[p_argument];
318}
319
320void VariantInternal::refcounted_object_assign(Variant *v, const RefCounted *rc) {
321 if (!rc || !const_cast<RefCounted *>(rc)->init_ref()) {
322 v->_get_obj().obj = nullptr;
323 v->_get_obj().id = ObjectID();
324 return;
325 }
326
327 v->_get_obj().obj = const_cast<RefCounted *>(rc);
328 v->_get_obj().id = rc->get_instance_id();
329}
330
331void VariantInternal::object_assign(Variant *v, const Object *o) {
332 if (o) {
333 if (o->is_ref_counted()) {
334 RefCounted *ref_counted = const_cast<RefCounted *>(static_cast<const RefCounted *>(o));
335 if (!ref_counted->init_ref()) {
336 v->_get_obj().obj = nullptr;
337 v->_get_obj().id = ObjectID();
338 return;
339 }
340 }
341
342 v->_get_obj().obj = const_cast<Object *>(o);
343 v->_get_obj().id = o->get_instance_id();
344 } else {
345 v->_get_obj().obj = nullptr;
346 v->_get_obj().id = ObjectID();
347 }
348}
349
350void Variant::get_constructor_list(Type p_type, List<MethodInfo> *r_list) {
351 ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX);
352
353 MethodInfo mi;
354 mi.return_val.type = p_type;
355 mi.name = get_type_name(p_type);
356
357 for (int i = 0; i < get_constructor_count(p_type); i++) {
358 int ac = get_constructor_argument_count(p_type, i);
359 mi.arguments.clear();
360 for (int j = 0; j < ac; j++) {
361 PropertyInfo arg;
362 arg.name = get_constructor_argument_name(p_type, i, j);
363 arg.type = get_constructor_argument_type(p_type, i, j);
364 mi.arguments.push_back(arg);
365 }
366 r_list->push_back(mi);
367 }
368}
369