Skip to content

Commit 72cf9bb

Browse files
Implement vararg methods of builtin classes.
1 parent feaba55 commit 72cf9bb

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

binding_generator.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
121121
include_gen_folder / "variant" / "builtin_binds.hpp",
122122
include_gen_folder / "variant" / "utility_functions.hpp",
123123
include_gen_folder / "variant" / "variant_size.hpp",
124+
include_gen_folder / "variant" / "builtin_vararg_methods.hpp",
124125
include_gen_folder / "classes" / "global_constants.hpp",
125126
include_gen_folder / "classes" / "global_constants_binds.hpp",
126127
]:
@@ -342,6 +343,101 @@ def generate_builtin_bindings(api, output_dir, build_config):
342343

343344
builtin_binds_file.write("\n".join(builtin_binds))
344345

346+
# Craete a header to implement all builin class vararg methods and be included in `variant.hpp``.
347+
builtin_vararg_methods_header = include_gen_folder / "builtin_vararg_methods.hpp"
348+
builtin_vararg_methods_header.open("w+").write(
349+
generate_builtin_class_vararg_method_implements_header(api["builtin_classes"])
350+
)
351+
352+
353+
def generate_builtin_class_vararg_method_implements_header(builtin_classes):
354+
result = []
355+
356+
add_header("builtin_vararg_methods.hpp", result)
357+
358+
header_guard = "GODOT_CPP_BUILTIN_VARARG_METHODS_HPP"
359+
result.append(f"#ifndef {header_guard}")
360+
result.append(f"#define {header_guard}")
361+
for builtin_api in builtin_classes:
362+
if not "methods" in builtin_api:
363+
continue
364+
class_name = builtin_api["name"]
365+
for method in builtin_api["methods"]:
366+
if not method["is_vararg"]:
367+
continue
368+
369+
need_return = "return_type" in method
370+
371+
result.append("template<class... Args>")
372+
method_signature = ""
373+
if need_return:
374+
method_signature += f'{correct_type(method["return_type"])} '
375+
else:
376+
method_signature += "void "
377+
378+
method_name = method["name"]
379+
method_signature += f"{class_name}::{method_name}("
380+
381+
method_arguments = []
382+
if "arguments" in method:
383+
method_arguments = method["arguments"]
384+
385+
method_signature += make_function_parameters(
386+
method_arguments, include_default=False, for_builtin=True, is_vararg=True
387+
)
388+
389+
method_signature += ")"
390+
if method["is_const"]:
391+
method_signature += " const"
392+
393+
method_signature += "{"
394+
result.append(method_signature)
395+
396+
arguments = []
397+
if "arguments" in method:
398+
for argument in method["arguments"]:
399+
arguments.append(escape_identifier(argument["name"]))
400+
401+
need_return = "return_type" in method
402+
403+
variant_args = f"\tstd::array<Variant, {len(arguments)} + sizeof...(Args)> variant_args = " + "{ { "
404+
if len(arguments) > 0:
405+
for i in range(len(arguments)):
406+
if i > 0:
407+
variant_args += ", "
408+
variant_args += f"Variant({arguments[i]})"
409+
variant_args += ", "
410+
variant_args += "(Variant(args))... } };"
411+
result.append(variant_args)
412+
result.append(f"\tstd::array<const Variant *, {len(arguments)} + sizeof...(Args)> call_args;")
413+
result.append(f"\tfor (size_t i = 0; i < ({len(arguments)} + sizeof...(Args)); ++i) " + "{")
414+
result.append("\t\tcall_args[i] = &variant_args[i];")
415+
result.append("\t}")
416+
417+
base = "(GDExtensionTypePtr)&opaque"
418+
if "is_static" in method and method["is_static"]:
419+
base = "nullptr"
420+
421+
ret = "nullptr"
422+
if need_return:
423+
ret = "&ret"
424+
result.append(f'\t{correct_type(method["return_type"])} ret;')
425+
426+
result.append(
427+
f"\t_method_bindings.method_{method_name}({base}, reinterpret_cast<GDExtensionConstTypePtr *>(call_args.data()), {ret}, {len(arguments)} + sizeof...(Args));"
428+
)
429+
430+
if need_return:
431+
result.append("\treturn ret;")
432+
433+
result.append("}")
434+
result.append("")
435+
436+
result.append("")
437+
result.append(f"#endif // ! {header_guard}")
438+
439+
return "\n".join(result)
440+
345441

346442
def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes):
347443
result = []

include/godot_cpp/variant/variant.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,8 @@ String vformat(const String &p_text, const VarArgs... p_args) {
334334
return p_text % args_array;
335335
}
336336

337+
#include <godot_cpp/variant/builtin_vararg_methods.hpp>
338+
337339
} // namespace godot
338340

339341
#endif // GODOT_VARIANT_HPP

0 commit comments

Comments
 (0)