summaryrefslogtreecommitdiffstats
path: root/binding_generator.py
diff options
context:
space:
mode:
Diffstat (limited to 'binding_generator.py')
-rw-r--r--binding_generator.py100
1 files changed, 80 insertions, 20 deletions
diff --git a/binding_generator.py b/binding_generator.py
index 9efd2b7..da437d7 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -653,9 +653,17 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
# First create map of classes.
for class_api in api["classes"]:
+ # TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
+ if class_api["name"] == "ClassDB":
+ continue
engine_classes[class_api["name"]] = class_api["is_refcounted"]
+ for native_struct in api["native_structures"]:
+ engine_classes[native_struct["name"]] = False
for class_api in api["classes"]:
+ # TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
+ if class_api["name"] == "ClassDB":
+ continue
# Check used classes for header include.
used_classes = set()
fully_used_classes = set()
@@ -669,24 +677,31 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
for method in class_api["methods"]:
if "arguments" in method:
for argument in method["arguments"]:
- if is_included(argument["type"], class_name):
- if is_enum(argument["type"]):
- fully_used_classes.add(get_enum_class(argument["type"]))
+ type_name = argument["type"]
+ if type_name.endswith("*"):
+ type_name = type_name[:-1]
+ if is_included(type_name, class_name):
+ if is_enum(type_name):
+ fully_used_classes.add(get_enum_class(type_name))
elif "default_value" in argument:
- fully_used_classes.add(argument["type"])
+ fully_used_classes.add(type_name)
else:
- used_classes.add(argument["type"])
- if is_refcounted(argument["type"]):
+ used_classes.add(type_name)
+ if is_refcounted(type_name):
fully_used_classes.add("Ref")
if "return_value" in method:
- if is_included(method["return_value"]["type"], class_name):
- if is_enum(method["return_value"]["type"]):
- fully_used_classes.add(get_enum_class(method["return_value"]["type"]))
- elif is_variant(method["return_value"]["type"]):
- fully_used_classes.add(method["return_value"]["type"])
+ type_name = method["return_value"]["type"]
+ if type_name.endswith("*"):
+ type_name = type_name[:-1]
+ print("New type name ", type_name)
+ if is_included(type_name, class_name):
+ if is_enum(type_name):
+ fully_used_classes.add(get_enum_class(type_name))
+ elif is_variant(type_name):
+ fully_used_classes.add(type_name)
else:
- used_classes.add(method["return_value"]["type"])
- if is_refcounted(method["return_value"]["type"]):
+ used_classes.add(type_name)
+ if is_refcounted(type_name):
fully_used_classes.add("Ref")
if "members" in class_api:
@@ -721,6 +736,36 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
generate_engine_class_source(class_api, used_classes, fully_used_classes, use_template_get_node)
)
+ for native_struct in api["native_structures"]:
+ struct_name = native_struct["name"]
+ snake_struct_name = camel_to_snake(struct_name)
+
+ header_filename = include_gen_folder / (snake_struct_name + ".hpp")
+
+ result = []
+ add_header(f"{snake_struct_name}.hpp", result)
+
+ header_guard = f"GODOT_CPP_{snake_struct_name.upper()}_HPP"
+ result.append(f"#ifndef {header_guard}")
+ result.append(f"#define {header_guard}")
+
+ result.append("")
+ result.append("namespace godot {")
+ result.append("")
+
+ result.append(f"struct {struct_name} {{")
+ for field in native_struct["format"].split(","):
+ result.append(f"\t{field};")
+ result.append("};")
+
+ result.append("")
+ result.append("} // namespace godot")
+ result.append("")
+ result.append(f"#endif // ! {header_guard}")
+
+ with header_filename.open("w+") as header_file:
+ header_file.write("\n".join(result))
+
def generate_engine_class_header(class_api, used_classes, fully_used_classes, use_template_get_node):
result = []
@@ -800,7 +845,9 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
continue
method_signature = "\t"
- method_signature += make_signature(class_name, method, for_header=True, use_template_get_node=use_template_get_node)
+ method_signature += make_signature(
+ class_name, method, for_header=True, use_template_get_node=use_template_get_node
+ )
result.append(method_signature + ";")
result.append("protected:")
@@ -813,7 +860,9 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
if not method["is_virtual"]:
continue
method_name = escape_identifier(method["name"])
- result.append(f"\t\tif constexpr (!std::is_same_v<decltype(&{class_name}::{method_name}),decltype(&T::{method_name})>) {{")
+ result.append(
+ f"\t\tif constexpr (!std::is_same_v<decltype(&{class_name}::{method_name}),decltype(&T::{method_name})>) {{"
+ )
result.append(f"\t\t\tBIND_VIRTUAL_METHOD(T, {method_name});")
result.append("\t\t}")
@@ -828,7 +877,9 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
result.append("\tstatic T *cast_to(Object *p_object);")
elif use_template_get_node and class_name == "Node":
result.append("\ttemplate<class T>")
- result.append("\tT *get_node(const NodePath &p_path) const { return Object::cast_to<T>(get_node_internal(p_path)); }")
+ result.append(
+ "\tT *get_node(const NodePath &p_path) const { return Object::cast_to<T>(get_node_internal(p_path)); }"
+ )
# Constructor.
result.append("")
@@ -1164,7 +1215,7 @@ def make_function_parameters(parameters, include_default=False, for_builtin=Fals
parameter_type = correct_type(par["type"])
if parameter_type == "void":
parameter_type = "Variant"
- parameter += f'({parameter_type})'
+ parameter += f"({parameter_type})"
parameter += correct_default_value(par["default_value"], par["type"])
signature.append(parameter)
@@ -1214,7 +1265,9 @@ def get_encoded_arg(arg_name, type_name, type_meta):
return (result, name)
-def make_signature(class_name, function_data, for_header=False, use_template_get_node=True, for_builtin=False, static=False):
+def make_signature(
+ class_name, function_data, for_header=False, use_template_get_node=True, for_builtin=False, static=False
+):
function_signature = ""
is_vararg = "is_vararg" in function_data and function_data["is_vararg"]
@@ -1379,7 +1432,8 @@ def is_variant(type_name):
def is_engine_class(type_name):
- return type_name in engine_classes
+ global engine_classes
+ return type_name == "Object" or type_name in engine_classes
def is_refcounted(type_name):
@@ -1392,7 +1446,11 @@ def is_included(type_name, current_type):
This removes Variant and POD types from inclusion, and the current type.
"""
to_include = get_enum_class(type_name) if is_enum(type_name) else type_name
- return to_include != current_type and not is_pod_type(to_include)
+ if to_include == current_type or is_pod_type(to_include):
+ return False
+ if to_include == "GlobalConstants" or to_include == "UtilityFunctions":
+ return True
+ return is_engine_class(to_include) or is_variant(to_include)
def correct_default_value(value, type_name):
@@ -1430,6 +1488,8 @@ def correct_type(type_name, meta=None):
return f"Ref<{type_name}>"
if type_name == "Object" or is_engine_class(type_name):
return f"{type_name} *"
+ if type_name.endswith("*"):
+ return f"{type_name[:-1]} *"
return type_name