1 | /**************************************************************************/ |
2 | /* variant_utility.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_utility.h" |
32 | |
33 | #include "core/core_string_names.h" |
34 | #include "core/io/marshalls.h" |
35 | #include "core/object/ref_counted.h" |
36 | #include "core/os/os.h" |
37 | #include "core/templates/oa_hash_map.h" |
38 | #include "core/templates/rid.h" |
39 | #include "core/templates/rid_owner.h" |
40 | #include "core/variant/binder_common.h" |
41 | #include "core/variant/variant_parser.h" |
42 | |
43 | // Math |
44 | double VariantUtilityFunctions::sin(double arg) { |
45 | return Math::sin(arg); |
46 | } |
47 | |
48 | double VariantUtilityFunctions::cos(double arg) { |
49 | return Math::cos(arg); |
50 | } |
51 | |
52 | double VariantUtilityFunctions::tan(double arg) { |
53 | return Math::tan(arg); |
54 | } |
55 | |
56 | double VariantUtilityFunctions::sinh(double arg) { |
57 | return Math::sinh(arg); |
58 | } |
59 | |
60 | double VariantUtilityFunctions::cosh(double arg) { |
61 | return Math::cosh(arg); |
62 | } |
63 | |
64 | double VariantUtilityFunctions::tanh(double arg) { |
65 | return Math::tanh(arg); |
66 | } |
67 | |
68 | double VariantUtilityFunctions::asin(double arg) { |
69 | return Math::asin(arg); |
70 | } |
71 | |
72 | double VariantUtilityFunctions::acos(double arg) { |
73 | return Math::acos(arg); |
74 | } |
75 | |
76 | double VariantUtilityFunctions::atan(double arg) { |
77 | return Math::atan(arg); |
78 | } |
79 | |
80 | double VariantUtilityFunctions::atan2(double y, double x) { |
81 | return Math::atan2(y, x); |
82 | } |
83 | |
84 | double VariantUtilityFunctions::asinh(double arg) { |
85 | return Math::asinh(arg); |
86 | } |
87 | |
88 | double VariantUtilityFunctions::acosh(double arg) { |
89 | return Math::acosh(arg); |
90 | } |
91 | |
92 | double VariantUtilityFunctions::atanh(double arg) { |
93 | return Math::atanh(arg); |
94 | } |
95 | |
96 | double VariantUtilityFunctions::sqrt(double x) { |
97 | return Math::sqrt(x); |
98 | } |
99 | |
100 | double VariantUtilityFunctions::fmod(double b, double r) { |
101 | return Math::fmod(b, r); |
102 | } |
103 | |
104 | double VariantUtilityFunctions::fposmod(double b, double r) { |
105 | return Math::fposmod(b, r); |
106 | } |
107 | |
108 | int64_t VariantUtilityFunctions::posmod(int64_t b, int64_t r) { |
109 | return Math::posmod(b, r); |
110 | } |
111 | |
112 | Variant VariantUtilityFunctions::floor(Variant x, Callable::CallError &r_error) { |
113 | r_error.error = Callable::CallError::CALL_OK; |
114 | switch (x.get_type()) { |
115 | case Variant::INT: { |
116 | return VariantInternalAccessor<int64_t>::get(&x); |
117 | } break; |
118 | case Variant::FLOAT: { |
119 | return Math::floor(VariantInternalAccessor<double>::get(&x)); |
120 | } break; |
121 | case Variant::VECTOR2: { |
122 | return VariantInternalAccessor<Vector2>::get(&x).floor(); |
123 | } break; |
124 | case Variant::VECTOR3: { |
125 | return VariantInternalAccessor<Vector3>::get(&x).floor(); |
126 | } break; |
127 | case Variant::VECTOR4: { |
128 | return VariantInternalAccessor<Vector4>::get(&x).floor(); |
129 | } break; |
130 | default: { |
131 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; |
132 | return Variant(); |
133 | } |
134 | } |
135 | } |
136 | |
137 | double VariantUtilityFunctions::floorf(double x) { |
138 | return Math::floor(x); |
139 | } |
140 | |
141 | int64_t VariantUtilityFunctions::floori(double x) { |
142 | return int64_t(Math::floor(x)); |
143 | } |
144 | |
145 | Variant VariantUtilityFunctions::ceil(Variant x, Callable::CallError &r_error) { |
146 | r_error.error = Callable::CallError::CALL_OK; |
147 | switch (x.get_type()) { |
148 | case Variant::INT: { |
149 | return VariantInternalAccessor<int64_t>::get(&x); |
150 | } break; |
151 | case Variant::FLOAT: { |
152 | return Math::ceil(VariantInternalAccessor<double>::get(&x)); |
153 | } break; |
154 | case Variant::VECTOR2: { |
155 | return VariantInternalAccessor<Vector2>::get(&x).ceil(); |
156 | } break; |
157 | case Variant::VECTOR3: { |
158 | return VariantInternalAccessor<Vector3>::get(&x).ceil(); |
159 | } break; |
160 | case Variant::VECTOR4: { |
161 | return VariantInternalAccessor<Vector4>::get(&x).ceil(); |
162 | } break; |
163 | default: { |
164 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; |
165 | return Variant(); |
166 | } |
167 | } |
168 | } |
169 | |
170 | double VariantUtilityFunctions::ceilf(double x) { |
171 | return Math::ceil(x); |
172 | } |
173 | |
174 | int64_t VariantUtilityFunctions::ceili(double x) { |
175 | return int64_t(Math::ceil(x)); |
176 | } |
177 | |
178 | Variant VariantUtilityFunctions::round(Variant x, Callable::CallError &r_error) { |
179 | r_error.error = Callable::CallError::CALL_OK; |
180 | switch (x.get_type()) { |
181 | case Variant::INT: { |
182 | return VariantInternalAccessor<int64_t>::get(&x); |
183 | } break; |
184 | case Variant::FLOAT: { |
185 | return Math::round(VariantInternalAccessor<double>::get(&x)); |
186 | } break; |
187 | case Variant::VECTOR2: { |
188 | return VariantInternalAccessor<Vector2>::get(&x).round(); |
189 | } break; |
190 | case Variant::VECTOR3: { |
191 | return VariantInternalAccessor<Vector3>::get(&x).round(); |
192 | } break; |
193 | case Variant::VECTOR4: { |
194 | return VariantInternalAccessor<Vector4>::get(&x).round(); |
195 | } break; |
196 | default: { |
197 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; |
198 | return Variant(); |
199 | } |
200 | } |
201 | } |
202 | |
203 | double VariantUtilityFunctions::roundf(double x) { |
204 | return Math::round(x); |
205 | } |
206 | |
207 | int64_t VariantUtilityFunctions::roundi(double x) { |
208 | return int64_t(Math::round(x)); |
209 | } |
210 | |
211 | Variant VariantUtilityFunctions::abs(const Variant &x, Callable::CallError &r_error) { |
212 | r_error.error = Callable::CallError::CALL_OK; |
213 | switch (x.get_type()) { |
214 | case Variant::INT: { |
215 | return ABS(VariantInternalAccessor<int64_t>::get(&x)); |
216 | } break; |
217 | case Variant::FLOAT: { |
218 | return Math::absd(VariantInternalAccessor<double>::get(&x)); |
219 | } break; |
220 | case Variant::VECTOR2: { |
221 | return VariantInternalAccessor<Vector2>::get(&x).abs(); |
222 | } break; |
223 | case Variant::VECTOR2I: { |
224 | return VariantInternalAccessor<Vector2i>::get(&x).abs(); |
225 | } break; |
226 | case Variant::VECTOR3: { |
227 | return VariantInternalAccessor<Vector3>::get(&x).abs(); |
228 | } break; |
229 | case Variant::VECTOR3I: { |
230 | return VariantInternalAccessor<Vector3i>::get(&x).abs(); |
231 | } break; |
232 | case Variant::VECTOR4: { |
233 | return VariantInternalAccessor<Vector4>::get(&x).abs(); |
234 | } break; |
235 | case Variant::VECTOR4I: { |
236 | return VariantInternalAccessor<Vector4i>::get(&x).abs(); |
237 | } break; |
238 | default: { |
239 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; |
240 | return Variant(); |
241 | } |
242 | } |
243 | } |
244 | |
245 | double VariantUtilityFunctions::absf(double x) { |
246 | return Math::absd(x); |
247 | } |
248 | |
249 | int64_t VariantUtilityFunctions::absi(int64_t x) { |
250 | return ABS(x); |
251 | } |
252 | |
253 | Variant VariantUtilityFunctions::sign(const Variant &x, Callable::CallError &r_error) { |
254 | r_error.error = Callable::CallError::CALL_OK; |
255 | switch (x.get_type()) { |
256 | case Variant::INT: { |
257 | return SIGN(VariantInternalAccessor<int64_t>::get(&x)); |
258 | } break; |
259 | case Variant::FLOAT: { |
260 | return SIGN(VariantInternalAccessor<double>::get(&x)); |
261 | } break; |
262 | case Variant::VECTOR2: { |
263 | return VariantInternalAccessor<Vector2>::get(&x).sign(); |
264 | } break; |
265 | case Variant::VECTOR2I: { |
266 | return VariantInternalAccessor<Vector2i>::get(&x).sign(); |
267 | } break; |
268 | case Variant::VECTOR3: { |
269 | return VariantInternalAccessor<Vector3>::get(&x).sign(); |
270 | } break; |
271 | case Variant::VECTOR3I: { |
272 | return VariantInternalAccessor<Vector3i>::get(&x).sign(); |
273 | } break; |
274 | case Variant::VECTOR4: { |
275 | return VariantInternalAccessor<Vector4>::get(&x).sign(); |
276 | } break; |
277 | case Variant::VECTOR4I: { |
278 | return VariantInternalAccessor<Vector4i>::get(&x).sign(); |
279 | } break; |
280 | default: { |
281 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; |
282 | return Variant(); |
283 | } |
284 | } |
285 | } |
286 | |
287 | double VariantUtilityFunctions::signf(double x) { |
288 | return SIGN(x); |
289 | } |
290 | |
291 | int64_t VariantUtilityFunctions::signi(int64_t x) { |
292 | return SIGN(x); |
293 | } |
294 | |
295 | double VariantUtilityFunctions::pow(double x, double y) { |
296 | return Math::pow(x, y); |
297 | } |
298 | |
299 | double VariantUtilityFunctions::log(double x) { |
300 | return Math::log(x); |
301 | } |
302 | |
303 | double VariantUtilityFunctions::exp(double x) { |
304 | return Math::exp(x); |
305 | } |
306 | |
307 | bool VariantUtilityFunctions::is_nan(double x) { |
308 | return Math::is_nan(x); |
309 | } |
310 | |
311 | bool VariantUtilityFunctions::is_inf(double x) { |
312 | return Math::is_inf(x); |
313 | } |
314 | |
315 | bool VariantUtilityFunctions::is_equal_approx(double x, double y) { |
316 | return Math::is_equal_approx(x, y); |
317 | } |
318 | |
319 | bool VariantUtilityFunctions::is_zero_approx(double x) { |
320 | return Math::is_zero_approx(x); |
321 | } |
322 | |
323 | bool VariantUtilityFunctions::is_finite(double x) { |
324 | return Math::is_finite(x); |
325 | } |
326 | |
327 | double VariantUtilityFunctions::ease(float x, float curve) { |
328 | return Math::ease(x, curve); |
329 | } |
330 | |
331 | int VariantUtilityFunctions::step_decimals(float step) { |
332 | return Math::step_decimals(step); |
333 | } |
334 | |
335 | Variant VariantUtilityFunctions::snapped(const Variant &x, const Variant &step, Callable::CallError &r_error) { |
336 | r_error.error = Callable::CallError::CALL_OK; |
337 | if (x.get_type() != step.get_type() && !((x.get_type() == Variant::INT && step.get_type() == Variant::FLOAT) || (x.get_type() == Variant::FLOAT && step.get_type() == Variant::INT))) { |
338 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
339 | r_error.argument = 1; |
340 | return Variant(); |
341 | } |
342 | |
343 | switch (step.get_type()) { |
344 | case Variant::INT: { |
345 | return snappedi(x, VariantInternalAccessor<int64_t>::get(&step)); |
346 | } break; |
347 | case Variant::FLOAT: { |
348 | return snappedf(x, VariantInternalAccessor<double>::get(&step)); |
349 | } break; |
350 | case Variant::VECTOR2: { |
351 | return VariantInternalAccessor<Vector2>::get(&x).snapped(VariantInternalAccessor<Vector2>::get(&step)); |
352 | } break; |
353 | case Variant::VECTOR2I: { |
354 | return VariantInternalAccessor<Vector2i>::get(&x).snapped(VariantInternalAccessor<Vector2i>::get(&step)); |
355 | } break; |
356 | case Variant::VECTOR3: { |
357 | return VariantInternalAccessor<Vector3>::get(&x).snapped(VariantInternalAccessor<Vector3>::get(&step)); |
358 | } break; |
359 | case Variant::VECTOR3I: { |
360 | return VariantInternalAccessor<Vector3i>::get(&x).snapped(VariantInternalAccessor<Vector3i>::get(&step)); |
361 | } break; |
362 | case Variant::VECTOR4: { |
363 | return VariantInternalAccessor<Vector4>::get(&x).snapped(VariantInternalAccessor<Vector4>::get(&step)); |
364 | } break; |
365 | case Variant::VECTOR4I: { |
366 | return VariantInternalAccessor<Vector4i>::get(&x).snapped(VariantInternalAccessor<Vector4i>::get(&step)); |
367 | } break; |
368 | default: { |
369 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; |
370 | return Variant(); |
371 | } |
372 | } |
373 | } |
374 | |
375 | double VariantUtilityFunctions::snappedf(double x, double step) { |
376 | return Math::snapped(x, step); |
377 | } |
378 | |
379 | int64_t VariantUtilityFunctions::snappedi(double x, int64_t step) { |
380 | return Math::snapped(x, step); |
381 | } |
382 | |
383 | Variant VariantUtilityFunctions::lerp(const Variant &from, const Variant &to, double weight, Callable::CallError &r_error) { |
384 | r_error.error = Callable::CallError::CALL_OK; |
385 | if (from.get_type() != to.get_type()) { |
386 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
387 | r_error.expected = from.get_type(); |
388 | r_error.argument = 1; |
389 | return Variant(); |
390 | } |
391 | |
392 | switch (from.get_type()) { |
393 | case Variant::INT: { |
394 | return lerpf(VariantInternalAccessor<int64_t>::get(&from), to, weight); |
395 | } break; |
396 | case Variant::FLOAT: { |
397 | return lerpf(VariantInternalAccessor<double>::get(&from), to, weight); |
398 | } break; |
399 | case Variant::VECTOR2: { |
400 | return VariantInternalAccessor<Vector2>::get(&from).lerp(VariantInternalAccessor<Vector2>::get(&to), weight); |
401 | } break; |
402 | case Variant::VECTOR3: { |
403 | return VariantInternalAccessor<Vector3>::get(&from).lerp(VariantInternalAccessor<Vector3>::get(&to), weight); |
404 | } break; |
405 | case Variant::VECTOR4: { |
406 | return VariantInternalAccessor<Vector4>::get(&from).lerp(VariantInternalAccessor<Vector4>::get(&to), weight); |
407 | } break; |
408 | case Variant::QUATERNION: { |
409 | return VariantInternalAccessor<Quaternion>::get(&from).slerp(VariantInternalAccessor<Quaternion>::get(&to), weight); |
410 | } break; |
411 | case Variant::BASIS: { |
412 | return VariantInternalAccessor<Basis>::get(&from).slerp(VariantInternalAccessor<Basis>::get(&to), weight); |
413 | } break; |
414 | case Variant::COLOR: { |
415 | return VariantInternalAccessor<Color>::get(&from).lerp(VariantInternalAccessor<Color>::get(&to), weight); |
416 | } break; |
417 | default: { |
418 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; |
419 | return Variant(); |
420 | } |
421 | } |
422 | } |
423 | |
424 | double VariantUtilityFunctions::lerpf(double from, double to, double weight) { |
425 | return Math::lerp(from, to, weight); |
426 | } |
427 | |
428 | double VariantUtilityFunctions::cubic_interpolate(double from, double to, double pre, double post, double weight) { |
429 | return Math::cubic_interpolate(from, to, pre, post, weight); |
430 | } |
431 | |
432 | double VariantUtilityFunctions::cubic_interpolate_angle(double from, double to, double pre, double post, double weight) { |
433 | return Math::cubic_interpolate_angle(from, to, pre, post, weight); |
434 | } |
435 | |
436 | double VariantUtilityFunctions::cubic_interpolate_in_time(double from, double to, double pre, double post, double weight, |
437 | double to_t, double pre_t, double post_t) { |
438 | return Math::cubic_interpolate_in_time(from, to, pre, post, weight, to_t, pre_t, post_t); |
439 | } |
440 | |
441 | double VariantUtilityFunctions::cubic_interpolate_angle_in_time(double from, double to, double pre, double post, double weight, |
442 | double to_t, double pre_t, double post_t) { |
443 | return Math::cubic_interpolate_angle_in_time(from, to, pre, post, weight, to_t, pre_t, post_t); |
444 | } |
445 | |
446 | double VariantUtilityFunctions::bezier_interpolate(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { |
447 | return Math::bezier_interpolate(p_start, p_control_1, p_control_2, p_end, p_t); |
448 | } |
449 | |
450 | double VariantUtilityFunctions::bezier_derivative(double p_start, double p_control_1, double p_control_2, double p_end, double p_t) { |
451 | return Math::bezier_derivative(p_start, p_control_1, p_control_2, p_end, p_t); |
452 | } |
453 | |
454 | double VariantUtilityFunctions::lerp_angle(double from, double to, double weight) { |
455 | return Math::lerp_angle(from, to, weight); |
456 | } |
457 | |
458 | double VariantUtilityFunctions::inverse_lerp(double from, double to, double weight) { |
459 | return Math::inverse_lerp(from, to, weight); |
460 | } |
461 | |
462 | double VariantUtilityFunctions::remap(double value, double istart, double istop, double ostart, double ostop) { |
463 | return Math::remap(value, istart, istop, ostart, ostop); |
464 | } |
465 | |
466 | double VariantUtilityFunctions::smoothstep(double from, double to, double val) { |
467 | return Math::smoothstep(from, to, val); |
468 | } |
469 | |
470 | double VariantUtilityFunctions::move_toward(double from, double to, double delta) { |
471 | return Math::move_toward(from, to, delta); |
472 | } |
473 | |
474 | double VariantUtilityFunctions::deg_to_rad(double angle_deg) { |
475 | return Math::deg_to_rad(angle_deg); |
476 | } |
477 | |
478 | double VariantUtilityFunctions::rad_to_deg(double angle_rad) { |
479 | return Math::rad_to_deg(angle_rad); |
480 | } |
481 | |
482 | double VariantUtilityFunctions::linear_to_db(double linear) { |
483 | return Math::linear_to_db(linear); |
484 | } |
485 | |
486 | double VariantUtilityFunctions::db_to_linear(double db) { |
487 | return Math::db_to_linear(db); |
488 | } |
489 | |
490 | Variant VariantUtilityFunctions::wrap(const Variant &p_x, const Variant &p_min, const Variant &p_max, Callable::CallError &r_error) { |
491 | Variant::Type x_type = p_x.get_type(); |
492 | if (x_type != Variant::INT && x_type != Variant::FLOAT) { |
493 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
494 | r_error.argument = 0; |
495 | r_error.expected = x_type; |
496 | return Variant(); |
497 | } |
498 | |
499 | Variant::Type min_type = p_min.get_type(); |
500 | if (min_type != Variant::INT && min_type != Variant::FLOAT) { |
501 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
502 | r_error.argument = 1; |
503 | r_error.expected = x_type; |
504 | return Variant(); |
505 | } |
506 | |
507 | Variant::Type max_type = p_max.get_type(); |
508 | if (max_type != Variant::INT && max_type != Variant::FLOAT) { |
509 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
510 | r_error.argument = 2; |
511 | r_error.expected = x_type; |
512 | return Variant(); |
513 | } |
514 | |
515 | Variant value; |
516 | |
517 | switch (x_type) { |
518 | case Variant::INT: { |
519 | if (x_type != min_type || x_type != max_type) { |
520 | value = wrapf((double)p_x, (double)p_min, (double)p_max); |
521 | } else { |
522 | value = wrapi((int)p_x, (int)p_min, (int)p_max); |
523 | } |
524 | } break; |
525 | case Variant::FLOAT: { |
526 | value = wrapf((double)p_x, (double)p_min, (double)p_max); |
527 | } break; |
528 | default: |
529 | break; |
530 | } |
531 | |
532 | r_error.error = Callable::CallError::CALL_OK; |
533 | return value; |
534 | } |
535 | |
536 | int64_t VariantUtilityFunctions::wrapi(int64_t value, int64_t min, int64_t max) { |
537 | return Math::wrapi(value, min, max); |
538 | } |
539 | |
540 | double VariantUtilityFunctions::wrapf(double value, double min, double max) { |
541 | return Math::wrapf(value, min, max); |
542 | } |
543 | |
544 | double VariantUtilityFunctions::pingpong(double value, double length) { |
545 | return Math::pingpong(value, length); |
546 | } |
547 | |
548 | Variant VariantUtilityFunctions::max(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { |
549 | if (p_argcount < 2) { |
550 | r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; |
551 | r_error.expected = 2; |
552 | return Variant(); |
553 | } |
554 | Variant base = *p_args[0]; |
555 | Variant ret; |
556 | |
557 | for (int i = 0; i < p_argcount; i++) { |
558 | Variant::Type arg_type = p_args[i]->get_type(); |
559 | if (arg_type != Variant::INT && arg_type != Variant::FLOAT) { |
560 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
561 | r_error.expected = Variant::FLOAT; |
562 | r_error.argument = i; |
563 | return Variant(); |
564 | } |
565 | if (i == 0) { |
566 | continue; |
567 | } |
568 | bool valid; |
569 | Variant::evaluate(Variant::OP_LESS, base, *p_args[i], ret, valid); |
570 | if (!valid) { |
571 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
572 | r_error.expected = base.get_type(); |
573 | r_error.argument = i; |
574 | return Variant(); |
575 | } |
576 | if (ret.booleanize()) { |
577 | base = *p_args[i]; |
578 | } |
579 | } |
580 | r_error.error = Callable::CallError::CALL_OK; |
581 | return base; |
582 | } |
583 | |
584 | double VariantUtilityFunctions::maxf(double x, double y) { |
585 | return MAX(x, y); |
586 | } |
587 | |
588 | int64_t VariantUtilityFunctions::maxi(int64_t x, int64_t y) { |
589 | return MAX(x, y); |
590 | } |
591 | |
592 | Variant VariantUtilityFunctions::min(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { |
593 | if (p_argcount < 2) { |
594 | r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; |
595 | r_error.expected = 2; |
596 | return Variant(); |
597 | } |
598 | Variant base = *p_args[0]; |
599 | Variant ret; |
600 | |
601 | for (int i = 0; i < p_argcount; i++) { |
602 | Variant::Type arg_type = p_args[i]->get_type(); |
603 | if (arg_type != Variant::INT && arg_type != Variant::FLOAT) { |
604 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
605 | r_error.expected = Variant::FLOAT; |
606 | r_error.argument = i; |
607 | return Variant(); |
608 | } |
609 | if (i == 0) { |
610 | continue; |
611 | } |
612 | bool valid; |
613 | Variant::evaluate(Variant::OP_GREATER, base, *p_args[i], ret, valid); |
614 | if (!valid) { |
615 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
616 | r_error.expected = base.get_type(); |
617 | r_error.argument = i; |
618 | return Variant(); |
619 | } |
620 | if (ret.booleanize()) { |
621 | base = *p_args[i]; |
622 | } |
623 | } |
624 | r_error.error = Callable::CallError::CALL_OK; |
625 | return base; |
626 | } |
627 | |
628 | double VariantUtilityFunctions::minf(double x, double y) { |
629 | return MIN(x, y); |
630 | } |
631 | |
632 | int64_t VariantUtilityFunctions::mini(int64_t x, int64_t y) { |
633 | return MIN(x, y); |
634 | } |
635 | |
636 | Variant VariantUtilityFunctions::clamp(const Variant &x, const Variant &min, const Variant &max, Callable::CallError &r_error) { |
637 | Variant value = x; |
638 | |
639 | Variant ret; |
640 | |
641 | bool valid; |
642 | Variant::evaluate(Variant::OP_LESS, value, min, ret, valid); |
643 | if (!valid) { |
644 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
645 | r_error.expected = value.get_type(); |
646 | r_error.argument = 1; |
647 | return Variant(); |
648 | } |
649 | if (ret.booleanize()) { |
650 | value = min; |
651 | } |
652 | Variant::evaluate(Variant::OP_GREATER, value, max, ret, valid); |
653 | if (!valid) { |
654 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
655 | r_error.expected = value.get_type(); |
656 | r_error.argument = 2; |
657 | return Variant(); |
658 | } |
659 | if (ret.booleanize()) { |
660 | value = max; |
661 | } |
662 | |
663 | r_error.error = Callable::CallError::CALL_OK; |
664 | |
665 | return value; |
666 | } |
667 | |
668 | double VariantUtilityFunctions::clampf(double x, double min, double max) { |
669 | return CLAMP(x, min, max); |
670 | } |
671 | |
672 | int64_t VariantUtilityFunctions::clampi(int64_t x, int64_t min, int64_t max) { |
673 | return CLAMP(x, min, max); |
674 | } |
675 | |
676 | int64_t VariantUtilityFunctions::nearest_po2(int64_t x) { |
677 | return nearest_power_of_2_templated(uint64_t(x)); |
678 | } |
679 | |
680 | // Random |
681 | |
682 | void VariantUtilityFunctions::randomize() { |
683 | Math::randomize(); |
684 | } |
685 | |
686 | int64_t VariantUtilityFunctions::randi() { |
687 | return Math::rand(); |
688 | } |
689 | |
690 | double VariantUtilityFunctions::randf() { |
691 | return Math::randf(); |
692 | } |
693 | |
694 | double VariantUtilityFunctions::randfn(double mean, double deviation) { |
695 | return Math::randfn(mean, deviation); |
696 | } |
697 | |
698 | int64_t VariantUtilityFunctions::randi_range(int64_t from, int64_t to) { |
699 | return Math::random((int32_t)from, (int32_t)to); |
700 | } |
701 | |
702 | double VariantUtilityFunctions::randf_range(double from, double to) { |
703 | return Math::random(from, to); |
704 | } |
705 | |
706 | void VariantUtilityFunctions::seed(int64_t s) { |
707 | return Math::seed(s); |
708 | } |
709 | |
710 | PackedInt64Array VariantUtilityFunctions::rand_from_seed(int64_t seed) { |
711 | uint64_t s = seed; |
712 | PackedInt64Array arr; |
713 | arr.resize(2); |
714 | arr.write[0] = Math::rand_from_seed(&s); |
715 | arr.write[1] = s; |
716 | return arr; |
717 | } |
718 | |
719 | // Utility |
720 | |
721 | Variant VariantUtilityFunctions::weakref(const Variant &obj, Callable::CallError &r_error) { |
722 | if (obj.get_type() == Variant::OBJECT) { |
723 | r_error.error = Callable::CallError::CALL_OK; |
724 | if (obj.is_ref_counted()) { |
725 | Ref<WeakRef> wref = memnew(WeakRef); |
726 | Ref<RefCounted> r = obj; |
727 | if (r.is_valid()) { |
728 | wref->set_ref(r); |
729 | } |
730 | return wref; |
731 | } else { |
732 | Ref<WeakRef> wref = memnew(WeakRef); |
733 | Object *o = obj.get_validated_object(); |
734 | if (o) { |
735 | wref->set_obj(o); |
736 | } |
737 | return wref; |
738 | } |
739 | } else if (obj.get_type() == Variant::NIL) { |
740 | r_error.error = Callable::CallError::CALL_OK; |
741 | Ref<WeakRef> wref = memnew(WeakRef); |
742 | return wref; |
743 | } else { |
744 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; |
745 | r_error.argument = 0; |
746 | r_error.expected = Variant::OBJECT; |
747 | return Variant(); |
748 | } |
749 | } |
750 | |
751 | int64_t VariantUtilityFunctions::_typeof(const Variant &obj) { |
752 | return obj.get_type(); |
753 | } |
754 | |
755 | Variant VariantUtilityFunctions::type_convert(const Variant &p_variant, const Variant::Type p_type) { |
756 | switch (p_type) { |
757 | case Variant::Type::NIL: |
758 | return Variant(); |
759 | case Variant::Type::BOOL: |
760 | return p_variant.operator bool(); |
761 | case Variant::Type::INT: |
762 | return p_variant.operator int64_t(); |
763 | case Variant::Type::FLOAT: |
764 | return p_variant.operator double(); |
765 | case Variant::Type::STRING: |
766 | return p_variant.operator String(); |
767 | case Variant::Type::VECTOR2: |
768 | return p_variant.operator Vector2(); |
769 | case Variant::Type::VECTOR2I: |
770 | return p_variant.operator Vector2i(); |
771 | case Variant::Type::RECT2: |
772 | return p_variant.operator Rect2(); |
773 | case Variant::Type::RECT2I: |
774 | return p_variant.operator Rect2i(); |
775 | case Variant::Type::VECTOR3: |
776 | return p_variant.operator Vector3(); |
777 | case Variant::Type::VECTOR3I: |
778 | return p_variant.operator Vector3i(); |
779 | case Variant::Type::TRANSFORM2D: |
780 | return p_variant.operator Transform2D(); |
781 | case Variant::Type::VECTOR4: |
782 | return p_variant.operator Vector4(); |
783 | case Variant::Type::VECTOR4I: |
784 | return p_variant.operator Vector4i(); |
785 | case Variant::Type::PLANE: |
786 | return p_variant.operator Plane(); |
787 | case Variant::Type::QUATERNION: |
788 | return p_variant.operator Quaternion(); |
789 | case Variant::Type::AABB: |
790 | return p_variant.operator ::AABB(); |
791 | case Variant::Type::BASIS: |
792 | return p_variant.operator Basis(); |
793 | case Variant::Type::TRANSFORM3D: |
794 | return p_variant.operator Transform3D(); |
795 | case Variant::Type::PROJECTION: |
796 | return p_variant.operator Projection(); |
797 | case Variant::Type::COLOR: |
798 | return p_variant.operator Color(); |
799 | case Variant::Type::STRING_NAME: |
800 | return p_variant.operator StringName(); |
801 | case Variant::Type::NODE_PATH: |
802 | return p_variant.operator NodePath(); |
803 | case Variant::Type::RID: |
804 | return p_variant.operator ::RID(); |
805 | case Variant::Type::OBJECT: |
806 | return p_variant.operator Object *(); |
807 | case Variant::Type::CALLABLE: |
808 | return p_variant.operator Callable(); |
809 | case Variant::Type::SIGNAL: |
810 | return p_variant.operator Signal(); |
811 | case Variant::Type::DICTIONARY: |
812 | return p_variant.operator Dictionary(); |
813 | case Variant::Type::ARRAY: |
814 | return p_variant.operator Array(); |
815 | case Variant::Type::PACKED_BYTE_ARRAY: |
816 | return p_variant.operator PackedByteArray(); |
817 | case Variant::Type::PACKED_INT32_ARRAY: |
818 | return p_variant.operator PackedInt32Array(); |
819 | case Variant::Type::PACKED_INT64_ARRAY: |
820 | return p_variant.operator PackedInt64Array(); |
821 | case Variant::Type::PACKED_FLOAT32_ARRAY: |
822 | return p_variant.operator PackedFloat32Array(); |
823 | case Variant::Type::PACKED_FLOAT64_ARRAY: |
824 | return p_variant.operator PackedFloat64Array(); |
825 | case Variant::Type::PACKED_STRING_ARRAY: |
826 | return p_variant.operator PackedStringArray(); |
827 | case Variant::Type::PACKED_VECTOR2_ARRAY: |
828 | return p_variant.operator PackedVector2Array(); |
829 | case Variant::Type::PACKED_VECTOR3_ARRAY: |
830 | return p_variant.operator PackedVector3Array(); |
831 | case Variant::Type::PACKED_COLOR_ARRAY: |
832 | return p_variant.operator PackedColorArray(); |
833 | case Variant::Type::VARIANT_MAX: |
834 | ERR_PRINT("Invalid type argument to type_convert(), use the TYPE_* constants. Returning the unconverted Variant." ); |
835 | } |
836 | return p_variant; |
837 | } |
838 | |
839 | String VariantUtilityFunctions::str(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
840 | if (p_arg_count < 1) { |
841 | r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; |
842 | r_error.argument = 1; |
843 | return String(); |
844 | } |
845 | String s; |
846 | for (int i = 0; i < p_arg_count; i++) { |
847 | String os = p_args[i]->operator String(); |
848 | |
849 | if (i == 0) { |
850 | s = os; |
851 | } else { |
852 | s += os; |
853 | } |
854 | } |
855 | |
856 | r_error.error = Callable::CallError::CALL_OK; |
857 | |
858 | return s; |
859 | } |
860 | |
861 | String VariantUtilityFunctions::error_string(Error error) { |
862 | if (error < 0 || error >= ERR_MAX) { |
863 | return String("(invalid error code)" ); |
864 | } |
865 | |
866 | return String(error_names[error]); |
867 | } |
868 | |
869 | void VariantUtilityFunctions::print(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
870 | String s; |
871 | for (int i = 0; i < p_arg_count; i++) { |
872 | String os = p_args[i]->operator String(); |
873 | |
874 | if (i == 0) { |
875 | s = os; |
876 | } else { |
877 | s += os; |
878 | } |
879 | } |
880 | |
881 | print_line(s); |
882 | r_error.error = Callable::CallError::CALL_OK; |
883 | } |
884 | |
885 | void VariantUtilityFunctions::print_rich(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
886 | String s; |
887 | for (int i = 0; i < p_arg_count; i++) { |
888 | String os = p_args[i]->operator String(); |
889 | |
890 | if (i == 0) { |
891 | s = os; |
892 | } else { |
893 | s += os; |
894 | } |
895 | } |
896 | |
897 | print_line_rich(s); |
898 | r_error.error = Callable::CallError::CALL_OK; |
899 | } |
900 | |
901 | #undef print_verbose |
902 | |
903 | void VariantUtilityFunctions::print_verbose(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
904 | if (OS::get_singleton()->is_stdout_verbose()) { |
905 | String s; |
906 | for (int i = 0; i < p_arg_count; i++) { |
907 | String os = p_args[i]->operator String(); |
908 | |
909 | if (i == 0) { |
910 | s = os; |
911 | } else { |
912 | s += os; |
913 | } |
914 | } |
915 | |
916 | // No need to use `print_verbose()` as this call already only happens |
917 | // when verbose mode is enabled. This avoids performing string argument concatenation |
918 | // when not needed. |
919 | print_line(s); |
920 | } |
921 | |
922 | r_error.error = Callable::CallError::CALL_OK; |
923 | } |
924 | |
925 | void VariantUtilityFunctions::printerr(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
926 | String s; |
927 | for (int i = 0; i < p_arg_count; i++) { |
928 | String os = p_args[i]->operator String(); |
929 | |
930 | if (i == 0) { |
931 | s = os; |
932 | } else { |
933 | s += os; |
934 | } |
935 | } |
936 | |
937 | print_error(s); |
938 | r_error.error = Callable::CallError::CALL_OK; |
939 | } |
940 | |
941 | void VariantUtilityFunctions::printt(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
942 | String s; |
943 | for (int i = 0; i < p_arg_count; i++) { |
944 | if (i) { |
945 | s += "\t" ; |
946 | } |
947 | s += p_args[i]->operator String(); |
948 | } |
949 | |
950 | print_line(s); |
951 | r_error.error = Callable::CallError::CALL_OK; |
952 | } |
953 | |
954 | void VariantUtilityFunctions::prints(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
955 | String s; |
956 | for (int i = 0; i < p_arg_count; i++) { |
957 | if (i) { |
958 | s += " " ; |
959 | } |
960 | s += p_args[i]->operator String(); |
961 | } |
962 | |
963 | print_line(s); |
964 | r_error.error = Callable::CallError::CALL_OK; |
965 | } |
966 | |
967 | void VariantUtilityFunctions::printraw(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
968 | String s; |
969 | for (int i = 0; i < p_arg_count; i++) { |
970 | String os = p_args[i]->operator String(); |
971 | |
972 | if (i == 0) { |
973 | s = os; |
974 | } else { |
975 | s += os; |
976 | } |
977 | } |
978 | |
979 | OS::get_singleton()->print("%s" , s.utf8().get_data()); |
980 | r_error.error = Callable::CallError::CALL_OK; |
981 | } |
982 | |
983 | void VariantUtilityFunctions::push_error(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
984 | if (p_arg_count < 1) { |
985 | r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; |
986 | r_error.argument = 1; |
987 | } |
988 | String s; |
989 | for (int i = 0; i < p_arg_count; i++) { |
990 | String os = p_args[i]->operator String(); |
991 | |
992 | if (i == 0) { |
993 | s = os; |
994 | } else { |
995 | s += os; |
996 | } |
997 | } |
998 | |
999 | ERR_PRINT(s); |
1000 | r_error.error = Callable::CallError::CALL_OK; |
1001 | } |
1002 | |
1003 | void VariantUtilityFunctions::push_warning(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { |
1004 | if (p_arg_count < 1) { |
1005 | r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; |
1006 | r_error.argument = 1; |
1007 | } |
1008 | String s; |
1009 | for (int i = 0; i < p_arg_count; i++) { |
1010 | String os = p_args[i]->operator String(); |
1011 | |
1012 | if (i == 0) { |
1013 | s = os; |
1014 | } else { |
1015 | s += os; |
1016 | } |
1017 | } |
1018 | |
1019 | WARN_PRINT(s); |
1020 | r_error.error = Callable::CallError::CALL_OK; |
1021 | } |
1022 | |
1023 | String VariantUtilityFunctions::var_to_str(const Variant &p_var) { |
1024 | String vars; |
1025 | VariantWriter::write_to_string(p_var, vars); |
1026 | return vars; |
1027 | } |
1028 | |
1029 | Variant VariantUtilityFunctions::str_to_var(const String &p_var) { |
1030 | VariantParser::StreamString ss; |
1031 | ss.s = p_var; |
1032 | |
1033 | String errs; |
1034 | int line; |
1035 | Variant ret; |
1036 | (void)VariantParser::parse(&ss, ret, errs, line); |
1037 | |
1038 | return ret; |
1039 | } |
1040 | |
1041 | PackedByteArray VariantUtilityFunctions::var_to_bytes(const Variant &p_var) { |
1042 | int len; |
1043 | Error err = encode_variant(p_var, nullptr, len, false); |
1044 | if (err != OK) { |
1045 | return PackedByteArray(); |
1046 | } |
1047 | |
1048 | PackedByteArray barr; |
1049 | barr.resize(len); |
1050 | { |
1051 | uint8_t *w = barr.ptrw(); |
1052 | err = encode_variant(p_var, w, len, false); |
1053 | if (err != OK) { |
1054 | return PackedByteArray(); |
1055 | } |
1056 | } |
1057 | |
1058 | return barr; |
1059 | } |
1060 | |
1061 | PackedByteArray VariantUtilityFunctions::var_to_bytes_with_objects(const Variant &p_var) { |
1062 | int len; |
1063 | Error err = encode_variant(p_var, nullptr, len, true); |
1064 | if (err != OK) { |
1065 | return PackedByteArray(); |
1066 | } |
1067 | |
1068 | PackedByteArray barr; |
1069 | barr.resize(len); |
1070 | { |
1071 | uint8_t *w = barr.ptrw(); |
1072 | err = encode_variant(p_var, w, len, true); |
1073 | if (err != OK) { |
1074 | return PackedByteArray(); |
1075 | } |
1076 | } |
1077 | |
1078 | return barr; |
1079 | } |
1080 | |
1081 | Variant VariantUtilityFunctions::bytes_to_var(const PackedByteArray &p_arr) { |
1082 | Variant ret; |
1083 | { |
1084 | const uint8_t *r = p_arr.ptr(); |
1085 | Error err = decode_variant(ret, r, p_arr.size(), nullptr, false); |
1086 | if (err != OK) { |
1087 | return Variant(); |
1088 | } |
1089 | } |
1090 | return ret; |
1091 | } |
1092 | |
1093 | Variant VariantUtilityFunctions::bytes_to_var_with_objects(const PackedByteArray &p_arr) { |
1094 | Variant ret; |
1095 | { |
1096 | const uint8_t *r = p_arr.ptr(); |
1097 | Error err = decode_variant(ret, r, p_arr.size(), nullptr, true); |
1098 | if (err != OK) { |
1099 | return Variant(); |
1100 | } |
1101 | } |
1102 | return ret; |
1103 | } |
1104 | |
1105 | int64_t VariantUtilityFunctions::hash(const Variant &p_arr) { |
1106 | return p_arr.hash(); |
1107 | } |
1108 | |
1109 | Object *VariantUtilityFunctions::instance_from_id(int64_t p_id) { |
1110 | ObjectID id = ObjectID((uint64_t)p_id); |
1111 | Object *ret = ObjectDB::get_instance(id); |
1112 | return ret; |
1113 | } |
1114 | |
1115 | bool VariantUtilityFunctions::is_instance_id_valid(int64_t p_id) { |
1116 | return ObjectDB::get_instance(ObjectID((uint64_t)p_id)) != nullptr; |
1117 | } |
1118 | |
1119 | bool VariantUtilityFunctions::is_instance_valid(const Variant &p_instance) { |
1120 | if (p_instance.get_type() != Variant::OBJECT) { |
1121 | return false; |
1122 | } |
1123 | return p_instance.get_validated_object() != nullptr; |
1124 | } |
1125 | |
1126 | uint64_t VariantUtilityFunctions::rid_allocate_id() { |
1127 | return RID_AllocBase::_gen_id(); |
1128 | } |
1129 | |
1130 | RID VariantUtilityFunctions::rid_from_int64(uint64_t p_base) { |
1131 | return RID::from_uint64(p_base); |
1132 | } |
1133 | |
1134 | bool VariantUtilityFunctions::is_same(const Variant &p_a, const Variant &p_b) { |
1135 | return p_a.identity_compare(p_b); |
1136 | } |
1137 | |
1138 | #ifdef DEBUG_METHODS_ENABLED |
1139 | #define VCALLR *ret = p_func(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...) |
1140 | #define VCALL p_func(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...) |
1141 | #else |
1142 | #define VCALLR *ret = p_func(VariantCaster<P>::cast(*p_args[Is])...) |
1143 | #define VCALL p_func(VariantCaster<P>::cast(*p_args[Is])...) |
1144 | #endif |
1145 | |
1146 | template <class R, class... P, size_t... Is> |
1147 | static _FORCE_INLINE_ void call_helperpr(R (*p_func)(P...), Variant *ret, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { |
1148 | r_error.error = Callable::CallError::CALL_OK; |
1149 | VCALLR; |
1150 | (void)p_args; // avoid gcc warning |
1151 | (void)r_error; |
1152 | } |
1153 | |
1154 | template <class R, class... P, size_t... Is> |
1155 | static _FORCE_INLINE_ void validated_call_helperpr(R (*p_func)(P...), Variant *ret, const Variant **p_args, IndexSequence<Is...>) { |
1156 | *ret = p_func(VariantCaster<P>::cast(*p_args[Is])...); |
1157 | (void)p_args; |
1158 | } |
1159 | |
1160 | template <class R, class... P, size_t... Is> |
1161 | static _FORCE_INLINE_ void ptr_call_helperpr(R (*p_func)(P...), void *ret, const void **p_args, IndexSequence<Is...>) { |
1162 | PtrToArg<R>::encode(p_func(PtrToArg<P>::convert(p_args[Is])...), ret); |
1163 | (void)p_args; |
1164 | } |
1165 | |
1166 | template <class R, class... P> |
1167 | static _FORCE_INLINE_ void call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args, Callable::CallError &r_error) { |
1168 | call_helperpr(p_func, ret, p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); |
1169 | } |
1170 | |
1171 | template <class R, class... P> |
1172 | static _FORCE_INLINE_ void validated_call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args) { |
1173 | validated_call_helperpr(p_func, ret, p_args, BuildIndexSequence<sizeof...(P)>{}); |
1174 | } |
1175 | |
1176 | template <class R, class... P> |
1177 | static _FORCE_INLINE_ void ptr_call_helperr(R (*p_func)(P...), void *ret, const void **p_args) { |
1178 | ptr_call_helperpr(p_func, ret, p_args, BuildIndexSequence<sizeof...(P)>{}); |
1179 | } |
1180 | |
1181 | template <class R, class... P> |
1182 | static _FORCE_INLINE_ int get_arg_count_helperr(R (*p_func)(P...)) { |
1183 | return sizeof...(P); |
1184 | } |
1185 | |
1186 | template <class R, class... P> |
1187 | static _FORCE_INLINE_ Variant::Type get_arg_type_helperr(R (*p_func)(P...), int p_arg) { |
1188 | return call_get_argument_type<P...>(p_arg); |
1189 | } |
1190 | |
1191 | template <class R, class... P> |
1192 | static _FORCE_INLINE_ Variant::Type get_ret_type_helperr(R (*p_func)(P...)) { |
1193 | return GetTypeInfo<R>::VARIANT_TYPE; |
1194 | } |
1195 | |
1196 | // WITHOUT RET |
1197 | |
1198 | template <class... P, size_t... Is> |
1199 | static _FORCE_INLINE_ void call_helperp(void (*p_func)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { |
1200 | r_error.error = Callable::CallError::CALL_OK; |
1201 | VCALL; |
1202 | (void)p_args; |
1203 | (void)r_error; |
1204 | } |
1205 | |
1206 | template <class... P, size_t... Is> |
1207 | static _FORCE_INLINE_ void validated_call_helperp(void (*p_func)(P...), const Variant **p_args, IndexSequence<Is...>) { |
1208 | p_func(VariantCaster<P>::cast(*p_args[Is])...); |
1209 | (void)p_args; |
1210 | } |
1211 | |
1212 | template <class... P, size_t... Is> |
1213 | static _FORCE_INLINE_ void ptr_call_helperp(void (*p_func)(P...), const void **p_args, IndexSequence<Is...>) { |
1214 | p_func(PtrToArg<P>::convert(p_args[Is])...); |
1215 | (void)p_args; |
1216 | } |
1217 | |
1218 | template <class... P> |
1219 | static _FORCE_INLINE_ void call_helper(void (*p_func)(P...), const Variant **p_args, Callable::CallError &r_error) { |
1220 | call_helperp(p_func, p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); |
1221 | } |
1222 | |
1223 | template <class... P> |
1224 | static _FORCE_INLINE_ void validated_call_helper(void (*p_func)(P...), const Variant **p_args) { |
1225 | validated_call_helperp(p_func, p_args, BuildIndexSequence<sizeof...(P)>{}); |
1226 | } |
1227 | |
1228 | template <class... P> |
1229 | static _FORCE_INLINE_ void ptr_call_helper(void (*p_func)(P...), const void **p_args) { |
1230 | ptr_call_helperp(p_func, p_args, BuildIndexSequence<sizeof...(P)>{}); |
1231 | } |
1232 | |
1233 | template <class... P> |
1234 | static _FORCE_INLINE_ int get_arg_count_helper(void (*p_func)(P...)) { |
1235 | return sizeof...(P); |
1236 | } |
1237 | |
1238 | template <class... P> |
1239 | static _FORCE_INLINE_ Variant::Type get_arg_type_helper(void (*p_func)(P...), int p_arg) { |
1240 | return call_get_argument_type<P...>(p_arg); |
1241 | } |
1242 | |
1243 | template <class... P> |
1244 | static _FORCE_INLINE_ Variant::Type get_ret_type_helper(void (*p_func)(P...)) { |
1245 | return Variant::NIL; |
1246 | } |
1247 | |
1248 | #define FUNCBINDR(m_func, m_args, m_category) \ |
1249 | class Func_##m_func { \ |
1250 | public: \ |
1251 | static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ |
1252 | call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args, r_error); \ |
1253 | } \ |
1254 | static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ |
1255 | validated_call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args); \ |
1256 | } \ |
1257 | static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ |
1258 | ptr_call_helperr(VariantUtilityFunctions::m_func, ret, p_args); \ |
1259 | } \ |
1260 | static int get_argument_count() { \ |
1261 | return get_arg_count_helperr(VariantUtilityFunctions::m_func); \ |
1262 | } \ |
1263 | static Variant::Type get_argument_type(int p_arg) { \ |
1264 | return get_arg_type_helperr(VariantUtilityFunctions::m_func, p_arg); \ |
1265 | } \ |
1266 | static Variant::Type get_return_type() { \ |
1267 | return get_ret_type_helperr(VariantUtilityFunctions::m_func); \ |
1268 | } \ |
1269 | static bool has_return_type() { \ |
1270 | return true; \ |
1271 | } \ |
1272 | static bool is_vararg() { return false; } \ |
1273 | static Variant::UtilityFunctionType get_type() { return m_category; } \ |
1274 | }; \ |
1275 | register_utility_function<Func_##m_func>(#m_func, m_args) |
1276 | |
1277 | #define FUNCBINDVR(m_func, m_args, m_category) \ |
1278 | class Func_##m_func { \ |
1279 | public: \ |
1280 | static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ |
1281 | r_error.error = Callable::CallError::CALL_OK; \ |
1282 | *r_ret = VariantUtilityFunctions::m_func(*p_args[0], r_error); \ |
1283 | } \ |
1284 | static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ |
1285 | Callable::CallError ce; \ |
1286 | *r_ret = VariantUtilityFunctions::m_func(*p_args[0], ce); \ |
1287 | } \ |
1288 | static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ |
1289 | Callable::CallError ce; \ |
1290 | PtrToArg<Variant>::encode(VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), ce), ret); \ |
1291 | } \ |
1292 | static int get_argument_count() { \ |
1293 | return 1; \ |
1294 | } \ |
1295 | static Variant::Type get_argument_type(int p_arg) { \ |
1296 | return Variant::NIL; \ |
1297 | } \ |
1298 | static Variant::Type get_return_type() { \ |
1299 | return Variant::NIL; \ |
1300 | } \ |
1301 | static bool has_return_type() { \ |
1302 | return true; \ |
1303 | } \ |
1304 | static bool is_vararg() { return false; } \ |
1305 | static Variant::UtilityFunctionType get_type() { return m_category; } \ |
1306 | }; \ |
1307 | register_utility_function<Func_##m_func>(#m_func, m_args) |
1308 | |
1309 | #define FUNCBINDVR2(m_func, m_args, m_category) \ |
1310 | class Func_##m_func { \ |
1311 | public: \ |
1312 | static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ |
1313 | r_error.error = Callable::CallError::CALL_OK; \ |
1314 | *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], r_error); \ |
1315 | } \ |
1316 | static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ |
1317 | Callable::CallError ce; \ |
1318 | *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], ce); \ |
1319 | } \ |
1320 | static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ |
1321 | Callable::CallError ce; \ |
1322 | Variant r; \ |
1323 | r = VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), PtrToArg<Variant>::convert(p_args[1]), ce); \ |
1324 | PtrToArg<Variant>::encode(r, ret); \ |
1325 | } \ |
1326 | static int get_argument_count() { \ |
1327 | return 2; \ |
1328 | } \ |
1329 | static Variant::Type get_argument_type(int p_arg) { \ |
1330 | return Variant::NIL; \ |
1331 | } \ |
1332 | static Variant::Type get_return_type() { \ |
1333 | return Variant::NIL; \ |
1334 | } \ |
1335 | static bool has_return_type() { \ |
1336 | return true; \ |
1337 | } \ |
1338 | static bool is_vararg() { return false; } \ |
1339 | static Variant::UtilityFunctionType get_type() { return m_category; } \ |
1340 | }; \ |
1341 | register_utility_function<Func_##m_func>(#m_func, m_args) |
1342 | |
1343 | #define FUNCBINDVR3(m_func, m_args, m_category) \ |
1344 | class Func_##m_func { \ |
1345 | public: \ |
1346 | static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ |
1347 | r_error.error = Callable::CallError::CALL_OK; \ |
1348 | *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], *p_args[2], r_error); \ |
1349 | } \ |
1350 | static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ |
1351 | Callable::CallError ce; \ |
1352 | *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], *p_args[2], ce); \ |
1353 | } \ |
1354 | static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ |
1355 | Callable::CallError ce; \ |
1356 | Variant r; \ |
1357 | r = VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), PtrToArg<Variant>::convert(p_args[1]), PtrToArg<Variant>::convert(p_args[2]), ce); \ |
1358 | PtrToArg<Variant>::encode(r, ret); \ |
1359 | } \ |
1360 | static int get_argument_count() { \ |
1361 | return 3; \ |
1362 | } \ |
1363 | static Variant::Type get_argument_type(int p_arg) { \ |
1364 | return Variant::NIL; \ |
1365 | } \ |
1366 | static Variant::Type get_return_type() { \ |
1367 | return Variant::NIL; \ |
1368 | } \ |
1369 | static bool has_return_type() { \ |
1370 | return true; \ |
1371 | } \ |
1372 | static bool is_vararg() { return false; } \ |
1373 | static Variant::UtilityFunctionType get_type() { return m_category; } \ |
1374 | }; \ |
1375 | register_utility_function<Func_##m_func>(#m_func, m_args) |
1376 | |
1377 | #define FUNCBINDVARARG(m_func, m_args, m_category) \ |
1378 | class Func_##m_func { \ |
1379 | public: \ |
1380 | static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ |
1381 | r_error.error = Callable::CallError::CALL_OK; \ |
1382 | *r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \ |
1383 | } \ |
1384 | static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ |
1385 | Callable::CallError c; \ |
1386 | *r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, c); \ |
1387 | } \ |
1388 | static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ |
1389 | Vector<Variant> args; \ |
1390 | for (int i = 0; i < p_argcount; i++) { \ |
1391 | args.push_back(PtrToArg<Variant>::convert(p_args[i])); \ |
1392 | } \ |
1393 | Vector<const Variant *> argsp; \ |
1394 | for (int i = 0; i < p_argcount; i++) { \ |
1395 | argsp.push_back(&args[i]); \ |
1396 | } \ |
1397 | Variant r; \ |
1398 | validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \ |
1399 | PtrToArg<Variant>::encode(r, ret); \ |
1400 | } \ |
1401 | static int get_argument_count() { \ |
1402 | return 2; \ |
1403 | } \ |
1404 | static Variant::Type get_argument_type(int p_arg) { \ |
1405 | return Variant::NIL; \ |
1406 | } \ |
1407 | static Variant::Type get_return_type() { \ |
1408 | return Variant::NIL; \ |
1409 | } \ |
1410 | static bool has_return_type() { \ |
1411 | return true; \ |
1412 | } \ |
1413 | static bool is_vararg() { \ |
1414 | return true; \ |
1415 | } \ |
1416 | static Variant::UtilityFunctionType get_type() { \ |
1417 | return m_category; \ |
1418 | } \ |
1419 | }; \ |
1420 | register_utility_function<Func_##m_func>(#m_func, m_args) |
1421 | |
1422 | #define FUNCBINDVARARGS(m_func, m_args, m_category) \ |
1423 | class Func_##m_func { \ |
1424 | public: \ |
1425 | static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ |
1426 | r_error.error = Callable::CallError::CALL_OK; \ |
1427 | *r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \ |
1428 | } \ |
1429 | static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ |
1430 | Callable::CallError c; \ |
1431 | *r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, c); \ |
1432 | } \ |
1433 | static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ |
1434 | Vector<Variant> args; \ |
1435 | for (int i = 0; i < p_argcount; i++) { \ |
1436 | args.push_back(PtrToArg<Variant>::convert(p_args[i])); \ |
1437 | } \ |
1438 | Vector<const Variant *> argsp; \ |
1439 | for (int i = 0; i < p_argcount; i++) { \ |
1440 | argsp.push_back(&args[i]); \ |
1441 | } \ |
1442 | Variant r; \ |
1443 | validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \ |
1444 | PtrToArg<String>::encode(r.operator String(), ret); \ |
1445 | } \ |
1446 | static int get_argument_count() { \ |
1447 | return 1; \ |
1448 | } \ |
1449 | static Variant::Type get_argument_type(int p_arg) { \ |
1450 | return Variant::NIL; \ |
1451 | } \ |
1452 | static Variant::Type get_return_type() { \ |
1453 | return Variant::STRING; \ |
1454 | } \ |
1455 | static bool has_return_type() { \ |
1456 | return true; \ |
1457 | } \ |
1458 | static bool is_vararg() { \ |
1459 | return true; \ |
1460 | } \ |
1461 | static Variant::UtilityFunctionType get_type() { \ |
1462 | return m_category; \ |
1463 | } \ |
1464 | }; \ |
1465 | register_utility_function<Func_##m_func>(#m_func, m_args) |
1466 | |
1467 | #define FUNCBINDVARARGV(m_func, m_args, m_category) \ |
1468 | class Func_##m_func { \ |
1469 | public: \ |
1470 | static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ |
1471 | r_error.error = Callable::CallError::CALL_OK; \ |
1472 | VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \ |
1473 | } \ |
1474 | static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ |
1475 | Callable::CallError c; \ |
1476 | VariantUtilityFunctions::m_func(p_args, p_argcount, c); \ |
1477 | } \ |
1478 | static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ |
1479 | Vector<Variant> args; \ |
1480 | for (int i = 0; i < p_argcount; i++) { \ |
1481 | args.push_back(PtrToArg<Variant>::convert(p_args[i])); \ |
1482 | } \ |
1483 | Vector<const Variant *> argsp; \ |
1484 | for (int i = 0; i < p_argcount; i++) { \ |
1485 | argsp.push_back(&args[i]); \ |
1486 | } \ |
1487 | Variant r; \ |
1488 | validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \ |
1489 | } \ |
1490 | static int get_argument_count() { \ |
1491 | return 1; \ |
1492 | } \ |
1493 | static Variant::Type get_argument_type(int p_arg) { \ |
1494 | return Variant::NIL; \ |
1495 | } \ |
1496 | static Variant::Type get_return_type() { \ |
1497 | return Variant::NIL; \ |
1498 | } \ |
1499 | static bool has_return_type() { \ |
1500 | return false; \ |
1501 | } \ |
1502 | static bool is_vararg() { \ |
1503 | return true; \ |
1504 | } \ |
1505 | static Variant::UtilityFunctionType get_type() { \ |
1506 | return m_category; \ |
1507 | } \ |
1508 | }; \ |
1509 | register_utility_function<Func_##m_func>(#m_func, m_args) |
1510 | |
1511 | #define FUNCBIND(m_func, m_args, m_category) \ |
1512 | class Func_##m_func { \ |
1513 | public: \ |
1514 | static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \ |
1515 | call_helper(VariantUtilityFunctions::m_func, p_args, r_error); \ |
1516 | } \ |
1517 | static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \ |
1518 | validated_call_helper(VariantUtilityFunctions::m_func, p_args); \ |
1519 | } \ |
1520 | static void ptrcall(void *ret, const void **p_args, int p_argcount) { \ |
1521 | ptr_call_helper(VariantUtilityFunctions::m_func, p_args); \ |
1522 | } \ |
1523 | static int get_argument_count() { \ |
1524 | return get_arg_count_helper(VariantUtilityFunctions::m_func); \ |
1525 | } \ |
1526 | static Variant::Type get_argument_type(int p_arg) { \ |
1527 | return get_arg_type_helper(VariantUtilityFunctions::m_func, p_arg); \ |
1528 | } \ |
1529 | static Variant::Type get_return_type() { \ |
1530 | return get_ret_type_helper(VariantUtilityFunctions::m_func); \ |
1531 | } \ |
1532 | static bool has_return_type() { \ |
1533 | return false; \ |
1534 | } \ |
1535 | static bool is_vararg() { return false; } \ |
1536 | static Variant::UtilityFunctionType get_type() { return m_category; } \ |
1537 | }; \ |
1538 | register_utility_function<Func_##m_func>(#m_func, m_args) |
1539 | |
1540 | struct VariantUtilityFunctionInfo { |
1541 | void (*call_utility)(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = nullptr; |
1542 | Variant::ValidatedUtilityFunction validated_call_utility = nullptr; |
1543 | Variant::PTRUtilityFunction ptr_call_utility = nullptr; |
1544 | Vector<String> argnames; |
1545 | bool is_vararg = false; |
1546 | bool returns_value = false; |
1547 | int argcount = 0; |
1548 | Variant::Type (*get_arg_type)(int) = nullptr; |
1549 | Variant::Type return_type; |
1550 | Variant::UtilityFunctionType type; |
1551 | }; |
1552 | |
1553 | static OAHashMap<StringName, VariantUtilityFunctionInfo> utility_function_table; |
1554 | static List<StringName> utility_function_name_table; |
1555 | |
1556 | template <class T> |
1557 | static void register_utility_function(const String &p_name, const Vector<String> &argnames) { |
1558 | String name = p_name; |
1559 | if (name.begins_with("_" )) { |
1560 | name = name.substr(1, name.length() - 1); |
1561 | } |
1562 | StringName sname = name; |
1563 | ERR_FAIL_COND(utility_function_table.has(sname)); |
1564 | |
1565 | VariantUtilityFunctionInfo bfi; |
1566 | bfi.call_utility = T::call; |
1567 | bfi.validated_call_utility = T::validated_call; |
1568 | bfi.ptr_call_utility = T::ptrcall; |
1569 | bfi.is_vararg = T::is_vararg(); |
1570 | bfi.argnames = argnames; |
1571 | bfi.argcount = T::get_argument_count(); |
1572 | if (!bfi.is_vararg) { |
1573 | ERR_FAIL_COND_MSG(argnames.size() != bfi.argcount, "wrong number of arguments binding utility function: " + name); |
1574 | } |
1575 | bfi.get_arg_type = T::get_argument_type; |
1576 | bfi.return_type = T::get_return_type(); |
1577 | bfi.type = T::get_type(); |
1578 | bfi.returns_value = T::has_return_type(); |
1579 | |
1580 | utility_function_table.insert(sname, bfi); |
1581 | utility_function_name_table.push_back(sname); |
1582 | } |
1583 | |
1584 | void Variant::_register_variant_utility_functions() { |
1585 | // Math |
1586 | |
1587 | FUNCBINDR(sin, sarray("angle_rad" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1588 | FUNCBINDR(cos, sarray("angle_rad" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1589 | FUNCBINDR(tan, sarray("angle_rad" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1590 | |
1591 | FUNCBINDR(sinh, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1592 | FUNCBINDR(cosh, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1593 | FUNCBINDR(tanh, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1594 | |
1595 | FUNCBINDR(asin, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1596 | FUNCBINDR(acos, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1597 | FUNCBINDR(atan, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1598 | |
1599 | FUNCBINDR(atan2, sarray("y" , "x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1600 | |
1601 | FUNCBINDR(asinh, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1602 | FUNCBINDR(acosh, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1603 | FUNCBINDR(atanh, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1604 | |
1605 | FUNCBINDR(sqrt, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1606 | FUNCBINDR(fmod, sarray("x" , "y" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1607 | FUNCBINDR(fposmod, sarray("x" , "y" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1608 | FUNCBINDR(posmod, sarray("x" , "y" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1609 | |
1610 | FUNCBINDVR(floor, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1611 | FUNCBINDR(floorf, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1612 | FUNCBINDR(floori, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1613 | |
1614 | FUNCBINDVR(ceil, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1615 | FUNCBINDR(ceilf, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1616 | FUNCBINDR(ceili, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1617 | |
1618 | FUNCBINDVR(round, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1619 | FUNCBINDR(roundf, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1620 | FUNCBINDR(roundi, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1621 | |
1622 | FUNCBINDVR(abs, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1623 | FUNCBINDR(absf, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1624 | FUNCBINDR(absi, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1625 | |
1626 | FUNCBINDVR(sign, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1627 | FUNCBINDR(signf, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1628 | FUNCBINDR(signi, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1629 | |
1630 | FUNCBINDVR2(snapped, sarray("x" , "step" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1631 | FUNCBINDR(snappedf, sarray("x" , "step" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1632 | FUNCBINDR(snappedi, sarray("x" , "step" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1633 | |
1634 | FUNCBINDR(pow, sarray("base" , "exp" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1635 | FUNCBINDR(log, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1636 | FUNCBINDR(exp, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1637 | |
1638 | FUNCBINDR(is_nan, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1639 | FUNCBINDR(is_inf, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1640 | |
1641 | FUNCBINDR(is_equal_approx, sarray("a" , "b" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1642 | FUNCBINDR(is_zero_approx, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1643 | FUNCBINDR(is_finite, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1644 | |
1645 | FUNCBINDR(ease, sarray("x" , "curve" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1646 | FUNCBINDR(step_decimals, sarray("x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1647 | |
1648 | FUNCBINDVR3(lerp, sarray("from" , "to" , "weight" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1649 | FUNCBINDR(lerpf, sarray("from" , "to" , "weight" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1650 | FUNCBINDR(cubic_interpolate, sarray("from" , "to" , "pre" , "post" , "weight" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1651 | FUNCBINDR(cubic_interpolate_angle, sarray("from" , "to" , "pre" , "post" , "weight" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1652 | FUNCBINDR(cubic_interpolate_in_time, sarray("from" , "to" , "pre" , "post" , "weight" , "to_t" , "pre_t" , "post_t" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1653 | FUNCBINDR(cubic_interpolate_angle_in_time, sarray("from" , "to" , "pre" , "post" , "weight" , "to_t" , "pre_t" , "post_t" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1654 | FUNCBINDR(bezier_interpolate, sarray("start" , "control_1" , "control_2" , "end" , "t" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1655 | FUNCBINDR(bezier_derivative, sarray("start" , "control_1" , "control_2" , "end" , "t" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1656 | FUNCBINDR(lerp_angle, sarray("from" , "to" , "weight" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1657 | FUNCBINDR(inverse_lerp, sarray("from" , "to" , "weight" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1658 | FUNCBINDR(remap, sarray("value" , "istart" , "istop" , "ostart" , "ostop" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1659 | |
1660 | FUNCBINDR(smoothstep, sarray("from" , "to" , "x" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1661 | FUNCBINDR(move_toward, sarray("from" , "to" , "delta" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1662 | |
1663 | FUNCBINDR(deg_to_rad, sarray("deg" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1664 | FUNCBINDR(rad_to_deg, sarray("rad" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1665 | FUNCBINDR(linear_to_db, sarray("lin" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1666 | FUNCBINDR(db_to_linear, sarray("db" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1667 | |
1668 | FUNCBINDVR3(wrap, sarray("value" , "min" , "max" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1669 | FUNCBINDR(wrapi, sarray("value" , "min" , "max" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1670 | FUNCBINDR(wrapf, sarray("value" , "min" , "max" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1671 | |
1672 | FUNCBINDVARARG(max, sarray(), Variant::UTILITY_FUNC_TYPE_MATH); |
1673 | FUNCBINDR(maxi, sarray("a" , "b" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1674 | FUNCBINDR(maxf, sarray("a" , "b" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1675 | |
1676 | FUNCBINDVARARG(min, sarray(), Variant::UTILITY_FUNC_TYPE_MATH); |
1677 | FUNCBINDR(mini, sarray("a" , "b" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1678 | FUNCBINDR(minf, sarray("a" , "b" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1679 | |
1680 | FUNCBINDVR3(clamp, sarray("value" , "min" , "max" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1681 | FUNCBINDR(clampi, sarray("value" , "min" , "max" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1682 | FUNCBINDR(clampf, sarray("value" , "min" , "max" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1683 | |
1684 | FUNCBINDR(nearest_po2, sarray("value" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1685 | FUNCBINDR(pingpong, sarray("value" , "length" ), Variant::UTILITY_FUNC_TYPE_MATH); |
1686 | |
1687 | // Random |
1688 | |
1689 | FUNCBIND(randomize, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM); |
1690 | FUNCBINDR(randi, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM); |
1691 | FUNCBINDR(randf, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM); |
1692 | FUNCBINDR(randi_range, sarray("from" , "to" ), Variant::UTILITY_FUNC_TYPE_RANDOM); |
1693 | FUNCBINDR(randf_range, sarray("from" , "to" ), Variant::UTILITY_FUNC_TYPE_RANDOM); |
1694 | FUNCBINDR(randfn, sarray("mean" , "deviation" ), Variant::UTILITY_FUNC_TYPE_RANDOM); |
1695 | FUNCBIND(seed, sarray("base" ), Variant::UTILITY_FUNC_TYPE_RANDOM); |
1696 | FUNCBINDR(rand_from_seed, sarray("seed" ), Variant::UTILITY_FUNC_TYPE_RANDOM); |
1697 | |
1698 | // Utility |
1699 | |
1700 | FUNCBINDVR(weakref, sarray("obj" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1701 | FUNCBINDR(_typeof, sarray("variable" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1702 | FUNCBINDR(type_convert, sarray("variant" , "type" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1703 | FUNCBINDVARARGS(str, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1704 | FUNCBINDR(error_string, sarray("error" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1705 | FUNCBINDVARARGV(print, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1706 | FUNCBINDVARARGV(print_rich, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1707 | FUNCBINDVARARGV(printerr, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1708 | FUNCBINDVARARGV(printt, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1709 | FUNCBINDVARARGV(prints, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1710 | FUNCBINDVARARGV(printraw, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1711 | FUNCBINDVARARGV(print_verbose, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1712 | FUNCBINDVARARGV(push_error, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1713 | FUNCBINDVARARGV(push_warning, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1714 | |
1715 | FUNCBINDR(var_to_str, sarray("variable" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1716 | FUNCBINDR(str_to_var, sarray("string" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1717 | |
1718 | FUNCBINDR(var_to_bytes, sarray("variable" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1719 | FUNCBINDR(bytes_to_var, sarray("bytes" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1720 | |
1721 | FUNCBINDR(var_to_bytes_with_objects, sarray("variable" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1722 | FUNCBINDR(bytes_to_var_with_objects, sarray("bytes" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1723 | |
1724 | FUNCBINDR(hash, sarray("variable" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1725 | |
1726 | FUNCBINDR(instance_from_id, sarray("instance_id" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1727 | FUNCBINDR(is_instance_id_valid, sarray("id" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1728 | FUNCBINDR(is_instance_valid, sarray("instance" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1729 | |
1730 | FUNCBINDR(rid_allocate_id, Vector<String>(), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1731 | FUNCBINDR(rid_from_int64, sarray("base" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1732 | |
1733 | FUNCBINDR(is_same, sarray("a" , "b" ), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1734 | } |
1735 | |
1736 | void Variant::_unregister_variant_utility_functions() { |
1737 | utility_function_table.clear(); |
1738 | utility_function_name_table.clear(); |
1739 | } |
1740 | |
1741 | void Variant::call_utility_function(const StringName &p_name, Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { |
1742 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1743 | if (!bfi) { |
1744 | r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; |
1745 | r_error.argument = 0; |
1746 | r_error.expected = 0; |
1747 | return; |
1748 | } |
1749 | |
1750 | if (unlikely(!bfi->is_vararg && p_argcount < bfi->argcount)) { |
1751 | r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; |
1752 | r_error.argument = 0; |
1753 | r_error.expected = bfi->argcount; |
1754 | return; |
1755 | } |
1756 | |
1757 | if (unlikely(!bfi->is_vararg && p_argcount > bfi->argcount)) { |
1758 | r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; |
1759 | r_error.argument = 0; |
1760 | r_error.expected = bfi->argcount; |
1761 | return; |
1762 | } |
1763 | |
1764 | bfi->call_utility(r_ret, p_args, p_argcount, r_error); |
1765 | } |
1766 | |
1767 | bool Variant::has_utility_function(const StringName &p_name) { |
1768 | return utility_function_table.has(p_name); |
1769 | } |
1770 | |
1771 | Variant::ValidatedUtilityFunction Variant::get_validated_utility_function(const StringName &p_name) { |
1772 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1773 | if (!bfi) { |
1774 | return nullptr; |
1775 | } |
1776 | |
1777 | return bfi->validated_call_utility; |
1778 | } |
1779 | |
1780 | Variant::PTRUtilityFunction Variant::get_ptr_utility_function(const StringName &p_name) { |
1781 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1782 | if (!bfi) { |
1783 | return nullptr; |
1784 | } |
1785 | |
1786 | return bfi->ptr_call_utility; |
1787 | } |
1788 | |
1789 | Variant::UtilityFunctionType Variant::get_utility_function_type(const StringName &p_name) { |
1790 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1791 | if (!bfi) { |
1792 | return Variant::UTILITY_FUNC_TYPE_MATH; |
1793 | } |
1794 | |
1795 | return bfi->type; |
1796 | } |
1797 | |
1798 | MethodInfo Variant::get_utility_function_info(const StringName &p_name) { |
1799 | MethodInfo info; |
1800 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1801 | if (bfi) { |
1802 | info.name = p_name; |
1803 | if (bfi->returns_value && bfi->return_type == Variant::NIL) { |
1804 | info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; |
1805 | } |
1806 | info.return_val.type = bfi->return_type; |
1807 | if (bfi->is_vararg) { |
1808 | info.flags |= METHOD_FLAG_VARARG; |
1809 | } |
1810 | for (int i = 0; i < bfi->argnames.size(); ++i) { |
1811 | PropertyInfo arg; |
1812 | arg.type = bfi->get_arg_type(i); |
1813 | arg.name = bfi->argnames[i]; |
1814 | info.arguments.push_back(arg); |
1815 | } |
1816 | } |
1817 | return info; |
1818 | } |
1819 | |
1820 | int Variant::get_utility_function_argument_count(const StringName &p_name) { |
1821 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1822 | if (!bfi) { |
1823 | return 0; |
1824 | } |
1825 | |
1826 | return bfi->argcount; |
1827 | } |
1828 | |
1829 | Variant::Type Variant::get_utility_function_argument_type(const StringName &p_name, int p_arg) { |
1830 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1831 | if (!bfi) { |
1832 | return Variant::NIL; |
1833 | } |
1834 | |
1835 | return bfi->get_arg_type(p_arg); |
1836 | } |
1837 | |
1838 | String Variant::get_utility_function_argument_name(const StringName &p_name, int p_arg) { |
1839 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1840 | if (!bfi) { |
1841 | return String(); |
1842 | } |
1843 | ERR_FAIL_INDEX_V(p_arg, bfi->argnames.size(), String()); |
1844 | ERR_FAIL_COND_V(bfi->is_vararg, String()); |
1845 | return bfi->argnames[p_arg]; |
1846 | } |
1847 | |
1848 | bool Variant::has_utility_function_return_value(const StringName &p_name) { |
1849 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1850 | if (!bfi) { |
1851 | return false; |
1852 | } |
1853 | return bfi->returns_value; |
1854 | } |
1855 | |
1856 | Variant::Type Variant::get_utility_function_return_type(const StringName &p_name) { |
1857 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1858 | if (!bfi) { |
1859 | return Variant::NIL; |
1860 | } |
1861 | |
1862 | return bfi->return_type; |
1863 | } |
1864 | |
1865 | bool Variant::is_utility_function_vararg(const StringName &p_name) { |
1866 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1867 | if (!bfi) { |
1868 | return false; |
1869 | } |
1870 | |
1871 | return bfi->is_vararg; |
1872 | } |
1873 | |
1874 | uint32_t Variant::get_utility_function_hash(const StringName &p_name) { |
1875 | const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); |
1876 | ERR_FAIL_NULL_V(bfi, 0); |
1877 | |
1878 | uint32_t hash = hash_murmur3_one_32(bfi->is_vararg); |
1879 | hash = hash_murmur3_one_32(bfi->returns_value, hash); |
1880 | if (bfi->returns_value) { |
1881 | hash = hash_murmur3_one_32(bfi->return_type, hash); |
1882 | } |
1883 | hash = hash_murmur3_one_32(bfi->argcount, hash); |
1884 | for (int i = 0; i < bfi->argcount; i++) { |
1885 | hash = hash_murmur3_one_32(bfi->get_arg_type(i), hash); |
1886 | } |
1887 | |
1888 | return hash_fmix32(hash); |
1889 | } |
1890 | |
1891 | void Variant::get_utility_function_list(List<StringName> *r_functions) { |
1892 | for (const StringName &E : utility_function_name_table) { |
1893 | r_functions->push_back(E); |
1894 | } |
1895 | } |
1896 | |
1897 | int Variant::get_utility_function_count() { |
1898 | return utility_function_name_table.size(); |
1899 | } |
1900 | |