diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 0eaa1b850ab..62b605f7d30 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 ecd5dff14c4..1ca98ba0556 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/variant/variant.h b/core/variant/variant.h index 44cd11c7be7..e6635efd2e8 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -645,6 +645,7 @@ public: 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 @@ public: 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 33f44c13fed..d2bf2aa04fe 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 */ @@ -2988,6 +3158,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); }