diff --git a/binding_generator.py b/binding_generator.py index 7a6fe248..596478c9 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -964,8 +964,19 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl result.append(method_signature + "{") method_call = "\t" + is_ref = False + if "return_type" in method: - method_call += f'return internal::_call_builtin_method_ptr_ret<{correct_type(method["return_type"])}>(' + return_type = method["return_type"] + if is_enum(return_type): + method_call += f"return ({get_gdextension_type(correct_type(return_type))})internal::_call_builtin_method_ptr_ret(" + elif is_pod_type(return_type) or is_variant(return_type): + method_call += f"return internal::_call_builtin_method_ptr_ret<{get_gdextension_type(correct_type(return_type))}>(" + elif is_refcounted(return_type): + method_call += f"return Ref<{return_type}>::_gde_internal_constructor(internal::_call_builtin_method_ptr_ret_obj<{return_type}>(" + is_ref = True + else: + method_call += f"return internal::_call_builtin_method_ptr_ret_obj<{return_type}>(" else: method_call += "internal::_call_builtin_method_ptr_no_ret(" method_call += f'_method_bindings.method_{method["name"]}, ' @@ -986,6 +997,9 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl result += encode arguments.append(arg_name) method_call += ", ".join(arguments) + + if is_ref: + method_call += ")" # Close Ref<> constructor. method_call += ");" result.append(method_call) diff --git a/include/godot_cpp/core/builtin_ptrcall.hpp b/include/godot_cpp/core/builtin_ptrcall.hpp index 87311b8a..19250d84 100644 --- a/include/godot_cpp/core/builtin_ptrcall.hpp +++ b/include/godot_cpp/core/builtin_ptrcall.hpp @@ -32,6 +32,7 @@ #define GODOT_BUILTIN_PTRCALL_HPP #include +#include #include @@ -39,6 +40,17 @@ namespace godot { namespace internal { +template +O *_call_builtin_method_ptr_ret_obj(const GDExtensionPtrBuiltInMethod method, GDExtensionTypePtr base, const Args &...args) { + GodotObject *ret = nullptr; + std::array call_args = { { (GDExtensionConstTypePtr)args... } }; + method(base, call_args.data(), &ret, sizeof...(Args)); + if (ret == nullptr) { + return nullptr; + } + return reinterpret_cast(internal::get_object_instance_binding(ret)); +} + template void _call_builtin_constructor(const GDExtensionPtrConstructor constructor, GDExtensionTypePtr base, Args... args) { std::array call_args = { { (GDExtensionConstTypePtr)args... } };