Compare commits

...

4 Commits

Author SHA1 Message Date
Thaddeus Crews 5d2ca780a3
Merge dfdc7bf971 into 36847f6af0 2024-01-24 16:15:04 +01:00
David Snopek 36847f6af0
Merge pull request #1370 from MJacred/patch-1
Update README: fix godot-cpp issue tracker url
2024-01-22 08:57:08 -06:00
MJacred 8a535d0ecc
Update README: fix godot-cpp issue tracker url 2024-01-22 10:50:27 +01:00
Thaddeus Crews dfdc7bf971
Add type hints to `binding_generator.py` 2024-01-18 15:23:06 -06:00
2 changed files with 135 additions and 112 deletions

View File

@ -58,7 +58,7 @@ first-party `godot-cpp` extension.
Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
get more used, documented, and critical issues get resolved. See the
[Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
and the [godot-cpp issue tracker](https://github.com/godotengine/godot/issues)
and the [godot-cpp issue tracker](https://github.com/godotengine/godot-cpp/issues)
for a list of known issues, and be sure to provide feedback on issues and PRs
which affect your use of this extension.

View File

@ -4,9 +4,10 @@ import json
import re
import shutil
from pathlib import Path
from typing import Tuple, Set, Dict, List, Any
def generate_mod_version(argcount, const=False, returns=False):
def generate_mod_version(argcount: int, const: bool = False, returns: bool = False) -> str:
s = """
#define MODBIND$VER($RETTYPE m_name$ARG) \\
virtual $RETVAL _##m_name($FUNCARGS) $CONST override; \\
@ -48,7 +49,7 @@ virtual $RETVAL _##m_name($FUNCARGS) $CONST override; \\
return s
def generate_wrappers(target):
def generate_wrappers(target: Path) -> None:
max_versions = 12
txt = """
@ -70,7 +71,7 @@ def generate_wrappers(target):
f.write(txt)
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
def get_file_list(api_filepath: str, output_dir: str, headers: bool = False, sources: bool = False) -> List[str]:
api = {}
files = []
with open(api_filepath, encoding="utf-8") as api_file:
@ -137,18 +138,18 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
return files
def print_file_list(api_filepath, output_dir, headers=False, sources=False):
def print_file_list(api_filepath: str, output_dir: str, headers: bool = False, sources: bool = False) -> None:
print(*get_file_list(api_filepath, output_dir, headers, sources), sep=";", end=None)
def scons_emit_files(target, source, env):
def scons_emit_files(target: Any, source: Any, env: Any) -> Tuple[List[Any], Any]:
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)]
env.Clean(target, files)
env["godot_cpp_gen_dir"] = target[0].abspath
return files, source
def scons_generate_bindings(target, source, env):
def scons_generate_bindings(target: Any, source: Any, env: Any) -> None:
generate_bindings(
str(source[0]),
env["generate_template_get_node"],
@ -159,9 +160,9 @@ def scons_generate_bindings(target, source, env):
return None
def generate_bindings(api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."):
api = None
def generate_bindings(
api_filepath: str, use_template_get_node: bool, bits: str = "64", precision: str = "single", output_dir: str = "."
) -> None:
target_dir = Path(output_dir) / "gen"
with open(api_filepath, encoding="utf-8") as api_file:
@ -192,7 +193,7 @@ native_structures = []
singletons = []
def generate_builtin_bindings(api, output_dir, build_config):
def generate_builtin_bindings(api: Dict[str, Any], output_dir: Path, build_config: str) -> None:
global builtin_classes
core_gen_folder = Path(output_dir) / "include" / "godot_cpp" / "core"
@ -222,7 +223,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
# Create a file for Variant size, since that class isn't generated.
variant_size_filename = include_gen_folder / "variant_size.hpp"
with variant_size_filename.open("+w", encoding="utf-8") as variant_size_file:
variant_size_source = []
variant_size_source: List[str] = []
add_header("variant_size.hpp", variant_size_source)
header_guard = "GODOT_CPP_VARIANT_SIZE_HPP"
@ -245,8 +246,8 @@ def generate_builtin_bindings(api, output_dir, build_config):
source_filename = source_gen_folder / (camel_to_snake(builtin_api["name"]) + ".cpp")
# Check used classes for header include
used_classes = set()
fully_used_classes = set()
used_classes: Set[str] = set()
fully_used_classes: Set[str] = set()
class_name = builtin_api["name"]
@ -292,21 +293,25 @@ def generate_builtin_bindings(api, output_dir, build_config):
if type_name in used_classes:
used_classes.remove(type_name)
used_classes = list(used_classes)
used_classes.sort()
fully_used_classes = list(fully_used_classes)
fully_used_classes.sort()
used_classes_list: List[str] = list(used_classes)
used_classes_list.sort()
fully_used_classes_list: List[str] = list(fully_used_classes)
fully_used_classes_list.sort()
with header_filename.open("w+", encoding="utf-8") as header_file:
header_file.write(generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes))
header_file.write(
generate_builtin_class_header(builtin_api, size, used_classes_list, fully_used_classes_list)
)
with source_filename.open("w+", encoding="utf-8") as source_file:
source_file.write(generate_builtin_class_source(builtin_api, size, used_classes, fully_used_classes))
source_file.write(
generate_builtin_class_source(builtin_api, size, used_classes_list, fully_used_classes_list)
)
# Create a header with all builtin types for convenience.
builtin_header_filename = include_gen_folder / "builtin_types.hpp"
with builtin_header_filename.open("w+", encoding="utf-8") as builtin_header_file:
builtin_header = []
builtin_header: List[str] = []
add_header("builtin_types.hpp", builtin_header)
builtin_header.append("#ifndef GODOT_CPP_BUILTIN_TYPES_HPP")
@ -326,7 +331,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
# Create a header with bindings for builtin types.
builtin_binds_filename = include_gen_folder / "builtin_binds.hpp"
with builtin_binds_filename.open("w+", encoding="utf-8") as builtin_binds_file:
builtin_binds = []
builtin_binds: List[str] = []
add_header("builtin_binds.hpp", builtin_binds)
builtin_binds.append("#ifndef GODOT_CPP_BUILTIN_BINDS_HPP")
@ -353,8 +358,8 @@ def generate_builtin_bindings(api, output_dir, build_config):
)
def generate_builtin_class_vararg_method_implements_header(builtin_classes):
result = []
def generate_builtin_class_vararg_method_implements_header(builtin_classes: List[Dict[str, Any]]) -> str:
result: List[str] = []
add_header("builtin_vararg_methods.hpp", result)
@ -381,8 +386,10 @@ def generate_builtin_class_vararg_method_implements_header(builtin_classes):
return "\n".join(result)
def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes):
result = []
def generate_builtin_class_header(
builtin_api: Dict[str, Any], size: int, used_classes: List[str], fully_used_classes: List[str]
) -> str:
result: List[str] = []
class_name = builtin_api["name"]
snake_class_name = camel_to_snake(class_name).upper()
@ -782,8 +789,10 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
return "\n".join(result)
def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_classes):
result = []
def generate_builtin_class_source(
builtin_api: Dict[str, Any], size: int, used_classes: List[str], fully_used_classes: List[str]
) -> str:
result: List[str] = []
class_name = builtin_api["name"]
snake_class_name = camel_to_snake(class_name)
@ -922,7 +931,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
(encode, arg_name) = get_encoded_arg(
argument["name"],
argument["type"],
argument["meta"] if "meta" in argument else None,
argument["meta"] if "meta" in argument else "",
)
result += encode
arguments.append(arg_name)
@ -981,7 +990,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
(encode, arg_name) = get_encoded_arg(
argument["name"],
argument["type"],
argument["meta"] if "meta" in argument else None,
argument["meta"] if "meta" in argument else "",
)
result += encode
arguments.append(arg_name)
@ -1003,7 +1012,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
if f'set_{member["name"]}' not in method_list:
result.append(f'void {class_name}::set_{member["name"]}({type_for_parameter(member["type"])}value) {{')
(encode, arg_name) = get_encoded_arg("value", member["type"], None)
(encode, arg_name) = get_encoded_arg("value", member["type"])
result += encode
result.append(
f'\t_method_bindings.member_{member["name"]}_setter((GDExtensionConstTypePtr)&opaque, (GDExtensionConstTypePtr){arg_name});'
@ -1019,7 +1028,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append(
f'{correct_type(operator["return_type"])} {class_name}::operator{operator["name"]}({type_for_parameter(operator["right_type"])}other) const {{'
)
(encode, arg_name) = get_encoded_arg("other", operator["right_type"], None)
(encode, arg_name) = get_encoded_arg("other", operator["right_type"])
result += encode
result.append(
f'\treturn internal::_call_builtin_operator_ptr<{get_gdextension_type(correct_type(operator["return_type"]))}>(_method_bindings.operator_{get_operator_id_name(operator["name"])}_{operator["right_type"]}, (GDExtensionConstTypePtr)&opaque, (GDExtensionConstTypePtr){arg_name});'
@ -1043,7 +1052,6 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
(encode, arg_name) = get_encoded_arg(
"other",
class_name,
None,
)
result += encode
result.append(
@ -1070,7 +1078,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
return "\n".join(result)
def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
def generate_engine_classes_bindings(api: Dict[str, Any], output_dir: Path, use_template_get_node: bool) -> None:
global engine_classes
global singletons
global native_structures
@ -1103,8 +1111,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
for class_api in api["classes"]:
# Check used classes for header include.
used_classes = set()
fully_used_classes = set()
used_classes: Set[str] = set()
fully_used_classes: Set[str] = set()
class_name = class_api["name"]
@ -1201,19 +1209,23 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
if type_name in used_classes:
used_classes.remove(type_name)
used_classes = list(used_classes)
used_classes.sort()
fully_used_classes = list(fully_used_classes)
fully_used_classes.sort()
used_classes_list: List[str] = list(used_classes)
used_classes_list.sort()
fully_used_classes_list: List[str] = list(fully_used_classes)
fully_used_classes_list.sort()
with header_filename.open("w+", encoding="utf-8") as header_file:
header_file.write(
generate_engine_class_header(class_api, used_classes, fully_used_classes, use_template_get_node)
generate_engine_class_header(
class_api, used_classes_list, fully_used_classes_list, use_template_get_node
)
)
with source_filename.open("w+", encoding="utf-8") as source_file:
source_file.write(
generate_engine_class_source(class_api, used_classes, fully_used_classes, use_template_get_node)
generate_engine_class_source(
class_api, used_classes_list, fully_used_classes_list, use_template_get_node
)
)
for native_struct in api["native_structures"]:
@ -1224,27 +1236,27 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
header_filename = include_gen_folder / (snake_struct_name + ".hpp")
result = []
result: List[str] = []
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}")
used_classes = []
used_classes_list = []
expanded_format = native_struct["format"].replace("(", " ").replace(")", ";").replace(",", ";")
for field in expanded_format.split(";"):
field_type = field.strip().split(" ")[0].split("::")[0]
if field_type != "" and not is_included_type(field_type) and not is_pod_type(field_type):
if not field_type in used_classes:
used_classes.append(field_type)
if not field_type in used_classes_list:
used_classes_list.append(field_type)
result.append("")
for included in used_classes:
for included in used_classes_list:
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
if len(used_classes) == 0:
if len(used_classes_list) == 0:
result.append("#include <godot_cpp/core/method_ptrcall.hpp>")
result.append("")
@ -1268,9 +1280,11 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
header_file.write("\n".join(result))
def generate_engine_class_header(class_api, used_classes, fully_used_classes, use_template_get_node):
def generate_engine_class_header(
class_api: Dict[str, Any], used_classes: List[str], fully_used_classes: List[str], use_template_get_node: bool
) -> str:
global singletons
result = []
result: List[str] = []
class_name = class_api["name"]
snake_class_name = camel_to_snake(class_name).upper()
@ -1473,7 +1487,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
method_signature += f'{correct_type(method["return_type"])} '
elif "return_value" in method:
method_signature += (
correct_type(method["return_value"]["type"], method["return_value"].get("meta", None)) + " "
correct_type(method["return_value"]["type"], method["return_value"].get("meta", "")) + " "
)
else:
method_signature += "void "
@ -1509,9 +1523,11 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
return "\n".join(result)
def generate_engine_class_source(class_api, used_classes, fully_used_classes, use_template_get_node):
def generate_engine_class_source(
class_api: Dict[str, Any], used_classes: List[str], fully_used_classes: List[str], use_template_get_node: bool
) -> str:
global singletons
result = []
result: List[str] = []
class_name = class_api["name"]
snake_class_name = camel_to_snake(class_name)
@ -1586,7 +1602,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
if not vararg:
if has_return:
return_type = method["return_value"]["type"]
meta_type = method["return_value"]["meta"] if "meta" in method["return_value"] else None
meta_type = method["return_value"]["meta"] if "meta" in method["return_value"] else ""
if is_enum(return_type):
if method["is_static"]:
method_call += f"return ({get_gdextension_type(correct_type(return_type, meta_type))})internal::_call_native_mb_ret<int64_t>(_gde_method_bind, nullptr"
@ -1625,7 +1641,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
(encode, arg_name) = get_encoded_arg(
argument["name"],
argument["type"],
argument["meta"] if "meta" in argument else None,
argument["meta"] if "meta" in argument else "",
)
result += encode
arguments.append(arg_name)
@ -1672,7 +1688,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
return "\n".join(result)
def generate_global_constants(api, output_dir):
def generate_global_constants(api: Dict[str, Any], output_dir: Path) -> None:
include_gen_folder = Path(output_dir) / "include" / "godot_cpp" / "classes"
source_gen_folder = Path(output_dir) / "src" / "classes"
@ -1681,7 +1697,7 @@ def generate_global_constants(api, output_dir):
# Generate header
header = []
header: List[str] = []
add_header("global_constants.hpp", header)
header_filename = include_gen_folder / "global_constants.hpp"
@ -1723,8 +1739,8 @@ def generate_global_constants(api, output_dir):
header_file.write("\n".join(header))
def generate_version_header(api, output_dir):
header = []
def generate_version_header(api: Dict[str, Any], output_dir: Path) -> None:
header: List[str] = []
header_filename = "version.hpp"
add_header(header_filename, header)
@ -1752,7 +1768,7 @@ def generate_version_header(api, output_dir):
header_file.write("\n".join(header))
def generate_global_constant_binds(api, output_dir):
def generate_global_constant_binds(api: Dict[str, Any], output_dir: Path) -> None:
include_gen_folder = Path(output_dir) / "include" / "godot_cpp" / "classes"
source_gen_folder = Path(output_dir) / "src" / "classes"
@ -1761,7 +1777,7 @@ def generate_global_constant_binds(api, output_dir):
# Generate header
header = []
header: List[str] = []
add_header("global_constants_binds.hpp", header)
header_filename = include_gen_folder / "global_constants_binds.hpp"
@ -1793,7 +1809,7 @@ def generate_global_constant_binds(api, output_dir):
header_file.write("\n".join(header))
def generate_utility_functions(api, output_dir):
def generate_utility_functions(api: Dict[str, Any], output_dir: Path) -> None:
include_gen_folder = Path(output_dir) / "include" / "godot_cpp" / "variant"
source_gen_folder = Path(output_dir) / "src" / "variant"
@ -1802,7 +1818,7 @@ def generate_utility_functions(api, output_dir):
# Generate header.
header = []
header: List[str] = []
add_header("utility_functions.hpp", header)
header_filename = include_gen_folder / "utility_functions.hpp"
@ -1843,7 +1859,7 @@ def generate_utility_functions(api, output_dir):
# Generate source.
source = []
source: List[str] = []
add_header("utility_functions.cpp", source)
source_filename = source_gen_folder / "utility_functions.cpp"
@ -1892,7 +1908,7 @@ def generate_utility_functions(api, output_dir):
(encode, arg_name) = get_encoded_arg(
argument["name"],
argument["type"],
argument["meta"] if "meta" in argument else None,
argument["meta"] if "meta" in argument else "",
)
source += encode
arguments.append(arg_name)
@ -1922,17 +1938,19 @@ def generate_utility_functions(api, output_dir):
# Helper functions.
def camel_to_snake(name):
def camel_to_snake(name: str) -> str:
name = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
name = re.sub("([a-z0-9])([A-Z])", r"\1_\2", name)
return name.replace("2_D", "2D").replace("3_D", "3D").lower()
def make_function_parameters(parameters, include_default=False, for_builtin=False, is_vararg=False):
def make_function_parameters(
parameters: List[Dict[str, Any]], include_default: bool = False, for_builtin: bool = False, is_vararg: bool = False
) -> str:
signature = []
for index, par in enumerate(parameters):
parameter = type_for_parameter(par["type"], par["meta"] if "meta" in par else None)
parameter = type_for_parameter(par["type"], par["meta"] if "meta" in par else "")
parameter_name = escape_identifier(par["name"])
if len(parameter_name) == 0:
parameter_name = "arg_" + str(index + 1)
@ -1954,7 +1972,7 @@ def make_function_parameters(parameters, include_default=False, for_builtin=Fals
return ", ".join(signature)
def type_for_parameter(type_name, meta=None):
def type_for_parameter(type_name: str, meta: str = "") -> str:
if type_name == "void":
return "Variant "
elif is_pod_type(type_name) and type_name != "Nil" or is_enum(type_name):
@ -1965,7 +1983,7 @@ def type_for_parameter(type_name, meta=None):
return f"{correct_type(type_name)}"
def get_include_path(type_name):
def get_include_path(type_name: str) -> str:
base_dir = ""
if type_name == "Object":
base_dir = "core"
@ -1977,8 +1995,8 @@ def get_include_path(type_name):
return f"{base_dir}/{camel_to_snake(type_name)}.hpp"
def get_encoded_arg(arg_name, type_name, type_meta):
result = []
def get_encoded_arg(arg_name: str, type_name: str, type_meta: str = "") -> Tuple[List[str], str]:
result: List[str] = []
name = escape_identifier(arg_name)
arg_type = correct_type(type_name)
@ -1997,8 +2015,13 @@ def get_encoded_arg(arg_name, type_name, type_meta):
def make_signature(
class_name, function_data, for_header=False, use_template_get_node=True, for_builtin=False, static=False
):
class_name: str,
function_data: Dict[str, Any],
for_header: bool = False,
use_template_get_node: bool = True,
for_builtin: bool = False,
static: bool = False,
) -> str:
function_signature = ""
is_vararg = "is_vararg" in function_data and function_data["is_vararg"]
@ -2014,12 +2037,12 @@ def make_signature(
function_signature += "static "
return_type = "void"
return_meta = None
return_meta = ""
if "return_type" in function_data:
return_type = correct_type(function_data["return_type"])
elif "return_value" in function_data:
return_type = function_data["return_value"]["type"]
return_meta = function_data["return_value"]["meta"] if "meta" in function_data["return_value"] else None
return_meta = function_data["return_value"]["meta"] if "meta" in function_data["return_value"] else ""
function_signature += correct_type(
return_type,
@ -2059,14 +2082,14 @@ def make_signature(
def make_varargs_template(
function_data,
static=False,
class_befor_signature="",
with_public_declare=True,
with_indent=True,
for_builtin_classes=False,
):
result = []
function_data: Dict[str, Any],
static: bool = False,
class_before_signature: str = "",
with_public_declare: bool = True,
with_indent: bool = True,
for_builtin_classes: bool = False,
) -> List[str]:
result: List[str] = []
function_signature = ""
@ -2079,12 +2102,12 @@ def make_varargs_template(
function_signature += "static "
return_type = "void"
return_meta = None
return_meta = ""
if "return_type" in function_data:
return_type = correct_type(function_data["return_type"])
elif "return_value" in function_data:
return_type = function_data["return_value"]["type"]
return_meta = function_data["return_value"]["meta"] if "meta" in function_data["return_value"] else None
return_meta = function_data["return_value"]["meta"] if "meta" in function_data["return_value"] else ""
function_signature += correct_type(
return_type,
@ -2094,8 +2117,8 @@ def make_varargs_template(
if not function_signature.endswith("*"):
function_signature += " "
if len(class_befor_signature) > 0:
function_signature += class_befor_signature + "::"
if len(class_before_signature) > 0:
function_signature += class_before_signature + "::"
function_signature += f'{escape_identifier(function_data["name"])}'
method_arguments = []
@ -2169,7 +2192,7 @@ def make_varargs_template(
# Engine idiosyncrasies.
def is_pod_type(type_name):
def is_pod_type(type_name: str) -> bool:
"""
Those are types for which no class should be generated.
"""
@ -2192,12 +2215,12 @@ def is_pod_type(type_name):
]
def is_included_type(type_name):
def is_included_type(type_name: str) -> bool:
# Types which we already have implemented.
return is_included_struct_type(type_name) or type_name in ["ObjectID"]
def is_included_struct_type(type_name):
def is_included_struct_type(type_name: str) -> bool:
# Struct types which we already have implemented.
return type_name in [
"AABB",
@ -2219,7 +2242,7 @@ def is_included_struct_type(type_name):
]
def is_packed_array(type_name):
def is_packed_array(type_name: str) -> bool:
"""
Those are types for which we add our extra packed array functions.
"""
@ -2236,7 +2259,7 @@ def is_packed_array(type_name):
]
def needs_copy_instead_of_move(type_name):
def needs_copy_instead_of_move(type_name: str) -> bool:
"""
Those are types which need initialised data or we'll get warning spam so need a copy instead of move.
"""
@ -2245,15 +2268,15 @@ def needs_copy_instead_of_move(type_name):
]
def is_enum(type_name):
def is_enum(type_name: str) -> bool:
return type_name.startswith("enum::") or type_name.startswith("bitfield::")
def is_bitfield(type_name):
def is_bitfield(type_name: str) -> bool:
return type_name.startswith("bitfield::")
def get_enum_class(enum_name: str):
def get_enum_class(enum_name: str) -> str:
if "." in enum_name:
if is_bitfield(enum_name):
return enum_name.replace("bitfield::", "").split(".")[0]
@ -2263,21 +2286,21 @@ def get_enum_class(enum_name: str):
return "GlobalConstants"
def get_enum_fullname(enum_name: str):
def get_enum_fullname(enum_name: str) -> str:
if is_bitfield(enum_name):
return enum_name.replace("bitfield::", "BitField<") + ">"
else:
return enum_name.replace("enum::", "")
def get_enum_name(enum_name: str):
def get_enum_name(enum_name: str) -> str:
if is_bitfield(enum_name):
return enum_name.replace("bitfield::", "").split(".")[-1]
else:
return enum_name.replace("enum::", "").split(".")[-1]
def is_variant(type_name):
def is_variant(type_name: str) -> bool:
return (
type_name == "Variant"
or type_name in builtin_classes
@ -2286,22 +2309,22 @@ def is_variant(type_name):
)
def is_engine_class(type_name):
def is_engine_class(type_name: str) -> bool:
global engine_classes
return type_name == "Object" or type_name in engine_classes
def is_struct_type(type_name):
def is_struct_type(type_name: str) -> bool:
# This is used to determine which keyword to use for forward declarations.
global native_structures
return is_included_struct_type(type_name) or type_name in native_structures
def is_refcounted(type_name):
def is_refcounted(type_name: str) -> bool:
return type_name in engine_classes and engine_classes[type_name]
def is_included(type_name, current_type):
def is_included(type_name: str, current_type: str) -> bool:
"""
Check if a builtin type should be included.
This removes Variant and POD types from inclusion, and the current type.
@ -2316,7 +2339,7 @@ def is_included(type_name, current_type):
return is_engine_class(to_include) or is_variant(to_include)
def correct_default_value(value, type_name):
def correct_default_value(value: str, type_name: str) -> str:
value_map = {
"null": "nullptr",
'""': "String()",
@ -2335,15 +2358,15 @@ def correct_default_value(value, type_name):
return value
def correct_typed_array(type_name):
def correct_typed_array(type_name: str) -> str:
if type_name.startswith("typedarray::"):
return type_name.replace("typedarray::", "TypedArray<") + ">"
return type_name
def correct_type(type_name, meta=None):
def correct_type(type_name: str, meta: str = "") -> str:
type_conversion = {"float": "double", "int": "int64_t", "Nil": "Variant"}
if meta != None:
if meta:
if "int" in meta:
return f"{meta}_t"
elif meta in type_conversion:
@ -2374,7 +2397,7 @@ def correct_type(type_name, meta=None):
return type_name
def get_gdextension_type(type_name):
def get_gdextension_type(type_name: str) -> str:
type_conversion_map = {
"bool": "int8_t",
"uint8_t": "int64_t",
@ -2395,7 +2418,7 @@ def get_gdextension_type(type_name):
return type_name
def escape_identifier(id):
def escape_identifier(id: str) -> str:
cpp_keywords_map = {
"class": "_class",
"char": "_char",
@ -2418,7 +2441,7 @@ def escape_identifier(id):
return id
def get_operator_id_name(op):
def get_operator_id_name(op: str) -> str:
op_id_map = {
"==": "equal",
"!=": "not_equal",
@ -2450,7 +2473,7 @@ def get_operator_id_name(op):
return op_id_map[op]
def get_default_value_for_type(type_name):
def get_default_value_for_type(type_name: str) -> str:
if type_name == "int":
return "0"
if type_name == "float":
@ -2501,7 +2524,7 @@ header = """\
"""
def add_header(filename, lines):
def add_header(filename: str, lines: List[str]) -> None:
desired_length = len(header.split("\n")[0])
pad_spaces = desired_length - 6 - len(filename)