diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 0eaa1b850ab1..62b605f7d305 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -797,6 +797,17 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) { d2["is_static"] = Variant::is_builtin_method_static(type, method_name); d2["hash"] = Variant::get_builtin_method_hash(type, method_name); + Vector compat_hashes = Variant::get_builtin_method_compatibility_hashes(type, method_name); + Array compatibility; + if (compat_hashes.size()) { + for (int j = 0; j < compat_hashes.size(); j++) { + compatibility.push_back(compat_hashes[j]); + } + } + if (compatibility.size() > 0) { + d2["hash_compatibility"] = compatibility; + } + Vector default_args = Variant::get_builtin_method_default_arguments(type, method_name); Array arguments; diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp index ecd5dff14c40..1ca98ba0556a 100644 --- a/core/extension/gdextension_interface.cpp +++ b/core/extension/gdextension_interface.cpp @@ -817,13 +817,11 @@ static GDExtensionPtrOperatorEvaluator gdextension_variant_get_ptr_operator_eval } static GDExtensionPtrBuiltInMethod gdextension_variant_get_ptr_builtin_method(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, GDExtensionInt p_hash) { const StringName method = *reinterpret_cast(p_method); - uint32_t hash = Variant::get_builtin_method_hash(Variant::Type(p_type), method); - if (hash != p_hash) { - ERR_PRINT_ONCE("Error getting method " + method + ", hash mismatch."); - return nullptr; + GDExtensionPtrBuiltInMethod ptr = (GDExtensionPtrBuiltInMethod)Variant::get_ptr_builtin_method_with_compatibility(Variant::Type(p_type), method, p_hash); + if (!ptr) { + ERR_PRINT("Error getting method " + method + ", missing or hash mismatch."); } - - return (GDExtensionPtrBuiltInMethod)Variant::get_ptr_builtin_method(Variant::Type(p_type), method); + return ptr; } static GDExtensionPtrConstructor gdextension_variant_get_ptr_constructor(GDExtensionVariantType p_type, int32_t p_constructor) { return (GDExtensionPtrConstructor)Variant::get_ptr_constructor(Variant::Type(p_type), p_constructor); diff --git a/core/templates/vector.h b/core/templates/vector.h index 1c0bc67a9364..ebca50b77a89 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -184,10 +184,16 @@ class Vector { return span().bisect(p_value, p_before, Comparator{ args... }); } - Vector duplicate() { + Vector duplicate() const { return *this; } +#ifndef DISABLE_DEPRECATED + Vector _duplicate_bind_compat_112290() { + return *this; + } +#endif // DISABLE_DEPRECATED + void ordered_insert(const T &p_val) { Size i; for (i = 0; i < _cowdata.size(); i++) { diff --git a/core/variant/variant.h b/core/variant/variant.h index 44cd11c7be72..e6635efd2e8e 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -645,6 +645,7 @@ class Variant { static ValidatedBuiltInMethod get_validated_builtin_method(Variant::Type p_type, const StringName &p_method); static PTRBuiltInMethod get_ptr_builtin_method(Variant::Type p_type, const StringName &p_method); + static PTRBuiltInMethod get_ptr_builtin_method_with_compatibility(Variant::Type p_type, const StringName &p_method, uint32_t p_hash); static MethodInfo get_builtin_method_info(Variant::Type p_type, const StringName &p_method); static int get_builtin_method_argument_count(Variant::Type p_type, const StringName &p_method); @@ -659,6 +660,7 @@ class Variant { static void get_builtin_method_list(Variant::Type p_type, List *p_list); static int get_builtin_method_count(Variant::Type p_type); static uint32_t get_builtin_method_hash(Variant::Type p_type, const StringName &p_method); + static Vector get_builtin_method_compatibility_hashes(Variant::Type p_type, const StringName &p_method); void callp(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 33f44c13feda..b9623404a7d4 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -369,7 +369,7 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con return GetTypeInfo::VARIANT_TYPE; } -#define METHOD_CLASS(m_class, m_method_name, m_method_ptr) \ +#define METHOD_CLASS(m_class, m_exposed_name, 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 &p_defvals, Callable::CallError &r_error) { \ vc_method_call(m_method_ptr, base, p_args, p_argcount, r_ret, p_defvals, r_error); \ @@ -405,11 +405,11 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con return vc_get_base_type(m_method_ptr); \ } \ static StringName get_name() { \ - return #m_method_name; \ + return #m_exposed_name; \ } \ }; -#define CONVERT_METHOD_CLASS(m_class, m_method_name, m_method_ptr) \ +#define CONVERT_METHOD_CLASS(m_class, m_exposed_name, 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 &p_defvals, Callable::CallError &r_error) { \ vc_convert_method_call(m_method_ptr, base, p_args, p_argcount, r_ret, p_defvals, r_error); \ @@ -445,7 +445,7 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con return GetTypeInfo::VARIANT_TYPE; \ } \ static StringName get_name() { \ - return #m_method_name; \ + return #m_exposed_name; \ } \ }; @@ -459,7 +459,7 @@ static _FORCE_INLINE_ void vc_static_ptrcall(void (*method)(P...), const void ** call_with_ptr_args_static_method(method, p_args); } -#define STATIC_METHOD_CLASS(m_class, m_method_name, m_method_ptr) \ +#define STATIC_METHOD_CLASS(m_class, m_exposed_name, 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 &p_defvals, Callable::CallError &r_error) { \ vc_static_method_call(m_method_ptr, p_args, p_argcount, r_ret, p_defvals, r_error); \ @@ -495,7 +495,7 @@ static _FORCE_INLINE_ void vc_static_ptrcall(void (*method)(P...), const void ** return GetTypeInfo::VARIANT_TYPE; \ } \ static StringName get_name() { \ - return #m_method_name; \ + return #m_exposed_name; \ } \ }; @@ -509,7 +509,7 @@ static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, c call_with_ptr_args_static(reinterpret_cast(p_base), method, p_args); } -#define FUNCTION_CLASS(m_class, m_method_name, m_method_ptr, m_const) \ +#define FUNCTION_CLASS(m_class, m_exposed_name, 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 &p_defvals, Callable::CallError &r_error) { \ vc_method_call_static(m_method_ptr, base, p_args, p_argcount, r_ret, p_defvals, r_error); \ @@ -545,11 +545,11 @@ static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, c return GetTypeInfo::VARIANT_TYPE; \ } \ static StringName get_name() { \ - return #m_method_name; \ + return #m_exposed_name; \ } \ }; -#define VARARG_CLASS(m_class, m_method_name, m_method_ptr, m_has_return, m_return_type) \ +#define VARARG_CLASS(m_class, m_exposed_name, m_method_name, m_method_ptr, m_has_return, m_return_type) \ struct Method_##m_class##_##m_method_name { \ static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector &p_defvals, Callable::CallError &r_error) { \ m_method_ptr(base, p_args, p_argcount, r_ret, r_error); \ @@ -601,11 +601,11 @@ static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, c return GetTypeInfo::VARIANT_TYPE; \ } \ static StringName get_name() { \ - return #m_method_name; \ + return #m_exposed_name; \ } \ }; -#define VARARG_CLASS1(m_class, m_method_name, m_method_ptr, m_arg_type) \ +#define VARARG_CLASS1(m_class, m_exposed_name, m_method_name, m_method_ptr, m_arg_type) \ struct Method_##m_class##_##m_method_name { \ static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector &p_defvals, Callable::CallError &r_error) { \ m_method_ptr(base, p_args, p_argcount, r_ret, r_error); \ @@ -653,7 +653,7 @@ static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, c return GetTypeInfo::VARIANT_TYPE; \ } \ static StringName get_name() { \ - return #m_method_name; \ + return #m_exposed_name; \ } \ }; @@ -1318,12 +1318,51 @@ struct VariantBuiltInMethodInfo { return mi; } + + uint32_t get_hash() const { + uint32_t hash = hash_murmur3_one_32(is_const); + hash = hash_murmur3_one_32(is_static, hash); + hash = hash_murmur3_one_32(is_vararg, hash); + hash = hash_murmur3_one_32(has_return_type, hash); + if (has_return_type) { + hash = hash_murmur3_one_32(return_type, hash); + } + hash = hash_murmur3_one_32(argument_count, hash); + for (int i = 0; i < argument_count; i++) { + hash = hash_murmur3_one_32(get_argument_type(i), hash); + } + + return hash_fmix32(hash); + } }; typedef AHashMap BuiltinMethodMap; static BuiltinMethodMap *builtin_method_info; static List *builtin_method_names; +#ifndef DISABLE_DEPRECATED +typedef AHashMap> BuiltinCompatMethodMap; +static BuiltinCompatMethodMap *builtin_compat_method_info; +#endif + +template +static void _populate_variant_builtin_method_info(VariantBuiltInMethodInfo &r_imi, const Vector &p_argnames, const Vector &p_def_args) { + r_imi.call = T::call; + r_imi.validated_call = T::validated_call; + r_imi.ptrcall = T::ptrcall; + + r_imi.default_arguments = p_def_args; + r_imi.argument_names = p_argnames; + + r_imi.is_const = T::is_const(); + r_imi.is_static = T::is_static(); + r_imi.is_vararg = T::is_vararg(); + r_imi.has_return_type = T::has_return_type(); + r_imi.return_type = T::get_return_type(); + r_imi.argument_count = T::get_argument_count(); + r_imi.get_argument_type = T::get_argument_type; +} + template static void register_builtin_method(const Vector &p_argnames, const Vector &p_def_args) { StringName name = T::get_name(); @@ -1331,21 +1370,8 @@ static void register_builtin_method(const Vector &p_argnames, const Vect ERR_FAIL_COND(builtin_method_info[T::get_base_type()].has(name)); VariantBuiltInMethodInfo imi; + _populate_variant_builtin_method_info(imi, p_argnames, p_def_args); - imi.call = T::call; - imi.validated_call = T::validated_call; - imi.ptrcall = T::ptrcall; - - imi.default_arguments = p_def_args; - 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(); - imi.argument_count = T::get_argument_count(); - imi.get_argument_type = T::get_argument_type; #ifdef DEBUG_ENABLED ERR_FAIL_COND(!imi.is_vararg && imi.argument_count != imi.argument_names.size()); #endif // DEBUG_ENABLED @@ -1354,6 +1380,27 @@ static void register_builtin_method(const Vector &p_argnames, const Vect builtin_method_names[T::get_base_type()].push_back(name); } +#ifndef DISABLE_DEPRECATED +template +static void register_builtin_compat_method(const Vector &p_argnames, const Vector &p_def_args) { + StringName name = T::get_name(); + + ERR_FAIL_COND(!builtin_method_info[T::get_base_type()].has(name)); + + VariantBuiltInMethodInfo imi; + _populate_variant_builtin_method_info(imi, p_argnames, p_def_args); + +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!imi.is_vararg && imi.argument_count != imi.argument_names.size()); +#endif // DEBUG_ENABLED + + if (!builtin_compat_method_info[T::get_base_type()].has(name)) { + builtin_compat_method_info[T::get_base_type()].insert(name, LocalVector()); + } + builtin_compat_method_info[T::get_base_type()][name].push_back(imi); +} +#endif + void Variant::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { if (type == Variant::OBJECT) { //call object @@ -1472,6 +1519,28 @@ Variant::PTRBuiltInMethod Variant::get_ptr_builtin_method(Variant::Type p_type, return method->ptrcall; } +Variant::PTRBuiltInMethod Variant::get_ptr_builtin_method_with_compatibility(Variant::Type p_type, const StringName &p_method, uint32_t p_hash) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].getptr(p_method); + if (method && method->get_hash() == p_hash) { + return method->ptrcall; + } + +#ifndef DISABLE_DEPRECATED + const LocalVector *compat_methods = builtin_compat_method_info[p_type].getptr(p_method); + if (compat_methods) { + for (const VariantBuiltInMethodInfo &imi : *compat_methods) { + if (imi.get_hash() == p_hash) { + return imi.ptrcall; + } + } + } +#endif + + return nullptr; +} + MethodInfo Variant::get_builtin_method_info(Variant::Type p_type, const StringName &p_method) { ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, MethodInfo()); const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].getptr(p_method); @@ -1564,19 +1633,21 @@ uint32_t Variant::get_builtin_method_hash(Variant::Type p_type, const StringName ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0); const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].getptr(p_method); ERR_FAIL_NULL_V(method, 0); - uint32_t hash = hash_murmur3_one_32(method->is_const); - hash = hash_murmur3_one_32(method->is_static, hash); - hash = hash_murmur3_one_32(method->is_vararg, hash); - hash = hash_murmur3_one_32(method->has_return_type, hash); - if (method->has_return_type) { - hash = hash_murmur3_one_32(method->return_type, hash); - } - hash = hash_murmur3_one_32(method->argument_count, hash); - for (int i = 0; i < method->argument_count; i++) { - hash = hash_murmur3_one_32(method->get_argument_type(i), hash); - } + return method->get_hash(); +} - return hash_fmix32(hash); +Vector Variant::get_builtin_method_compatibility_hashes(Variant::Type p_type, const StringName &p_method) { + Vector method_hashes; +#ifndef DISABLE_DEPRECATED + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, method_hashes); + const LocalVector *compat_methods = builtin_compat_method_info[p_type].getptr(p_method); + if (compat_methods) { + for (const VariantBuiltInMethodInfo &imi : *compat_methods) { + method_hashes.push_back(imi.get_hash()); + } + } +#endif + return method_hashes; } void Variant::get_method_list(List *p_list) const { @@ -1725,84 +1796,164 @@ StringName Variant::get_enum_for_enumeration(Variant::Type p_type, const StringN #ifdef DEBUG_ENABLED #define bind_method(m_type, m_method, m_arg_names, m_default_args) \ - METHOD_CLASS(m_type, m_method, &m_type::m_method); \ + METHOD_CLASS(m_type, m_method, m_method, &m_type::m_method); \ register_builtin_method(m_arg_names, m_default_args); #else #define bind_method(m_type, m_method, m_arg_names, m_default_args) \ - METHOD_CLASS(m_type, m_method, &m_type ::m_method); \ + METHOD_CLASS(m_type, m_method, m_method, &m_type ::m_method); \ register_builtin_method(sarray(), m_default_args); #endif // DEBUG_ENABLED +#ifdef DEBUG_ENABLED +#define bind_compat_method(m_type, m_exposed_method, m_method, m_arg_names, m_default_args) \ + METHOD_CLASS(m_type, m_exposed_method, m_method, &m_type::m_method); \ + register_builtin_compat_method(m_arg_names, m_default_args); +#else +#define bind_compat_method(m_type, m_exposed_method, m_method, m_arg_names, m_default_args) \ + METHOD_CLASS(m_type, m_exposed_method, m_method, &m_type ::m_method); \ + register_builtin_compat_method(sarray(), m_default_args); +#endif // DEBUG_ENABLED + #ifdef DEBUG_ENABLED #define bind_convert_method(m_type_from, m_type_to, m_method, m_arg_names, m_default_args) \ - CONVERT_METHOD_CLASS(m_type_from, m_method, &m_type_to::m_method); \ + CONVERT_METHOD_CLASS(m_type_from, m_method, m_method, &m_type_to::m_method); \ register_builtin_method(m_arg_names, m_default_args); #else #define bind_convert_method(m_type_from, m_type_to, m_method, m_arg_names, m_default_args) \ - CONVERT_METHOD_CLASS(m_type_from, m_method, &m_type_to ::m_method); \ + CONVERT_METHOD_CLASS(m_type_from, m_method, m_method, &m_type_to ::m_method); \ register_builtin_method(sarray(), m_default_args); #endif // DEBUG_ENABLED +#ifdef DEBUG_ENABLED +#define bind_convert_compat_method(m_type_from, m_type_to, m_exposed_method, m_method, m_arg_names, m_default_args) \ + CONVERT_METHOD_CLASS(m_type_from, m_exposed_method, m_method, &m_type_to::m_method); \ + register_builtin_compat_method(m_arg_names, m_default_args); +#else +#define bind_convert_compat_method(m_type_from, m_type_to, m_exposed_method, m_method, m_arg_names, m_default_args) \ + CONVERT_METHOD_CLASS(m_type_from, m_exposed_method, m_method, &m_type_to ::m_method); \ + register_builtin_compat_method(sarray(), m_default_args); +#endif // DEBUG_ENABLED + #ifdef DEBUG_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); \ + STATIC_METHOD_CLASS(m_type, m_method, m_method, m_type::m_method); \ register_builtin_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); \ + STATIC_METHOD_CLASS(m_type, m_method, m_method, m_type ::m_method); \ register_builtin_method(sarray(), m_default_args); #endif // DEBUG_ENABLED +#ifdef DEBUG_ENABLED +#define bind_static_compat_method(m_type, m_exposed_method, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_exposed_method, m_method, m_type::m_method); \ + register_builtin_compat_method(m_arg_names, m_default_args); +#else +#define bind_static_compat_method(m_type, m_exposed_method, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_exposed_method, m_method, m_type ::m_method); \ + register_builtin_compat_method(sarray(), m_default_args); +#endif // DEBUG_ENABLED + #ifdef DEBUG_ENABLED #define bind_static_methodv(m_type, m_name, m_method, m_arg_names, m_default_args) \ - STATIC_METHOD_CLASS(m_type, m_name, m_method); \ + STATIC_METHOD_CLASS(m_type, m_name, m_name, m_method); \ register_builtin_method(m_arg_names, m_default_args); #else #define bind_static_methodv(m_type, m_name, m_method, m_arg_names, m_default_args) \ - STATIC_METHOD_CLASS(m_type, m_name, m_method); \ + STATIC_METHOD_CLASS(m_type, m_name, m_name, m_method); \ register_builtin_method(sarray(), m_default_args); #endif +#ifdef DEBUG_ENABLED +#define bind_static_compat_methodv(m_type, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_exposed_name, m_name, m_method); \ + register_builtin_compat_method(m_arg_names, m_default_args); +#else +#define bind_static_compat_methodv(m_type, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_exposed_name, m_name, m_method); \ + register_builtin_compat_method(sarray(), m_default_args); +#endif + #ifdef DEBUG_ENABLED #define bind_methodv(m_type, m_name, m_method, m_arg_names, m_default_args) \ - METHOD_CLASS(m_type, m_name, m_method); \ + METHOD_CLASS(m_type, m_name, m_name, m_method); \ register_builtin_method(m_arg_names, m_default_args); #else #define bind_methodv(m_type, m_name, m_method, m_arg_names, m_default_args) \ - METHOD_CLASS(m_type, m_name, m_method); \ + METHOD_CLASS(m_type, m_name, m_name, m_method); \ register_builtin_method(sarray(), m_default_args); #endif // DEBUG_ENABLED +#ifdef DEBUG_ENABLED +#define bind_compat_methodv(m_type, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + METHOD_CLASS(m_type, m_exposed_name, m_name, m_method); \ + register_builtin_compat_method(m_arg_names, m_default_args); +#else +#define bind_compat_methodv(m_type, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + METHOD_CLASS(m_type, m_exposed_name, m_name, m_method); \ + register_builtin_compat_method(sarray(), m_default_args); +#endif // DEBUG_ENABLED + #ifdef DEBUG_ENABLED #define bind_convert_methodv(m_type_from, m_type_to, m_name, m_method, m_arg_names, m_default_args) \ - CONVERT_METHOD_CLASS(m_type_from, m_name, m_method); \ + CONVERT_METHOD_CLASS(m_type_from, m_name, m_name, m_method); \ register_builtin_method(m_arg_names, m_default_args); #else #define bind_convert_methodv(m_type_from, m_type_to, m_name, m_method, m_arg_names, m_default_args) \ - CONVERT_METHOD_CLASS(m_type_from, m_name, m_method); \ + CONVERT_METHOD_CLASS(m_type_from, m_name, m_name, m_method); \ register_builtin_method(sarray(), m_default_args); #endif // DEBUG_ENABLED +#ifdef DEBUG_ENABLED +#define bind_convert_compat_methodv(m_type_from, m_type_to, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + CONVERT_METHOD_CLASS(m_type_from, m_exposed_name, m_name, m_method); \ + register_builtin_compat_method(m_arg_names, m_default_args); +#else +#define bind_convert_compat_methodv(m_type_from, m_type_to, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + CONVERT_METHOD_CLASS(m_type_from, m_exposed_name, m_name, m_method); \ + register_builtin_compat_method(sarray(), m_default_args); +#endif // DEBUG_ENABLED + #ifdef DEBUG_ENABLED #define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \ - FUNCTION_CLASS(m_type, m_name, m_method, true); \ + FUNCTION_CLASS(m_type, m_name, m_name, m_method, true); \ register_builtin_method(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, true); \ + FUNCTION_CLASS(m_type, m_name, m_name, m_method, true); \ register_builtin_method(sarray(), m_default_args); #endif // DEBUG_ENABLED +#ifdef DEBUG_ENABLED +#define bind_compat_function(m_type, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_exposed_name, m_name, m_method, true); \ + register_builtin_compat_method(m_arg_names, m_default_args); +#else +#define bind_compat_function(m_type, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_exposed_name, m_name, m_method, true); \ + register_builtin_compat_method(sarray(), m_default_args); +#endif // DEBUG_ENABLED + #ifdef DEBUG_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); \ + FUNCTION_CLASS(m_type, m_name, m_name, m_method, false); \ register_builtin_method(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); \ + FUNCTION_CLASS(m_type, m_name, m_name, m_method, false); \ register_builtin_method(sarray(), m_default_args); #endif // DEBUG_ENABLED +#ifdef DEBUG_ENABLED +#define bind_compat_functionnc(m_type, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_exposed_name, m_name, m_method, false); \ + register_builtin_compat_method(m_arg_names, m_default_args); +#else +#define bind_compat_functionnc(m_type, m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + FUNCTION_CLASS(m_type, m_exposed_name, m_name, m_method, false); \ + register_builtin_compat_method(sarray(), m_default_args); +#endif // DEBUG_ENABLED + #define bind_string_method(m_method, m_arg_names, m_default_args) \ bind_method(String, m_method, m_arg_names, m_default_args); \ bind_convert_method(StringName, String, m_method, m_arg_names, m_default_args); @@ -1811,19 +1962,38 @@ StringName Variant::get_enum_for_enumeration(Variant::Type p_type, const StringN bind_methodv(String, m_name, m_method, m_arg_names, m_default_args); \ bind_convert_methodv(StringName, String, m_name, m_method, m_arg_names, m_default_args); -#define bind_custom(m_type, m_name, m_method, m_has_return, m_ret_type) \ - VARARG_CLASS(m_type, m_name, m_method, m_has_return, m_ret_type) \ +#define bind_string_compat_method(m_exposed_name, m_method, m_arg_names, m_default_args) \ + bind_compat_method(String, m_exposed_name, m_method, m_arg_names, m_default_args); \ + bind_convert_compat_method(StringName, String, m_exposed_name, m_method, m_arg_names, m_default_args); + +#define bind_string_compat_methodv(m_exposed_name, m_name, m_method, m_arg_names, m_default_args) \ + bind_compat_methodv(String, m_exposed_name, m_name, m_method, m_arg_names, m_default_args); \ + bind_convert_compat_methodv(StringName, String, m_exposed_name, m_name, m_method, m_arg_names, m_default_args); + +#define bind_custom(m_type, m_name, m_method, m_has_return, m_ret_type) \ + VARARG_CLASS(m_type, m_name, m_name, m_method, m_has_return, m_ret_type) \ register_builtin_method(sarray(), Vector()); #define bind_custom1(m_type, m_name, m_method, m_arg_type, m_arg_name) \ - VARARG_CLASS1(m_type, m_name, m_method, m_arg_type) \ + VARARG_CLASS1(m_type, m_name, m_name, m_method, m_arg_type) \ register_builtin_method(sarray(m_arg_name), Vector()); +#define bind_compat_custom(m_type, m_exposed_name, m_name, m_method, m_has_return, m_ret_type) \ + VARARG_CLASS(m_type, m_exposed_name, m_name, m_method, m_has_return, m_ret_type) \ + register_builtin_compat_method(sarray(), Vector()); + +#define bind_compat_custom1(m_type, m_exposed_name, m_name, m_method, m_arg_type, m_arg_name) \ + VARARG_CLASS1(m_type, m_exposed_name, m_name, m_method, m_arg_type) \ + register_builtin_compat_method(sarray(m_arg_name), Vector()); + static void _register_variant_builtin_methods_string() { _VariantCall::constant_data = memnew_arr(_VariantCall::ConstantData, Variant::VARIANT_MAX); _VariantCall::enum_data = memnew_arr(_VariantCall::EnumData, Variant::VARIANT_MAX); builtin_method_info = memnew_arr(BuiltinMethodMap, Variant::VARIANT_MAX); builtin_method_names = memnew_arr(List, Variant::VARIANT_MAX); +#ifndef DISABLE_DEPRECATED + builtin_compat_method_info = memnew_arr(BuiltinCompatMethodMap, Variant::VARIANT_MAX); +#endif /* String */ @@ -2583,6 +2753,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedByteArray, sort, sarray(), varray()); bind_method(PackedByteArray, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedByteArray, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedByteArray, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedByteArray, find, sarray("value", "from"), varray(0)); bind_method(PackedByteArray, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedByteArray, count, sarray("value"), varray()); @@ -2659,6 +2832,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedInt32Array, sort, sarray(), varray()); bind_method(PackedInt32Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedInt32Array, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedInt32Array, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedInt32Array, find, sarray("value", "from"), varray(0)); bind_method(PackedInt32Array, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedInt32Array, count, sarray("value"), varray()); @@ -2683,6 +2859,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedInt64Array, sort, sarray(), varray()); bind_method(PackedInt64Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedInt64Array, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedInt64Array, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedInt64Array, find, sarray("value", "from"), varray(0)); bind_method(PackedInt64Array, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedInt64Array, count, sarray("value"), varray()); @@ -2707,6 +2886,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedFloat32Array, sort, sarray(), varray()); bind_method(PackedFloat32Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedFloat32Array, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedFloat32Array, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedFloat32Array, find, sarray("value", "from"), varray(0)); bind_method(PackedFloat32Array, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedFloat32Array, count, sarray("value"), varray()); @@ -2731,6 +2913,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedFloat64Array, sort, sarray(), varray()); bind_method(PackedFloat64Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedFloat64Array, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedFloat64Array, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedFloat64Array, find, sarray("value", "from"), varray(0)); bind_method(PackedFloat64Array, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedFloat64Array, count, sarray("value"), varray()); @@ -2755,6 +2940,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedStringArray, sort, sarray(), varray()); bind_method(PackedStringArray, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedStringArray, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedStringArray, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedStringArray, find, sarray("value", "from"), varray(0)); bind_method(PackedStringArray, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedStringArray, count, sarray("value"), varray()); @@ -2779,6 +2967,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedVector2Array, sort, sarray(), varray()); bind_method(PackedVector2Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedVector2Array, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedVector2Array, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedVector2Array, find, sarray("value", "from"), varray(0)); bind_method(PackedVector2Array, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedVector2Array, count, sarray("value"), varray()); @@ -2803,6 +2994,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedVector3Array, sort, sarray(), varray()); bind_method(PackedVector3Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedVector3Array, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedVector3Array, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedVector3Array, find, sarray("value", "from"), varray(0)); bind_method(PackedVector3Array, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedVector3Array, count, sarray("value"), varray()); @@ -2827,6 +3021,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedColorArray, sort, sarray(), varray()); bind_method(PackedColorArray, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedColorArray, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedColorArray, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedColorArray, find, sarray("value", "from"), varray(0)); bind_method(PackedColorArray, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedColorArray, count, sarray("value"), varray()); @@ -2851,6 +3048,9 @@ static void _register_variant_builtin_methods_array() { bind_method(PackedVector4Array, sort, sarray(), varray()); bind_method(PackedVector4Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedVector4Array, duplicate, sarray(), varray()); +#ifndef DISABLE_DEPRECATED + bind_compat_method(PackedVector4Array, duplicate, _duplicate_bind_compat_112290, sarray(), varray()); +#endif bind_method(PackedVector4Array, find, sarray("value", "from"), varray(0)); bind_method(PackedVector4Array, rfind, sarray("value", "from"), varray(-1)); bind_method(PackedVector4Array, count, sarray("value"), varray()); @@ -2988,6 +3188,9 @@ void Variant::_unregister_variant_methods() { //clear methods memdelete_arr(builtin_method_names); memdelete_arr(builtin_method_info); +#ifndef DISABLE_DEPRECATED + memdelete_arr(builtin_compat_method_info); +#endif memdelete_arr(_VariantCall::constant_data); memdelete_arr(_VariantCall::enum_data); } diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index a614d6e357f8..7d054608d009 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -213,7 +213,7 @@ [b]Note:[/b] Decompression is not guaranteed to work with data not compressed by Godot, for example if data compressed with the deflate compression mode lacks a checksum or header. - + Creates a copy of the array, and returns it. diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml index 97a70f12fd5c..2dabfb5dee66 100644 --- a/doc/classes/PackedColorArray.xml +++ b/doc/classes/PackedColorArray.xml @@ -73,7 +73,7 @@ Returns the number of times an element is in the array. - + Creates a copy of the array, and returns it. diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index 1997ecf5f880..625172d56441 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -71,7 +71,7 @@ [b]Note:[/b] [constant @GDScript.NAN] doesn't behave the same as other numbers. Therefore, the results from this method may not be accurate if NaNs are included. - + Creates a copy of the array, and returns it. diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index b325df473427..55c576664a4e 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -72,7 +72,7 @@ [b]Note:[/b] [constant @GDScript.NAN] doesn't behave the same as other numbers. Therefore, the results from this method may not be accurate if NaNs are included. - + Creates a copy of the array, and returns it. diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index e230bd08bf2d..86c3a5b9ef8b 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -69,7 +69,7 @@ Returns the number of times an element is in the array. - + Creates a copy of the array, and returns it. diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index 094dbf5419a6..73e6c0e8794b 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -70,7 +70,7 @@ Returns the number of times an element is in the array. - + Creates a copy of the array, and returns it. diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml index 1bd79b33e40f..4f84ba824351 100644 --- a/doc/classes/PackedStringArray.xml +++ b/doc/classes/PackedStringArray.xml @@ -76,7 +76,7 @@ Returns the number of times an element is in the array. - + Creates a copy of the array, and returns it. diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml index 133011ee41cb..1fa4a989169a 100644 --- a/doc/classes/PackedVector2Array.xml +++ b/doc/classes/PackedVector2Array.xml @@ -76,7 +76,7 @@ [b]Note:[/b] Vectors with [constant @GDScript.NAN] elements don't behave the same as other vectors. Therefore, the results from this method may not be accurate if NaNs are included. - + Creates a copy of the array, and returns it. diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index 87161e813f1d..0a85d1ac6826 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -75,7 +75,7 @@ [b]Note:[/b] Vectors with [constant @GDScript.NAN] elements don't behave the same as other vectors. Therefore, the results from this method may not be accurate if NaNs are included. - + Creates a copy of the array, and returns it. diff --git a/doc/classes/PackedVector4Array.xml b/doc/classes/PackedVector4Array.xml index 30203ffe1ae1..4bc43fe6ba5f 100644 --- a/doc/classes/PackedVector4Array.xml +++ b/doc/classes/PackedVector4Array.xml @@ -75,7 +75,7 @@ [b]Note:[/b] Vectors with [constant @GDScript.NAN] elements don't behave the same as other vectors. Therefore, the results from this method may not be accurate if NaNs are included. - + Creates a copy of the array, and returns it. diff --git a/misc/extension_api_validation/4.5-stable.expected b/misc/extension_api_validation/4.5-stable.expected index 4fef411d0574..e24b0cd383ff 100644 --- a/misc/extension_api_validation/4.5-stable.expected +++ b/misc/extension_api_validation/4.5-stable.expected @@ -68,3 +68,20 @@ GH-110433 Validate extension JSON: Error: Field 'classes/Performance/methods/add_custom_monitor/arguments': size changed value in new API, from 3 to 4. Optional argument added. Compatibility method registered. + + +GH-112290 +--------- + +Validate extension JSON: Error: Field 'builtin_classes/PackedByteArray/methods/duplicate': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'builtin_classes/PackedColorArray/methods/duplicate': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'builtin_classes/PackedFloat32Array/methods/duplicate': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'builtin_classes/PackedFloat64Array/methods/duplicate': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'builtin_classes/PackedInt32Array/methods/duplicate': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'builtin_classes/PackedInt64Array/methods/duplicate': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'builtin_classes/PackedStringArray/methods/duplicate': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'builtin_classes/PackedVector2Array/methods/duplicate': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'builtin_classes/PackedVector3Array/methods/duplicate': is_const changed value in new API, from false to true. +Validate extension JSON: Error: Field 'builtin_classes/PackedVector4Array/methods/duplicate': is_const changed value in new API, from false to true. + +Duplicate method made const. Compatibility methods registered.