summaryrefslogtreecommitdiffstats
path: root/binding_generator.py
diff options
context:
space:
mode:
Diffstat (limited to 'binding_generator.py')
-rw-r--r--binding_generator.py137
1 files changed, 124 insertions, 13 deletions
diff --git a/binding_generator.py b/binding_generator.py
index 44c8fe7..e680784 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -122,8 +122,10 @@ 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",
]:
files.append(str(path.as_posix()))
if sources:
@@ -174,6 +176,7 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
print("Built-in type config: " + real_t + "_" + bits)
generate_global_constants(api, target_dir)
+ generate_version_header(api, target_dir)
generate_global_constant_binds(api, target_dir)
generate_builtin_bindings(api, target_dir, real_t + "_" + bits)
generate_engine_classes_bindings(api, target_dir, use_template_get_node)
@@ -345,6 +348,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 = []
@@ -367,6 +404,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
if class_name == "String":
result.append("#include <godot_cpp/variant/char_string.hpp>")
result.append("#include <godot_cpp/variant/char_utils.hpp>")
+ result.append("#include <godot_cpp/classes/global_constants.hpp>")
if class_name == "PackedStringArray":
result.append("#include <godot_cpp/variant/string.hpp>")
@@ -553,6 +591,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("\tChar32String utf32() const;")
result.append("\tCharWideString wide_string() const;")
result.append("\tstatic String num_real(double p_num, bool p_trailing = true);")
+ result.append("\tError resize(int p_size);")
if "members" in builtin_api:
for member in builtin_api["members"]:
@@ -1143,6 +1182,12 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
else:
fully_used_classes.add("Wrapped")
+ # In order to ensure that PtrToArg specializations for native structs are
+ # always used, let's move any of them into 'fully_used_classes'.
+ for type_name in used_classes:
+ if is_struct_type(type_name) and not is_included_struct_type(type_name):
+ fully_used_classes.add(type_name)
+
for type_name in fully_used_classes:
if type_name in used_classes:
used_classes.remove(type_name)
@@ -1717,6 +1762,35 @@ def generate_global_constants(api, output_dir):
header_file.write("\n".join(header))
+def generate_version_header(api, output_dir):
+ header = []
+ header_filename = "version.hpp"
+ add_header(header_filename, header)
+
+ include_gen_folder = Path(output_dir) / "include" / "godot_cpp" / "core"
+ include_gen_folder.mkdir(parents=True, exist_ok=True)
+
+ header_file_path = include_gen_folder / header_filename
+
+ header_guard = "GODOT_CPP_VERSION_HPP"
+ header.append(f"#ifndef {header_guard}")
+ header.append(f"#define {header_guard}")
+ header.append("")
+
+ header.append(f"#define GODOT_VERSION_MAJOR {api['header']['version_major']}")
+ header.append(f"#define GODOT_VERSION_MINOR {api['header']['version_minor']}")
+ header.append(f"#define GODOT_VERSION_PATCH {api['header']['version_patch']}")
+ header.append(f"#define GODOT_VERSION_STATUS \"{api['header']['version_status']}\"")
+ header.append(f"#define GODOT_VERSION_BUILD \"{api['header']['version_build']}\"")
+
+ header.append("")
+ header.append(f"#endif // {header_guard}")
+ header.append("")
+
+ with header_file_path.open("w+", encoding="utf-8") as header_file:
+ header_file.write("\n".join(header))
+
+
def generate_global_constant_binds(api, output_dir):
include_gen_folder = Path(output_dir) / "include" / "godot_cpp" / "classes"
source_gen_folder = Path(output_dir) / "src" / "classes"
@@ -2023,10 +2097,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 "
@@ -2047,6 +2133,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 = []
@@ -2067,7 +2155,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"]
@@ -2077,19 +2165,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