diff options
Diffstat (limited to 'core/variant')
-rw-r--r-- | core/variant/array.cpp | 44 | ||||
-rw-r--r-- | core/variant/array.h | 10 | ||||
-rw-r--r-- | core/variant/binder_common.h | 242 | ||||
-rw-r--r-- | core/variant/callable.cpp | 4 | ||||
-rw-r--r-- | core/variant/variant.h | 3 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 547 | ||||
-rw-r--r-- | core/variant/variant_op.cpp | 8 | ||||
-rw-r--r-- | core/variant/variant_parser.cpp | 45 | ||||
-rw-r--r-- | core/variant/variant_setget.cpp | 123 |
9 files changed, 850 insertions, 176 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 9a2922a777..2fb2dd4a30 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -139,9 +139,9 @@ uint32_t Array::hash() const { return h; } -void Array::_assign(const Array &p_array) { +bool Array::_assign(const Array &p_array) { if (_p->typed.type != Variant::OBJECT && _p->typed.type == p_array._p->typed.type) { - //same type or untyped, just reference, shuold be fine + //same type or untyped, just reference, should be fine _ref(p_array); } else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway _p->array = p_array._p->array; @@ -150,7 +150,7 @@ void Array::_assign(const Array &p_array) { //for objects, it needs full validation, either can be converted or fail for (int i = 0; i < p_array._p->array.size(); i++) { if (!_p->typed.validate(p_array._p->array[i], "assign")) { - return; + return false; } } _p->array = p_array._p->array; //then just copy, which is cheap anyway @@ -168,10 +168,10 @@ void Array::_assign(const Array &p_array) { Callable::CallError ce; Variant::construct(_p->typed.type, new_array.write[i], (const Variant **)&ptr, 1, ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); + ERR_FAIL_V_MSG(false, "Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); } } else { - ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); + ERR_FAIL_V_MSG(false, "Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); } } @@ -180,12 +180,13 @@ void Array::_assign(const Array &p_array) { } else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible _ref(p_array); } else { - ERR_FAIL_MSG("Assignment of arrays of incompatible types."); + ERR_FAIL_V_MSG(false, "Assignment of arrays of incompatible types."); } + return true; } void Array::operator=(const Array &p_array) { - _assign(p_array); + _ref(p_array); } void Array::push_back(const Variant &p_value) { @@ -207,6 +208,11 @@ void Array::insert(int p_pos, const Variant &p_value) { _p->array.insert(p_pos, p_value); } +void Array::fill(const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "fill")); + _p->array.fill(p_value); +} + void Array::erase(const Variant &p_value) { ERR_FAIL_COND(!_p->typed.validate(p_value, "erase")); _p->array.erase(p_value); @@ -445,8 +451,8 @@ int Array::bsearch_custom(const Variant &p_value, Callable p_callable, bool p_be return bisect(_p->array, p_value, p_before, less); } -void Array::invert() { - _p->array.invert(); +void Array::reverse() { + _p->array.reverse(); } void Array::push_front(const Variant &p_value) { @@ -528,6 +534,10 @@ Array::Array(const Array &p_from, uint32_t p_type, const StringName &p_class_nam _assign(p_from); } +bool Array::typed_assign(const Array &p_other) { + return _assign(p_other); +} + void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) { ERR_FAIL_COND_MSG(_p->array.size() > 0, "Type can only be set when array is empty."); ERR_FAIL_COND_MSG(_p->refcount.get() > 1, "Type can only be set when array has no more than one user."); @@ -542,6 +552,22 @@ void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Var _p->typed.where = "TypedArray"; } +bool Array::is_typed() const { + return _p->typed.type != Variant::NIL; +} + +uint32_t Array::get_typed_builtin() const { + return _p->typed.type; +} + +StringName Array::get_typed_class_name() const { + return _p->typed.class_name; +} + +Variant Array::get_typed_script() const { + return _p->typed.script; +} + Array::Array(const Array &p_from) { _p = nullptr; _ref(p_from); diff --git a/core/variant/array.h b/core/variant/array.h index d8f2402330..5ce977ee4b 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -48,7 +48,7 @@ class Array { protected: Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script); - void _assign(const Array &p_array); + bool _assign(const Array &p_array); public: Variant &operator[](int p_idx); @@ -74,6 +74,7 @@ public: void insert(int p_pos, const Variant &p_value); void remove(int p_pos); + void fill(const Variant &p_value); Variant front() const; Variant back() const; @@ -83,7 +84,7 @@ public: void shuffle(); int bsearch(const Variant &p_value, bool p_before = true); int bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before = true); - void invert(); + void reverse(); int find(const Variant &p_value, int p_from = 0) const; int rfind(const Variant &p_value, int p_from = -1) const; @@ -111,7 +112,12 @@ public: const void *id() const; + bool typed_assign(const Array &p_other); void set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script); + bool is_typed() const; + uint32_t get_typed_builtin() const; + StringName get_typed_class_name() const; + Variant get_typed_script() const; Array(const Array &p_from); Array(); ~Array(); diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 490bd45b7b..830e0a5cbd 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -122,6 +122,18 @@ struct VariantObjectClassChecker { } }; +template <typename T> +class Ref; + +template <typename T> +struct VariantObjectClassChecker<const Ref<T> &> { + static _FORCE_INLINE_ bool check(const Variant &p_variant) { + Object *obj = p_variant; + const Ref<T> node = p_variant; + return node.ptr() || !obj; + } +}; + template <> struct VariantObjectClassChecker<Node *> { static _FORCE_INLINE_ bool check(const Variant &p_variant) { @@ -233,11 +245,26 @@ void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret); } +template <class T, class... P, size_t... Is> +void call_with_ptr_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const void **p_args, IndexSequence<Is...>) { + p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...); +} + template <class T, class R, class... P, size_t... Is> void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret, IndexSequence<Is...>) { PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret); } +template <class R, class... P, size_t... Is> +void call_with_ptr_args_static_method_ret_helper(R (*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) { + PtrToArg<R>::encode(p_method(PtrToArg<P>::convert(p_args[Is])...), r_ret); +} + +template <class... P, size_t... Is> +void call_with_ptr_args_static_method_helper(void (*p_method)(P...), const void **p_args, IndexSequence<Is...>) { + p_method(PtrToArg<P>::convert(p_args[Is])...); +} + template <class T, class... P, size_t... Is> void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) { (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...); @@ -263,6 +290,21 @@ void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_me VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...)); } +template <class T, class... P, size_t... Is> +void call_with_validated_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, IndexSequence<Is...>) { + p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...); +} + +template <class R, class... P, size_t... Is> +void call_with_validated_variant_args_static_method_ret_helper(R (*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) { + VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...)); +} + +template <class... P, size_t... Is> +void call_with_validated_variant_args_static_method_helper(void (*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) { + p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...); +} + template <class T, class... P> void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) { #ifdef DEBUG_METHODS_ENABLED @@ -451,11 +493,26 @@ void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); } +template <class T, class... P> +void call_with_ptr_args_static(T *p_instance, void (*p_method)(T *, P...), const void **p_args) { + call_with_ptr_args_static_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + template <class T, class R, class... P> void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) { call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); } +template <class R, class... P> +void call_with_ptr_args_static_method_ret(R (*p_method)(P...), const void **p_args, void *r_ret) { + call_with_ptr_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class... P> +void call_with_ptr_args_static_method(void (*p_method)(P...), const void **p_args) { + call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + template <class T, class... P> void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) { call_with_validated_variant_args_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{}); @@ -471,11 +528,26 @@ void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...) call_with_validated_variant_args_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); } +template <class T, class... P> +void call_with_validated_variant_args_static(Variant *base, void (*p_method)(T *, P...), const Variant **p_args) { + call_with_validated_variant_args_static_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + template <class T, class R, class... P> void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) { call_with_validated_variant_args_static_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); } +template <class... P> +void call_with_validated_variant_args_static_method(void (*p_method)(P...), const Variant **p_args) { + call_with_validated_variant_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class R, class... P> +void call_with_validated_variant_args_static_method_ret(R (*p_method)(P...), const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); +} + // GCC raises "parameter 'p_args' set but not used" when P = {}, // it's not clever enough to treat other P values as making this branch valid. #if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__) @@ -566,6 +638,28 @@ void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), co #endif } +template <class R, class... P, size_t... Is> +void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) { + r_error.error = Callable::CallError::CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + r_ret = (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + r_ret = (p_method)(VariantCaster<P>::cast(*p_args[Is])...); +#endif +} + +template <class... P, size_t... Is> +void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { + r_error.error = Callable::CallError::CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + (p_method)(VariantCaster<P>::cast(*p_args[Is])...); +#endif +} + template <class T, class R, class... P> void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { #ifdef DEBUG_METHODS_ENABLED @@ -596,6 +690,42 @@ void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) co (void)p_args; } +template <class R, class... P> +void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { +#ifdef DEBUG_METHODS_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } + + if ((size_t)p_argcount < sizeof...(P)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + call_with_variant_args_static_ret<R, P...>(p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class... P> +void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { +#ifdef DEBUG_METHODS_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } + + if ((size_t)p_argcount < sizeof...(P)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + call_with_variant_args_static<P...>(p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + template <class T, class R, class... P> void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { #ifdef DEBUG_METHODS_ENABLED @@ -660,6 +790,118 @@ void call_with_variant_args_retc_static_helper_dv(T *p_instance, R (*p_method)(T call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); } +template <class T, class... P, size_t... Is> +void call_with_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { + r_error.error = Callable::CallError::CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...); +#endif + + (void)p_args; +} + +template <class T, class... P> +void call_with_variant_args_static_helper_dv(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, int p_argcount, const Vector<Variant> &default_values, Callable::CallError &r_error) { +#ifdef DEBUG_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount; + + int32_t dvs = default_values.size(); +#ifdef DEBUG_ENABLED + if (missing > dvs) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array + for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) { + if (i < p_argcount) { + args[i] = p_args[i]; + } else { + args[i] = &default_values[i - p_argcount + (dvs - missing)]; + } + } + + call_with_variant_args_static_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class R, class... P> +void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) { +#ifdef DEBUG_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount; + + int32_t dvs = default_values.size(); +#ifdef DEBUG_ENABLED + if (missing > dvs) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array + for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) { + if (i < p_argcount) { + args[i] = p_args[i]; + } else { + args[i] = &default_values[i - p_argcount + (dvs - missing)]; + } + } + + call_with_variant_args_static_ret(p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class... P> +void call_with_variant_args_static_dv(void (*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) { +#ifdef DEBUG_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount; + + int32_t dvs = default_values.size(); +#ifdef DEBUG_ENABLED + if (missing > dvs) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array + for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) { + if (i < p_argcount) { + args[i] = p_args[i]; + } else { + args[i] = &default_values[i - p_argcount + (dvs - missing)]; + } + } + + call_with_variant_args_static(p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + #if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index bd51e2dd1e..a1d9c5ed2f 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -126,7 +126,7 @@ bool Callable::operator==(const Callable &p_callable) const { if (custom_a == custom_b) { if (custom_a) { if (custom == p_callable.custom) { - return true; //same pointer, dont even compare + return true; //same pointer, don't even compare } CallableCustom::CompareEqualFunc eq_a = custom->get_compare_equal_func(); @@ -155,7 +155,7 @@ bool Callable::operator<(const Callable &p_callable) const { if (custom_a == custom_b) { if (custom_a) { if (custom == p_callable.custom) { - return false; //same pointer, dont even compare + return false; //same pointer, don't even compare } CallableCustom::CompareLessFunc less_a = custom->get_compare_less_func(); diff --git a/core/variant/variant.h b/core/variant/variant.h index 5050aa24ec..0acafc64fa 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -495,6 +495,7 @@ public: static bool has_builtin_method_return_value(Variant::Type p_type, const StringName &p_method); static Variant::Type get_builtin_method_return_type(Variant::Type p_type, const StringName &p_method); static bool is_builtin_method_const(Variant::Type p_type, const StringName &p_method); + static bool is_builtin_method_static(Variant::Type p_type, const StringName &p_method); static bool is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method); static void get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list); static int get_builtin_method_count(Variant::Type p_type); @@ -502,6 +503,8 @@ public: void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant()); + static void call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); + static String get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); static String get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 54ca1a911d..deaccc6304 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -34,6 +34,7 @@ #include "core/crypto/crypto_core.h" #include "core/debugger/engine_debugger.h" #include "core/io/compression.h" +#include "core/io/marshalls.h" #include "core/object/class_db.h" #include "core/os/os.h" #include "core/templates/local_vector.h" @@ -42,6 +43,16 @@ typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args); typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args); +template <class R, class... P> +static _FORCE_INLINE_ void vc_static_method_call(R (*method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_static_ret_dv(method, p_args, p_argcount, r_ret, r_error, p_defvals); +} + +template <class... P> +static _FORCE_INLINE_ void vc_static_method_call(void (*method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_static_dv(method, p_args, p_argcount, r_error, p_defvals); +} + template <class R, class T, class... P> static _FORCE_INLINE_ void vc_method_call(R (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { call_with_variant_args_ret_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, p_defvals); @@ -63,6 +74,16 @@ static _FORCE_INLINE_ void vc_method_call(void (T::*method)(P...) const, Variant } template <class R, class T, class... P> +static _FORCE_INLINE_ void vc_method_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_retc_static_helper_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, p_defvals, r_error); +} + +template <class T, class... P> +static _FORCE_INLINE_ void vc_method_call_static(void (*method)(T *, P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_static_helper_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, p_defvals, r_error); +} + +template <class R, class T, class... P> static _FORCE_INLINE_ void vc_validated_call(R (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) { call_with_validated_variant_args_ret(base, method, p_args, r_ret); } @@ -82,48 +103,43 @@ static _FORCE_INLINE_ void vc_validated_call(void (T::*method)(P...) const, Vari } template <class R, class T, class... P> -static _FORCE_INLINE_ void vc_ptrcall(R (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) { - call_with_ptr_args_ret(reinterpret_cast<T *>(p_base), method, p_args, r_ret); +static _FORCE_INLINE_ void vc_validated_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static_retc(base, method, p_args, r_ret); } -template <class R, class T, class... P> -static _FORCE_INLINE_ void vc_ptrcall(R (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) { - call_with_ptr_args_retc(reinterpret_cast<T *>(p_base), method, p_args, r_ret); +template <class T, class... P> +static _FORCE_INLINE_ void vc_validated_call_static(void (*method)(T *, P...), Variant *base, const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static(base, method, p_args); } -template <class T, class... P> -static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) { - call_with_ptr_args(reinterpret_cast<T *>(p_base), method, p_args); +template <class R, class... P> +static _FORCE_INLINE_ void vc_validated_static_call(R (*method)(P...), const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static_method_ret(method, p_args, r_ret); } -template <class T, class... P> -static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) { - call_with_ptr_argsc(reinterpret_cast<T *>(p_base), method, p_args); +template <class... P> +static _FORCE_INLINE_ void vc_validated_static_call(void (*method)(P...), const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static_method(method, p_args); } template <class R, class T, class... P> -static _FORCE_INLINE_ void vc_change_return_type(R (T::*method)(P...), Variant *v) { - VariantTypeAdjust<R>::adjust(v); +static _FORCE_INLINE_ void vc_ptrcall(R (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_args_ret(reinterpret_cast<T *>(p_base), method, p_args, r_ret); } template <class R, class T, class... P> -static _FORCE_INLINE_ void vc_change_return_type(R (T::*method)(P...) const, Variant *v) { - VariantTypeAdjust<R>::adjust(v); +static _FORCE_INLINE_ void vc_ptrcall(R (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_args_retc(reinterpret_cast<T *>(p_base), method, p_args, r_ret); } template <class T, class... P> -static _FORCE_INLINE_ void vc_change_return_type(void (T::*method)(P...), Variant *v) { - VariantInternal::clear(v); +static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_args(reinterpret_cast<T *>(p_base), method, p_args); } template <class T, class... P> -static _FORCE_INLINE_ void vc_change_return_type(void (T::*method)(P...) const, Variant *v) { - VariantInternal::clear(v); -} - -template <class R, class... P> -static _FORCE_INLINE_ void vc_change_return_type(R (*method)(P...), Variant *v) { - VariantTypeAdjust<R>::adjust(v); +static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_argsc(reinterpret_cast<T *>(p_base), method, p_args); } template <class R, class T, class... P> @@ -150,6 +166,11 @@ static _FORCE_INLINE_ int vc_get_argument_count(R (*method)(T *, P...)) { return sizeof...(P); } +template <class R, class... P> +static _FORCE_INLINE_ int vc_get_argument_count_static(R (*method)(P...)) { + return sizeof...(P); +} + template <class R, class T, class... P> static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (T::*method)(P...), int p_arg) { return call_get_argument_type<P...>(p_arg); @@ -174,6 +195,11 @@ static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (*method)(T *, P...), return call_get_argument_type<P...>(p_arg); } +template <class R, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_argument_type_static(R (*method)(P...), int p_arg) { + return call_get_argument_type<P...>(p_arg); +} + template <class R, class T, class... P> static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (T::*method)(P...)) { return GetTypeInfo<R>::VARIANT_TYPE; @@ -199,6 +225,11 @@ static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (*method)(P...)) { return GetTypeInfo<R>::VARIANT_TYPE; } +template <class... P> +static _FORCE_INLINE_ Variant::Type vc_get_return_type(void (*method)(P...)) { + return Variant::NIL; +} + template <class R, class T, class... P> static _FORCE_INLINE_ bool vc_has_return_type(R (T::*method)(P...)) { return true; @@ -218,6 +249,16 @@ static _FORCE_INLINE_ bool vc_has_return_type(void (T::*method)(P...) const) { return false; } +template <class... P> +static _FORCE_INLINE_ bool vc_has_return_type_static(void (*method)(P...)) { + return false; +} + +template <class R, class... P> +static _FORCE_INLINE_ bool vc_has_return_type_static(R (*method)(P...)) { + return true; +} + template <class R, class T, class... P> static _FORCE_INLINE_ bool vc_is_const(R (T::*method)(P...)) { return false; @@ -262,7 +303,6 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con vc_method_call(m_method_ptr, base, p_args, p_argcount, r_ret, p_defvals, r_error); \ } \ static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ - vc_change_return_type(m_method_ptr, r_ret); \ vc_validated_call(m_method_ptr, base, p_args, r_ret); \ } \ static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ @@ -283,6 +323,9 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con static bool is_const() { \ return vc_is_const(m_method_ptr); \ } \ + static bool is_static() { \ + return false; \ + } \ static bool is_vararg() { \ return false; \ } \ @@ -294,47 +337,104 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con } \ }; +template <class R, class... P> +static _FORCE_INLINE_ void vc_static_ptrcall(R (*method)(P...), const void **p_args, void *r_ret) { + call_with_ptr_args_static_method_ret<R, P...>(method, p_args, r_ret); +} + +template <class... P> +static _FORCE_INLINE_ void vc_static_ptrcall(void (*method)(P...), const void **p_args, void *r_ret) { + call_with_ptr_args_static_method<P...>(method, p_args); +} + +#define STATIC_METHOD_CLASS(m_class, m_method_name, m_method_ptr) \ + struct Method_##m_class##_##m_method_name { \ + static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ + vc_static_method_call(m_method_ptr, p_args, p_argcount, r_ret, p_defvals, r_error); \ + } \ + static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ + vc_validated_static_call(m_method_ptr, p_args, r_ret); \ + } \ + static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ + vc_static_ptrcall(m_method_ptr, p_args, r_ret); \ + } \ + static int get_argument_count() { \ + return vc_get_argument_count_static(m_method_ptr); \ + } \ + static Variant::Type get_argument_type(int p_arg) { \ + return vc_get_argument_type_static(m_method_ptr, p_arg); \ + } \ + static Variant::Type get_return_type() { \ + return vc_get_return_type(m_method_ptr); \ + } \ + static bool has_return_type() { \ + return vc_has_return_type_static(m_method_ptr); \ + } \ + static bool is_const() { \ + return false; \ + } \ + static bool is_static() { \ + return true; \ + } \ + static bool is_vararg() { \ + return false; \ + } \ + static Variant::Type get_base_type() { \ + return GetTypeInfo<m_class>::VARIANT_TYPE; \ + } \ + static StringName get_name() { \ + return #m_method_name; \ + } \ + }; + template <class R, class T, class... P> static _FORCE_INLINE_ void vc_ptrcall(R (*method)(T *, P...), void *p_base, const void **p_args, void *r_ret) { call_with_ptr_args_static_retc<T, R, P...>(reinterpret_cast<T *>(p_base), method, p_args, r_ret); } -#define FUNCTION_CLASS(m_class, m_method_name, m_method_ptr) \ - struct Method_##m_class##_##m_method_name { \ - static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ - call_with_variant_args_retc_static_helper_dv(VariantGetInternalPtr<m_class>::get_ptr(base), m_method_ptr, p_args, p_argcount, r_ret, p_defvals, r_error); \ - } \ - static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ - vc_change_return_type(m_method_ptr, r_ret); \ - call_with_validated_variant_args_static_retc(base, m_method_ptr, p_args, r_ret); \ - } \ - static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ - vc_ptrcall(m_method_ptr, p_base, p_args, r_ret); \ - } \ - static int get_argument_count() { \ - return vc_get_argument_count(m_method_ptr); \ - } \ - static Variant::Type get_argument_type(int p_arg) { \ - return vc_get_argument_type(m_method_ptr, p_arg); \ - } \ - static Variant::Type get_return_type() { \ - return vc_get_return_type(m_method_ptr); \ - } \ - static bool has_return_type() { \ - return true; \ - } \ - static bool is_const() { \ - return true; \ - } \ - static bool is_vararg() { \ - return false; \ - } \ - static Variant::Type get_base_type() { \ - return GetTypeInfo<m_class>::VARIANT_TYPE; \ - } \ - static StringName get_name() { \ - return #m_method_name; \ - } \ +template <class T, class... P> +static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, const void **p_args, void *r_ret) { + call_with_ptr_args_static<T, P...>(reinterpret_cast<T *>(p_base), method, p_args); +} + +#define FUNCTION_CLASS(m_class, m_method_name, m_method_ptr, m_const) \ + struct Method_##m_class##_##m_method_name { \ + static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ + vc_method_call_static(m_method_ptr, base, p_args, p_argcount, r_ret, p_defvals, r_error); \ + } \ + static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ + vc_validated_call_static(m_method_ptr, base, p_args, r_ret); \ + } \ + static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ + vc_ptrcall(m_method_ptr, p_base, p_args, r_ret); \ + } \ + static int get_argument_count() { \ + return vc_get_argument_count(m_method_ptr); \ + } \ + static Variant::Type get_argument_type(int p_arg) { \ + return vc_get_argument_type(m_method_ptr, p_arg); \ + } \ + static Variant::Type get_return_type() { \ + return vc_get_return_type(m_method_ptr); \ + } \ + static bool has_return_type() { \ + return vc_has_return_type_static(m_method_ptr); \ + } \ + static bool is_const() { \ + return m_const; \ + } \ + static bool is_static() { \ + return false; \ + } \ + static bool is_vararg() { \ + return false; \ + } \ + static Variant::Type get_base_type() { \ + return GetTypeInfo<m_class>::VARIANT_TYPE; \ + } \ + static StringName get_name() { \ + return #m_method_name; \ + } \ }; #define VARARG_CLASS(m_class, m_method_name, m_method_ptr, m_has_return, m_return_type) \ @@ -379,6 +479,9 @@ static _FORCE_INLINE_ void vc_ptrcall(R (*method)(T *, P...), void *p_base, cons static bool is_const() { \ return true; \ } \ + static bool is_static() { \ + return false; \ + } \ static bool is_vararg() { \ return true; \ } \ @@ -397,7 +500,7 @@ struct _VariantCall { const uint8_t *r = p_instance->ptr(); CharString cs; cs.resize(p_instance->size() + 1); - copymem(cs.ptrw(), r, p_instance->size()); + memcpy(cs.ptrw(), r, p_instance->size()); cs[p_instance->size()] = 0; s = cs.get_data(); @@ -490,6 +593,195 @@ struct _VariantCall { return s; } + static int64_t func_PackedByteArray_decode_u8(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > int64_t(size) - 1, 0); + const uint8_t *r = p_instance->ptr(); + return r[p_offset]; + } + static int64_t func_PackedByteArray_decode_s8(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > int64_t(size) - 1, 0); + const uint8_t *r = p_instance->ptr(); + return *((const int8_t *)&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_u16(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 2), 0); + const uint8_t *r = p_instance->ptr(); + return decode_uint16(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_s16(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 2), 0); + const uint8_t *r = p_instance->ptr(); + return (int16_t)decode_uint16(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_u32(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 4), 0); + const uint8_t *r = p_instance->ptr(); + return decode_uint32(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_s32(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 4), 0); + const uint8_t *r = p_instance->ptr(); + return (int32_t)decode_uint32(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_u64(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 8), 0); + const uint8_t *r = p_instance->ptr(); + return (int64_t)decode_uint64(&r[p_offset]); + } + static int64_t func_PackedByteArray_decode_s64(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 8), 0); + const uint8_t *r = p_instance->ptr(); + return (int64_t)decode_uint64(&r[p_offset]); + } + static double func_PackedByteArray_decode_half(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 2), 0); + const uint8_t *r = p_instance->ptr(); + return Math::half_to_float(decode_uint16(&r[p_offset])); + } + static double func_PackedByteArray_decode_float(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 4), 0); + const uint8_t *r = p_instance->ptr(); + return decode_float(&r[p_offset]); + } + + static double func_PackedByteArray_decode_double(PackedByteArray *p_instance, int64_t p_offset) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 8), 0); + const uint8_t *r = p_instance->ptr(); + return decode_double(&r[p_offset]); + } + + static bool func_PackedByteArray_has_encoded_var(PackedByteArray *p_instance, int64_t p_offset, bool p_allow_objects) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0, false); + const uint8_t *r = p_instance->ptr(); + Variant ret; + Error err = decode_variant(ret, r + p_offset, size - p_offset, nullptr, p_allow_objects); + return err == OK; + } + + static Variant func_PackedByteArray_decode_var(PackedByteArray *p_instance, int64_t p_offset, bool p_allow_objects) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0, Variant()); + const uint8_t *r = p_instance->ptr(); + Variant ret; + Error err = decode_variant(ret, r + p_offset, size - p_offset, nullptr, p_allow_objects); + if (err != OK) { + ret = Variant(); + } + return ret; + } + + static int64_t func_PackedByteArray_decode_var_size(PackedByteArray *p_instance, int64_t p_offset, bool p_allow_objects) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0, 0); + const uint8_t *r = p_instance->ptr(); + Variant ret; + int r_size; + Error err = decode_variant(ret, r + p_offset, size - p_offset, &r_size, p_allow_objects); + if (err == OK) { + return r_size; + } + return 0; + } + + static void func_PackedByteArray_encode_u8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1); + uint8_t *w = p_instance->ptrw(); + *((uint8_t *)&w[p_offset]) = p_value; + } + static void func_PackedByteArray_encode_s8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1); + uint8_t *w = p_instance->ptrw(); + *((int8_t *)&w[p_offset]) = p_value; + } + + static void func_PackedByteArray_encode_u16(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 2); + uint8_t *w = p_instance->ptrw(); + encode_uint16((uint16_t)p_value, &w[p_offset]); + } + static void func_PackedByteArray_encode_s16(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 2); + uint8_t *w = p_instance->ptrw(); + encode_uint16((int16_t)p_value, &w[p_offset]); + } + + static void func_PackedByteArray_encode_u32(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 4); + uint8_t *w = p_instance->ptrw(); + encode_uint32((uint32_t)p_value, &w[p_offset]); + } + static void func_PackedByteArray_encode_s32(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 4); + uint8_t *w = p_instance->ptrw(); + encode_uint32((int32_t)p_value, &w[p_offset]); + } + + static void func_PackedByteArray_encode_u64(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 8); + uint8_t *w = p_instance->ptrw(); + encode_uint64((uint64_t)p_value, &w[p_offset]); + } + static void func_PackedByteArray_encode_s64(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 8); + uint8_t *w = p_instance->ptrw(); + encode_uint64((int64_t)p_value, &w[p_offset]); + } + + static void func_PackedByteArray_encode_half(PackedByteArray *p_instance, int64_t p_offset, double p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 2); + uint8_t *w = p_instance->ptrw(); + encode_uint16(Math::make_half_float(p_value), &w[p_offset]); + } + static void func_PackedByteArray_encode_float(PackedByteArray *p_instance, int64_t p_offset, double p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 4); + uint8_t *w = p_instance->ptrw(); + encode_float(p_value, &w[p_offset]); + } + static void func_PackedByteArray_encode_double(PackedByteArray *p_instance, int64_t p_offset, double p_value) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 8); + uint8_t *w = p_instance->ptrw(); + encode_double(p_value, &w[p_offset]); + } + static int64_t func_PackedByteArray_encode_var(PackedByteArray *p_instance, int64_t p_offset, const Variant &p_value, bool p_allow_objects) { + uint64_t size = p_instance->size(); + ERR_FAIL_COND_V(p_offset < 0, -1); + uint8_t *w = p_instance->ptrw(); + int len; + Error err = encode_variant(p_value, nullptr, len, p_allow_objects); + if (err != OK) { + return -1; + } + if (uint64_t(p_offset + len) > size) { + return -1; // did not fit + } + encode_variant(p_value, w + p_offset, len, p_allow_objects); + + return len; + } + static void func_Callable_call(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v); callable->call(p_args, p_argcount, r_ret, r_error); @@ -549,6 +841,7 @@ struct VariantBuiltInMethodInfo { Vector<String> argument_names; bool is_const; + bool is_static; bool has_return_type; bool is_vararg; Variant::Type return_type; @@ -580,6 +873,7 @@ static void register_builtin_method(const Vector<String> &p_argnames, const Vect imi.argument_names = p_argnames; imi.is_const = T::is_const(); + imi.is_static = T::is_static(); imi.is_vararg = T::is_vararg(); imi.has_return_type = T::has_return_type(); imi.return_type = T::get_return_type(); @@ -625,6 +919,24 @@ void Variant::call(const StringName &p_method, const Variant **p_args, int p_arg } } +void Variant::call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + + const VariantBuiltInMethodInfo *imf = builtin_method_info[p_type].lookup_ptr(p_method); + + if (!imf) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return; + } + + if (!imf->is_static) { + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; + return; + } + + imf->call(nullptr, p_args, p_argcount, r_ret, imf->default_arguments, r_error); +} + bool Variant::has_method(const StringName &p_method) const { if (type == OBJECT) { Object *obj = get_validated_object(); @@ -724,6 +1036,13 @@ bool Variant::is_builtin_method_const(Variant::Type p_type, const StringName &p_ return method->is_const; } +bool Variant::is_builtin_method_static(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, false); + return method->is_static; +} + bool Variant::is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method) { ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); @@ -759,7 +1078,9 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const { if (method->is_vararg) { mi.flags |= METHOD_FLAG_VARARG; } - + if (method->is_static) { + mi.flags |= METHOD_FLAG_STATIC; + } for (int i = 0; i < method->argument_count; i++) { PropertyInfo pi; #ifdef DEBUG_METHODS_ENABLED @@ -855,6 +1176,16 @@ Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_va #endif #ifdef DEBUG_METHODS_ENABLED +#define bind_static_method(m_type, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_method, m_type::m_method); \ + register_builtin_method<Method_##m_type##_##m_method>(m_arg_names, m_default_args); +#else +#define bind_static_method(m_type, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_method, m_type ::m_method); \ + register_builtin_method<Method_##m_type##_##m_method>(sarray(), m_default_args); +#endif + +#ifdef DEBUG_METHODS_ENABLED #define bind_methodv(m_type, m_name, m_method, m_arg_names, m_default_args) \ METHOD_CLASS(m_type, m_name, m_method); \ register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args); @@ -866,11 +1197,21 @@ Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_va #ifdef DEBUG_METHODS_ENABLED #define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \ - FUNCTION_CLASS(m_type, m_name, m_method); \ + FUNCTION_CLASS(m_type, m_name, m_method, true); \ register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args); #else #define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \ - FUNCTION_CLASS(m_type, m_name, m_method); \ + FUNCTION_CLASS(m_type, m_name, m_method, true); \ + register_builtin_method<Method_##m_type##_##m_name>(sarray(), m_default_args); +#endif + +#ifdef DEBUG_METHODS_ENABLED +#define bind_functionnc(m_type, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_name, m_method, false); \ + register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args); +#else +#define bind_functionnc(m_type, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_name, m_method, false); \ register_builtin_method<Method_##m_type##_##m_name>(sarray(), m_default_args); #endif @@ -956,6 +1297,8 @@ static void _register_variant_builtin_methods() { bind_method(String, c_unescape, sarray(), varray()); bind_method(String, json_escape, sarray(), varray()); + bind_method(String, validate_node_name, sarray(), varray()); + bind_method(String, is_valid_identifier, sarray(), varray()); bind_method(String, is_valid_integer, sarray(), varray()); bind_method(String, is_valid_float, sarray(), varray()); @@ -981,6 +1324,11 @@ static void _register_variant_builtin_methods() { bind_method(String, to_utf16_buffer, sarray(), varray()); bind_method(String, to_utf32_buffer, sarray(), varray()); + bind_static_method(String, num_scientific, sarray("number"), varray()); + bind_static_method(String, num, sarray("number", "decimals"), varray(-1)); + bind_static_method(String, chr, sarray("char"), varray()); + bind_static_method(String, humanize_size, sarray("size"), varray()); + /* Vector2 */ bind_method(Vector2, angle, sarray(), varray()); @@ -1145,6 +1493,17 @@ static void _register_variant_builtin_methods() { //ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0)); bind_method(Color, is_equal_approx, sarray("to"), varray()); + bind_static_method(Color, hex, sarray("hex"), varray()); + bind_static_method(Color, hex64, sarray("hex"), varray()); + bind_static_method(Color, html, sarray("rgba"), varray()); + bind_static_method(Color, html_is_valid, sarray("color"), varray()); + bind_static_method(Color, find_named_color, sarray("name"), varray()); + bind_static_method(Color, get_named_color_count, sarray(), varray()); + bind_static_method(Color, get_named_color_name, sarray("idx"), varray()); + bind_static_method(Color, get_named_color, sarray("idx"), varray()); + bind_static_method(Color, from_string, sarray("str", "default"), varray()); + bind_static_method(Color, from_rgbe9995, sarray("rgbe"), varray()); + /* RID */ bind_method(RID, get_id, sarray(), varray()); @@ -1288,6 +1647,7 @@ static void _register_variant_builtin_methods() { bind_method(Array, resize, sarray("size"), varray()); bind_method(Array, insert, sarray("position", "value"), varray()); bind_method(Array, remove, sarray("position"), varray()); + bind_method(Array, fill, sarray("value"), varray()); bind_method(Array, erase, sarray("value"), varray()); bind_method(Array, front, sarray(), varray()); bind_method(Array, back, sarray(), varray()); @@ -1303,7 +1663,7 @@ static void _register_variant_builtin_methods() { bind_method(Array, shuffle, sarray(), varray()); bind_method(Array, bsearch, sarray("value", "before"), varray(true)); bind_method(Array, bsearch_custom, sarray("value", "func", "before"), varray(true)); - bind_method(Array, invert, sarray(), varray()); + bind_method(Array, reverse, sarray(), varray()); bind_method(Array, duplicate, sarray("deep"), varray(false)); bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false)); bind_method(Array, max, sarray(), varray()); @@ -1318,9 +1678,10 @@ static void _register_variant_builtin_methods() { bind_method(PackedByteArray, append_array, sarray("array"), varray()); bind_method(PackedByteArray, remove, sarray("index"), varray()); bind_method(PackedByteArray, insert, sarray("at_index", "value"), varray()); + bind_method(PackedByteArray, fill, sarray("value"), varray()); bind_method(PackedByteArray, resize, sarray("new_size"), varray()); bind_method(PackedByteArray, has, sarray("value"), varray()); - bind_method(PackedByteArray, invert, sarray(), varray()); + bind_method(PackedByteArray, reverse, sarray(), varray()); bind_method(PackedByteArray, subarray, sarray("from", "to"), varray()); bind_method(PackedByteArray, sort, sarray(), varray()); bind_method(PackedByteArray, duplicate, sarray(), varray()); @@ -1334,6 +1695,34 @@ static void _register_variant_builtin_methods() { bind_function(PackedByteArray, decompress, _VariantCall::func_PackedByteArray_decompress, sarray("buffer_size", "compression_mode"), varray(0)); bind_function(PackedByteArray, decompress_dynamic, _VariantCall::func_PackedByteArray_decompress_dynamic, sarray("max_output_size", "compression_mode"), varray(0)); + bind_function(PackedByteArray, decode_u8, _VariantCall::func_PackedByteArray_decode_u8, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_s8, _VariantCall::func_PackedByteArray_decode_s8, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_u16, _VariantCall::func_PackedByteArray_decode_u16, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_s16, _VariantCall::func_PackedByteArray_decode_s16, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_u32, _VariantCall::func_PackedByteArray_decode_u32, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_s32, _VariantCall::func_PackedByteArray_decode_s32, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_u64, _VariantCall::func_PackedByteArray_decode_u64, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_s64, _VariantCall::func_PackedByteArray_decode_s64, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_half, _VariantCall::func_PackedByteArray_decode_half, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_float, _VariantCall::func_PackedByteArray_decode_float, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, decode_double, _VariantCall::func_PackedByteArray_decode_double, sarray("byte_offset"), varray()); + bind_function(PackedByteArray, has_encoded_var, _VariantCall::func_PackedByteArray_has_encoded_var, sarray("byte_offset", "allow_objects"), varray(false)); + bind_function(PackedByteArray, decode_var, _VariantCall::func_PackedByteArray_decode_var, sarray("byte_offset", "allow_objects"), varray(false)); + bind_function(PackedByteArray, decode_var_size, _VariantCall::func_PackedByteArray_decode_var_size, sarray("byte_offset", "allow_objects"), varray(false)); + + bind_functionnc(PackedByteArray, encode_u8, _VariantCall::func_PackedByteArray_encode_u8, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_s8, _VariantCall::func_PackedByteArray_encode_s8, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_u16, _VariantCall::func_PackedByteArray_encode_u16, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_s16, _VariantCall::func_PackedByteArray_encode_s16, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_u32, _VariantCall::func_PackedByteArray_encode_u32, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_s32, _VariantCall::func_PackedByteArray_encode_s32, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_u64, _VariantCall::func_PackedByteArray_encode_u64, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_s64, _VariantCall::func_PackedByteArray_encode_s64, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_half, _VariantCall::func_PackedByteArray_encode_half, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_float, _VariantCall::func_PackedByteArray_encode_float, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_double, _VariantCall::func_PackedByteArray_encode_double, sarray("byte_offset", "value"), varray()); + bind_functionnc(PackedByteArray, encode_var, _VariantCall::func_PackedByteArray_encode_var, sarray("byte_offset", "value", "allow_objects"), varray(false)); + /* Int32 Array */ bind_method(PackedInt32Array, size, sarray(), varray()); @@ -1344,9 +1733,10 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt32Array, append_array, sarray("array"), varray()); bind_method(PackedInt32Array, remove, sarray("index"), varray()); bind_method(PackedInt32Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedInt32Array, fill, sarray("value"), varray()); bind_method(PackedInt32Array, resize, sarray("new_size"), varray()); bind_method(PackedInt32Array, has, sarray("value"), varray()); - bind_method(PackedInt32Array, invert, sarray(), varray()); + bind_method(PackedInt32Array, reverse, sarray(), varray()); bind_method(PackedInt32Array, subarray, sarray("from", "to"), varray()); bind_method(PackedInt32Array, to_byte_array, sarray(), varray()); bind_method(PackedInt32Array, sort, sarray(), varray()); @@ -1362,9 +1752,10 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt64Array, append_array, sarray("array"), varray()); bind_method(PackedInt64Array, remove, sarray("index"), varray()); bind_method(PackedInt64Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedInt64Array, fill, sarray("value"), varray()); bind_method(PackedInt64Array, resize, sarray("new_size"), varray()); bind_method(PackedInt64Array, has, sarray("value"), varray()); - bind_method(PackedInt64Array, invert, sarray(), varray()); + bind_method(PackedInt64Array, reverse, sarray(), varray()); bind_method(PackedInt64Array, subarray, sarray("from", "to"), varray()); bind_method(PackedInt64Array, to_byte_array, sarray(), varray()); bind_method(PackedInt64Array, sort, sarray(), varray()); @@ -1380,9 +1771,10 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat32Array, append_array, sarray("array"), varray()); bind_method(PackedFloat32Array, remove, sarray("index"), varray()); bind_method(PackedFloat32Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedFloat32Array, fill, sarray("value"), varray()); bind_method(PackedFloat32Array, resize, sarray("new_size"), varray()); bind_method(PackedFloat32Array, has, sarray("value"), varray()); - bind_method(PackedFloat32Array, invert, sarray(), varray()); + bind_method(PackedFloat32Array, reverse, sarray(), varray()); bind_method(PackedFloat32Array, subarray, sarray("from", "to"), varray()); bind_method(PackedFloat32Array, to_byte_array, sarray(), varray()); bind_method(PackedFloat32Array, sort, sarray(), varray()); @@ -1398,9 +1790,10 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat64Array, append_array, sarray("array"), varray()); bind_method(PackedFloat64Array, remove, sarray("index"), varray()); bind_method(PackedFloat64Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedFloat64Array, fill, sarray("value"), varray()); bind_method(PackedFloat64Array, resize, sarray("new_size"), varray()); bind_method(PackedFloat64Array, has, sarray("value"), varray()); - bind_method(PackedFloat64Array, invert, sarray(), varray()); + bind_method(PackedFloat64Array, reverse, sarray(), varray()); bind_method(PackedFloat64Array, subarray, sarray("from", "to"), varray()); bind_method(PackedFloat64Array, to_byte_array, sarray(), varray()); bind_method(PackedFloat64Array, sort, sarray(), varray()); @@ -1416,9 +1809,10 @@ static void _register_variant_builtin_methods() { bind_method(PackedStringArray, append_array, sarray("array"), varray()); bind_method(PackedStringArray, remove, sarray("index"), varray()); bind_method(PackedStringArray, insert, sarray("at_index", "value"), varray()); + bind_method(PackedStringArray, fill, sarray("value"), varray()); bind_method(PackedStringArray, resize, sarray("new_size"), varray()); bind_method(PackedStringArray, has, sarray("value"), varray()); - bind_method(PackedStringArray, invert, sarray(), varray()); + bind_method(PackedStringArray, reverse, sarray(), varray()); bind_method(PackedStringArray, subarray, sarray("from", "to"), varray()); bind_method(PackedStringArray, to_byte_array, sarray(), varray()); bind_method(PackedStringArray, sort, sarray(), varray()); @@ -1434,9 +1828,10 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector2Array, append_array, sarray("array"), varray()); bind_method(PackedVector2Array, remove, sarray("index"), varray()); bind_method(PackedVector2Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedVector2Array, fill, sarray("value"), varray()); bind_method(PackedVector2Array, resize, sarray("new_size"), varray()); bind_method(PackedVector2Array, has, sarray("value"), varray()); - bind_method(PackedVector2Array, invert, sarray(), varray()); + bind_method(PackedVector2Array, reverse, sarray(), varray()); bind_method(PackedVector2Array, subarray, sarray("from", "to"), varray()); bind_method(PackedVector2Array, to_byte_array, sarray(), varray()); bind_method(PackedVector2Array, sort, sarray(), varray()); @@ -1452,9 +1847,10 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector3Array, append_array, sarray("array"), varray()); bind_method(PackedVector3Array, remove, sarray("index"), varray()); bind_method(PackedVector3Array, insert, sarray("at_index", "value"), varray()); + bind_method(PackedVector3Array, fill, sarray("value"), varray()); bind_method(PackedVector3Array, resize, sarray("new_size"), varray()); bind_method(PackedVector3Array, has, sarray("value"), varray()); - bind_method(PackedVector3Array, invert, sarray(), varray()); + bind_method(PackedVector3Array, reverse, sarray(), varray()); bind_method(PackedVector3Array, subarray, sarray("from", "to"), varray()); bind_method(PackedVector3Array, to_byte_array, sarray(), varray()); bind_method(PackedVector3Array, sort, sarray(), varray()); @@ -1470,9 +1866,10 @@ static void _register_variant_builtin_methods() { bind_method(PackedColorArray, append_array, sarray("array"), varray()); bind_method(PackedColorArray, remove, sarray("index"), varray()); bind_method(PackedColorArray, insert, sarray("at_index", "value"), varray()); + bind_method(PackedColorArray, fill, sarray("value"), varray()); bind_method(PackedColorArray, resize, sarray("new_size"), varray()); bind_method(PackedColorArray, has, sarray("value"), varray()); - bind_method(PackedColorArray, invert, sarray(), varray()); + bind_method(PackedColorArray, reverse, sarray(), varray()); bind_method(PackedColorArray, subarray, sarray("from", "to"), varray()); bind_method(PackedColorArray, to_byte_array, sarray(), varray()); bind_method(PackedColorArray, sort, sarray(), varray()); diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index e0a3cf4215..6cbc98d14d 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -1365,10 +1365,10 @@ void register_op(Variant::Operator p_op, Variant::Type p_type_a, Variant::Type p } void Variant::_register_variant_operators() { - zeromem(operator_return_type_table, sizeof(operator_return_type_table)); - zeromem(operator_evaluator_table, sizeof(operator_evaluator_table)); - zeromem(validated_operator_evaluator_table, sizeof(validated_operator_evaluator_table)); - zeromem(ptr_operator_evaluator_table, sizeof(ptr_operator_evaluator_table)); + memset(operator_return_type_table, 0, sizeof(operator_return_type_table)); + memset(operator_evaluator_table, 0, sizeof(operator_evaluator_table)); + memset(validated_operator_evaluator_table, 0, sizeof(validated_operator_evaluator_table)); + memset(ptr_operator_evaluator_table, 0, sizeof(ptr_operator_evaluator_table)); register_op<OperatorEvaluatorAdd<int64_t, int64_t, int64_t>>(Variant::OP_ADD, Variant::INT, Variant::INT); register_op<OperatorEvaluatorAdd<double, int64_t, double>>(Variant::OP_ADD, Variant::INT, Variant::FLOAT); diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index ed936c626b..edaeddbf27 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -381,7 +381,6 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri r_token.value = num.as_int(); } return OK; - } else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') { StringBuffer<> id; bool first = true; @@ -508,8 +507,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } else if (id == "nan") { value = Math_NAN; } else if (id == "Vector2") { - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -534,8 +533,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = Vector2i(args[0], args[1]); } else if (id == "Rect2") { - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -560,8 +559,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = Rect2i(args[0], args[1], args[2], args[3]); } else if (id == "Vector3") { - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -586,8 +585,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = Vector3i(args[0], args[1], args[2]); } else if (id == "Transform2D" || id == "Matrix32") { //compatibility - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -603,8 +602,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, m[2] = Vector2(args[4], args[5]); value = m; } else if (id == "Plane") { - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -616,8 +615,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = Plane(args[0], args[1], args[2], args[3]); } else if (id == "Quat") { - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -629,8 +628,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = Quat(args[0], args[1], args[2], args[3]); } else if (id == "AABB" || id == "Rect3") { - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -642,8 +641,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = AABB(Vector3(args[0], args[1], args[2]), Vector3(args[3], args[4], args[5])); } else if (id == "Basis" || id == "Matrix3") { //compatibility - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -655,8 +654,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); } else if (id == "Transform") { - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -1006,8 +1005,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = arr; } else if (id == "PackedVector2Array" || id == "PoolVector2Array" || id == "Vector2Array") { - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } @@ -1024,8 +1023,8 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = arr; } else if (id == "PackedVector3Array" || id == "PoolVector3Array" || id == "Vector3Array") { - Vector<float> args; - Error err = _parse_construct<float>(p_stream, args, line, r_err_str); + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); if (err) { return err; } diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index ea8263402a..9ab8602782 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -875,65 +875,66 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ }; -#define INDEXED_SETGET_STRUCT_VARIANT(m_base_type) \ - struct VariantIndexedSetGet_##m_base_type { \ - static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \ - int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ - if (index < 0) { \ - index += size; \ - } \ - if (index < 0 || index >= size) { \ - *oob = true; \ - return; \ - } \ - *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ - *oob = false; \ - } \ - static void ptr_get(const void *base, int64_t index, void *member) { \ - /* avoid ptrconvert for performance*/ \ - const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \ - if (index < 0) \ - index += v.size(); \ - OOB_TEST(index, v.size()); \ - PtrToArg<Variant>::encode(v[index], member); \ - } \ - static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) { \ - int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ - if (index < 0) { \ - index += size; \ - } \ - if (index < 0 || index >= size) { \ - *oob = true; \ - *valid = false; \ - return; \ - } \ - (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \ - *oob = false; \ - *valid = true; \ - } \ - static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) { \ - int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ - if (index < 0) { \ - index += size; \ - } \ - if (index < 0 || index >= size) { \ - *oob = true; \ - return; \ - } \ - (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \ - *oob = false; \ - } \ - static void ptr_set(void *base, int64_t index, const void *member) { \ - /* avoid ptrconvert for performance*/ \ - m_base_type &v = *reinterpret_cast<m_base_type *>(base); \ - if (index < 0) \ - index += v.size(); \ - OOB_TEST(index, v.size()); \ - v[index] = PtrToArg<Variant>::convert(member); \ - } \ - static Variant::Type get_index_type() { return Variant::NIL; } \ - static uint64_t get_indexed_size(const Variant *base) { return 0; } \ - }; +struct VariantIndexedSetGet_Array { + static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { + int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size(); + if (index < 0) { + index += size; + } + if (index < 0 || index >= size) { + *oob = true; + return; + } + *value = (*VariantGetInternalPtr<Array>::get_ptr(base))[index]; + *oob = false; + } + static void ptr_get(const void *base, int64_t index, void *member) { + /* avoid ptrconvert for performance*/ + const Array &v = *reinterpret_cast<const Array *>(base); + if (index < 0) { + index += v.size(); + } + OOB_TEST(index, v.size()); + PtrToArg<Variant>::encode(v[index], member); + } + static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) { + int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size(); + if (index < 0) { + index += size; + } + if (index < 0 || index >= size) { + *oob = true; + *valid = false; + return; + } + VariantGetInternalPtr<Array>::get_ptr(base)->set(index, *value); + *oob = false; + *valid = true; + } + static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) { + int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size(); + if (index < 0) { + index += size; + } + if (index < 0 || index >= size) { + *oob = true; + return; + } + VariantGetInternalPtr<Array>::get_ptr(base)->set(index, *value); + *oob = false; + } + static void ptr_set(void *base, int64_t index, const void *member) { + /* avoid ptrconvert for performance*/ + Array &v = *reinterpret_cast<Array *>(base); + if (index < 0) { + index += v.size(); + } + OOB_TEST(index, v.size()); + v.set(index, PtrToArg<Variant>::convert(member)); + } + static Variant::Type get_index_type() { return Variant::NIL; } + static uint64_t get_indexed_size(const Variant *base) { return 0; } +}; #define INDEXED_SETGET_STRUCT_DICT(m_base_type) \ struct VariantIndexedSetGet_##m_base_type { \ @@ -990,7 +991,6 @@ INDEXED_SETGET_STRUCT_TYPED(PackedVector3Array, Vector3) INDEXED_SETGET_STRUCT_TYPED(PackedStringArray, String) INDEXED_SETGET_STRUCT_TYPED(PackedColorArray, Color) -INDEXED_SETGET_STRUCT_VARIANT(Array) INDEXED_SETGET_STRUCT_DICT(Dictionary) struct VariantIndexedSetterGetterInfo { @@ -1045,6 +1045,7 @@ void register_indexed_setters_getters() { REGISTER_INDEXED_MEMBER(PackedByteArray); REGISTER_INDEXED_MEMBER(PackedInt32Array); REGISTER_INDEXED_MEMBER(PackedInt64Array); + REGISTER_INDEXED_MEMBER(PackedFloat32Array); REGISTER_INDEXED_MEMBER(PackedFloat64Array); REGISTER_INDEXED_MEMBER(PackedVector2Array); REGISTER_INDEXED_MEMBER(PackedVector3Array); @@ -2198,7 +2199,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } return; case STRING: { - //this is pretty funny and bizarre, but artists like to use it for typewritter effects + //this is pretty funny and bizarre, but artists like to use it for typewriter effects String sa = *reinterpret_cast<const String *>(a._data._mem); String sb = *reinterpret_cast<const String *>(b._data._mem); String dst; |