diff options
author | David Snopek <dsnopek@gmail.com> | 2023-09-02 08:04:29 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-02 08:04:29 -0500 |
commit | 8990d5a40ee93eb84d7eda590793b0901f1f7584 (patch) | |
tree | 742a88d0c11e6c93569021e61d82226906afe222 | |
parent | 9ada7065d64bff3d1b87f4e0de1a52d88959731e (diff) | |
parent | 3536803e9e92ff1877e4e2e0ae113b17fe415e5f (diff) | |
download | redot-cpp-8990d5a40ee93eb84d7eda590793b0901f1f7584.tar.gz |
Merge pull request #1091 from Daylily-Zeleen/daylily-zeleen/implement_builtin_classes_vararg_methods
Implement vararg methods of builtin classes.
-rw-r--r-- | binding_generator.py | 98 | ||||
-rw-r--r-- | include/godot_cpp/variant/variant.hpp | 2 |
2 files changed, 87 insertions, 13 deletions
diff --git a/binding_generator.py b/binding_generator.py index 62238d7..2a64725 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -121,6 +121,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False): include_gen_folder / "variant" / "builtin_binds.hpp", include_gen_folder / "variant" / "utility_functions.hpp", include_gen_folder / "variant" / "variant_size.hpp", + include_gen_folder / "variant" / "builtin_vararg_methods.hpp", include_gen_folder / "classes" / "global_constants.hpp", include_gen_folder / "classes" / "global_constants_binds.hpp", include_gen_folder / "core" / "version.hpp", @@ -346,6 +347,40 @@ def generate_builtin_bindings(api, output_dir, build_config): builtin_binds_file.write("\n".join(builtin_binds)) + # Create a header to implement all builtin class vararg methods and be included in "variant.hpp". + builtin_vararg_methods_header = include_gen_folder / "builtin_vararg_methods.hpp" + builtin_vararg_methods_header.open("w+").write( + generate_builtin_class_vararg_method_implements_header(api["builtin_classes"]) + ) + + +def generate_builtin_class_vararg_method_implements_header(builtin_classes): + result = [] + + add_header("builtin_vararg_methods.hpp", result) + + header_guard = "GODOT_CPP_BUILTIN_VARARG_METHODS_HPP" + result.append(f"#ifndef {header_guard}") + result.append(f"#define {header_guard}") + result.append("") + for builtin_api in builtin_classes: + if not "methods" in builtin_api: + continue + class_name = builtin_api["name"] + for method in builtin_api["methods"]: + if not method["is_vararg"]: + continue + + result += make_varargs_template( + method, "is_static" in method and method["is_static"], class_name, False, False, True + ) + result.append("") + + result.append("") + result.append(f"#endif // ! {header_guard}") + + return "\n".join(result) + def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes): result = [] @@ -2005,10 +2040,22 @@ def make_signature( return function_signature -def make_varargs_template(function_data, static=False): +def make_varargs_template( + function_data, + static=False, + class_befor_signature="", + with_public_declare=True, + with_indent=True, + for_builtin_classes=False, +): result = [] - function_signature = "\tpublic: template<class... Args> " + function_signature = "" + + if with_public_declare: + function_signature = "public: " + + function_signature += "template<class... Args> " if static: function_signature += "static " @@ -2029,6 +2076,8 @@ def make_varargs_template(function_data, static=False): if not function_signature.endswith("*"): function_signature += " " + if len(class_befor_signature) > 0: + function_signature += class_befor_signature + "::" function_signature += f'{escape_identifier(function_data["name"])}' method_arguments = [] @@ -2049,7 +2098,7 @@ def make_varargs_template(function_data, static=False): function_signature += " {" result.append(function_signature) - args_array = f"\t\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ " + args_array = f"\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ " for argument in method_arguments: if argument["type"] == "Variant": args_array += argument["name"] @@ -2059,19 +2108,42 @@ def make_varargs_template(function_data, static=False): args_array += "Variant(args)... };" result.append(args_array) - result.append(f"\t\tstd::array<const Variant *, {len(method_arguments)} + sizeof...(Args)> call_args;") - result.append("\t\tfor(size_t i = 0; i < variant_args.size(); i++) {") - result.append("\t\t\tcall_args[i] = &variant_args[i];") - result.append("\t\t}") + result.append(f"\tstd::array<const Variant *, {len(method_arguments)} + sizeof...(Args)> call_args;") + result.append("\tfor(size_t i = 0; i < variant_args.size(); i++) {") + result.append("\t\tcall_args[i] = &variant_args[i];") + result.append("\t}") - call_line = "\t\t" + call_line = "\t" - if return_type != "void": - call_line += "return " + if not for_builtin_classes: + if return_type != "void": + call_line += "return " - call_line += f'{escape_identifier(function_data["name"])}_internal(call_args.data(), variant_args.size());' - result.append(call_line) - result.append("\t}") + call_line += f'{escape_identifier(function_data["name"])}_internal(call_args.data(), variant_args.size());' + result.append(call_line) + else: + base = "(GDExtensionTypePtr)&opaque" + if static: + base = "nullptr" + + ret = "nullptr" + if return_type != "void": + ret = "&ret" + result.append(f'\t{correct_type(function_data["return_type"])} ret;') + + function_name = function_data["name"] + result.append( + f"\t_method_bindings.method_{function_name}({base}, reinterpret_cast<GDExtensionConstTypePtr *>(call_args.data()), {ret}, {len(method_arguments)} + sizeof...(Args));" + ) + + if return_type != "void": + result.append("\treturn ret;") + + result.append("}") + + if with_indent: + for i in range(len(result)): + result[i] = "\t" + result[i] return result diff --git a/include/godot_cpp/variant/variant.hpp b/include/godot_cpp/variant/variant.hpp index 06ba75f..3b5ca56 100644 --- a/include/godot_cpp/variant/variant.hpp +++ b/include/godot_cpp/variant/variant.hpp @@ -334,6 +334,8 @@ String vformat(const String &p_text, const VarArgs... p_args) { return p_text % args_array; } +#include <godot_cpp/variant/builtin_vararg_methods.hpp> + } // namespace godot #endif // GODOT_VARIANT_HPP |