Auto-bind virtual method overrides
parent
b3a4a2cf93
commit
a0634cca3f
|
@ -562,23 +562,8 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
||||||
# Done in the header because of the template.
|
# Done in the header because of the template.
|
||||||
continue
|
continue
|
||||||
|
|
||||||
method_signature = ""
|
method_signature = make_signature(class_name, method, for_builtin=True)
|
||||||
if "return_type" in method:
|
result.append(method_signature + "{")
|
||||||
method_signature += f'{correct_type(method["return_type"])} '
|
|
||||||
else:
|
|
||||||
method_signature += "void "
|
|
||||||
|
|
||||||
method_signature += f'{class_name}::{method["name"]}('
|
|
||||||
if "arguments" in method:
|
|
||||||
method_signature += make_function_parameters(
|
|
||||||
method["arguments"], include_default=False, for_builtin=True
|
|
||||||
)
|
|
||||||
method_signature += ")"
|
|
||||||
if method["is_const"]:
|
|
||||||
method_signature += " const"
|
|
||||||
method_signature += " {"
|
|
||||||
|
|
||||||
result.append(method_signature)
|
|
||||||
|
|
||||||
method_call = "\t"
|
method_call = "\t"
|
||||||
if "return_type" in method:
|
if "return_type" in method:
|
||||||
|
@ -758,6 +743,12 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||||
if len(fully_used_classes) > 0:
|
if len(fully_used_classes) > 0:
|
||||||
result.append("")
|
result.append("")
|
||||||
|
|
||||||
|
if class_name != "Object":
|
||||||
|
result.append("#include <godot_cpp/core/class_db.hpp>")
|
||||||
|
result.append("")
|
||||||
|
result.append("#include <type_traits>")
|
||||||
|
result.append("")
|
||||||
|
|
||||||
result.append("namespace godot {")
|
result.append("namespace godot {")
|
||||||
result.append("")
|
result.append("")
|
||||||
|
|
||||||
|
@ -783,114 +774,52 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||||
result.append("\t};")
|
result.append("\t};")
|
||||||
result.append("")
|
result.append("")
|
||||||
|
|
||||||
has_vararg_method = False
|
|
||||||
|
|
||||||
if "methods" in class_api:
|
if "methods" in class_api:
|
||||||
for method in class_api["methods"]:
|
for method in class_api["methods"]:
|
||||||
if method["is_virtual"]:
|
if method["is_virtual"]:
|
||||||
# TODO: See how to bind virtual methods (if they are even needed).
|
# Will be done later.
|
||||||
continue
|
continue
|
||||||
|
|
||||||
method_signature = "\t"
|
|
||||||
|
|
||||||
vararg = "is_vararg" in method and method["is_vararg"]
|
vararg = "is_vararg" in method and method["is_vararg"]
|
||||||
|
|
||||||
|
method_signature = "\t"
|
||||||
if vararg:
|
if vararg:
|
||||||
has_vararg_method = True
|
|
||||||
method_signature += "private: "
|
method_signature += "private: "
|
||||||
|
method_signature += make_signature(
|
||||||
if "return_value" in method:
|
class_name, method, for_header=True, use_template_get_node=use_template_get_node
|
||||||
method_signature += correct_type(
|
|
||||||
method["return_value"]["type"],
|
|
||||||
method["return_value"]["meta"] if "meta" in method["return_value"] else None,
|
|
||||||
)
|
)
|
||||||
else:
|
result.append(method_signature + ";")
|
||||||
method_signature += "void"
|
|
||||||
|
|
||||||
if not method_signature.endswith("*"):
|
|
||||||
method_signature += " "
|
|
||||||
|
|
||||||
method_signature += f'{escape_identifier(method["name"])}'
|
|
||||||
|
|
||||||
if vararg or (use_template_get_node and class_name == "Node" and method["name"] == "get_node"):
|
|
||||||
method_signature += "_internal"
|
|
||||||
|
|
||||||
method_signature += "("
|
|
||||||
|
|
||||||
method_arguments = []
|
|
||||||
if "arguments" in method:
|
|
||||||
method_arguments = method["arguments"]
|
|
||||||
|
|
||||||
if not vararg:
|
|
||||||
method_signature += make_function_parameters(
|
|
||||||
method_arguments, include_default=True, is_vararg=vararg, for_builtin=False
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
method_signature += "const Variant **args, GDNativeInt arg_count"
|
|
||||||
|
|
||||||
method_signature += ")"
|
|
||||||
|
|
||||||
if method["is_const"]:
|
|
||||||
method_signature += " const"
|
|
||||||
|
|
||||||
method_signature += ";"
|
|
||||||
result.append(method_signature)
|
|
||||||
|
|
||||||
if vararg:
|
if vararg:
|
||||||
# Add templated version.
|
# Add templated version.
|
||||||
method_signature = "\tpublic: template<class... Args> "
|
result += make_varargs_template(method)
|
||||||
|
|
||||||
if "return_value" in method:
|
# Virtuals now.
|
||||||
method_signature += correct_type(
|
for method in class_api["methods"]:
|
||||||
method["return_value"]["type"],
|
if not method["is_virtual"]:
|
||||||
method["return_value"]["meta"] if "meta" in method["return_value"] else None,
|
continue
|
||||||
)
|
|
||||||
else:
|
|
||||||
method_signature += "void"
|
|
||||||
|
|
||||||
if not method_signature.endswith("*"):
|
method_signature = "\t"
|
||||||
method_signature += " "
|
method_signature += make_signature(class_name, method, for_header=True, use_template_get_node=use_template_get_node)
|
||||||
|
result.append(method_signature + ";")
|
||||||
|
|
||||||
method_signature += f'{escape_identifier(method["name"])}'
|
result.append("protected:")
|
||||||
|
result.append("\ttemplate <class T>")
|
||||||
method_arguments = []
|
result.append("\tstatic void register_virtuals() {")
|
||||||
if "arguments" in method:
|
if class_name != "Object":
|
||||||
method_arguments = method["arguments"]
|
result.append(f"\t\t{inherits}::register_virtuals<T>();")
|
||||||
|
if "methods" in class_api:
|
||||||
method_signature += "("
|
for method in class_api["methods"]:
|
||||||
|
if not method["is_virtual"]:
|
||||||
method_signature += make_function_parameters(method_arguments, include_default=True, is_vararg=vararg)
|
continue
|
||||||
|
method_name = escape_identifier(method["name"])
|
||||||
method_signature += ")"
|
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});")
|
||||||
if method["is_const"]:
|
|
||||||
method_signature += " const"
|
|
||||||
|
|
||||||
method_signature += " {"
|
|
||||||
result.append(method_signature)
|
|
||||||
|
|
||||||
args_array = f"\t\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ "
|
|
||||||
for argument in method_arguments:
|
|
||||||
if argument["type"] == "Variant":
|
|
||||||
args_array += argument["name"]
|
|
||||||
else:
|
|
||||||
args_array += f'Variant({argument["name"]})'
|
|
||||||
args_array += ", "
|
|
||||||
|
|
||||||
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("\t\t}")
|
||||||
|
|
||||||
call_line = "\t\t"
|
|
||||||
|
|
||||||
if "return_value" in method and method["return_value"]["type"] != "void":
|
|
||||||
call_line += "return "
|
|
||||||
|
|
||||||
call_line += f'{escape_identifier(method["name"])}_internal(call_args.data(), variant_args.size());'
|
|
||||||
result.append(call_line)
|
|
||||||
result.append("\t}")
|
result.append("\t}")
|
||||||
|
result.append("")
|
||||||
|
result.append("public:")
|
||||||
|
|
||||||
# Special cases.
|
# Special cases.
|
||||||
if class_name == "Object":
|
if class_name == "Object":
|
||||||
|
@ -899,7 +828,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||||
result.append("\tstatic T *cast_to(Object *p_object);")
|
result.append("\tstatic T *cast_to(Object *p_object);")
|
||||||
elif use_template_get_node and class_name == "Node":
|
elif use_template_get_node and class_name == "Node":
|
||||||
result.append("\ttemplate<class T>")
|
result.append("\ttemplate<class T>")
|
||||||
result.append("\tT *get_node(const NodePath &p_path) { 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.
|
# Constructor.
|
||||||
result.append("")
|
result.append("")
|
||||||
|
@ -943,49 +872,14 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
||||||
if "methods" in class_api:
|
if "methods" in class_api:
|
||||||
for method in class_api["methods"]:
|
for method in class_api["methods"]:
|
||||||
if method["is_virtual"]:
|
if method["is_virtual"]:
|
||||||
# TODO: See how to bind virtual methods (if they are even needed).
|
# Will be done later
|
||||||
continue
|
continue
|
||||||
|
|
||||||
vararg = "is_vararg" in method and method["is_vararg"]
|
vararg = "is_vararg" in method and method["is_vararg"]
|
||||||
|
|
||||||
# Method signature.
|
# Method signature.
|
||||||
method_signature = ""
|
method_signature = make_signature(class_name, method, use_template_get_node=use_template_get_node)
|
||||||
if "return_value" in method:
|
result.append(method_signature + " {")
|
||||||
method_signature += correct_type(
|
|
||||||
method["return_value"]["type"],
|
|
||||||
method["return_value"]["meta"] if "meta" in method["return_value"] else None,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
method_signature += "void"
|
|
||||||
|
|
||||||
if not method_signature.endswith("*"):
|
|
||||||
method_signature += " "
|
|
||||||
|
|
||||||
method_signature += f'{class_name}::{escape_identifier(method["name"])}'
|
|
||||||
|
|
||||||
if vararg or (use_template_get_node and class_name == "Node" and method["name"] == "get_node"):
|
|
||||||
method_signature += "_internal"
|
|
||||||
|
|
||||||
method_signature += "("
|
|
||||||
|
|
||||||
method_arguments = []
|
|
||||||
if "arguments" in method:
|
|
||||||
method_arguments = method["arguments"]
|
|
||||||
|
|
||||||
if not vararg:
|
|
||||||
method_signature += make_function_parameters(
|
|
||||||
method_arguments, include_default=False, is_vararg=vararg, for_builtin=False
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
method_signature += "const Variant **args, GDNativeInt arg_count"
|
|
||||||
|
|
||||||
method_signature += ")"
|
|
||||||
|
|
||||||
if method["is_const"]:
|
|
||||||
method_signature += " const"
|
|
||||||
|
|
||||||
method_signature += " {"
|
|
||||||
result.append(method_signature)
|
|
||||||
|
|
||||||
# Method body.
|
# Method body.
|
||||||
result.append(
|
result.append(
|
||||||
|
@ -1044,6 +938,22 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
||||||
result.append("}")
|
result.append("}")
|
||||||
result.append("")
|
result.append("")
|
||||||
|
|
||||||
|
# Virtuals now.
|
||||||
|
for method in class_api["methods"]:
|
||||||
|
if not method["is_virtual"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
method_signature = make_signature(class_name, method, use_template_get_node=use_template_get_node)
|
||||||
|
method_signature += " {"
|
||||||
|
if "return_value" in method and correct_type(method["return_value"]["type"]) != "void":
|
||||||
|
result.append(method_signature)
|
||||||
|
result.append(f'\treturn {get_default_value_for_type(method["return_value"]["type"])};')
|
||||||
|
result.append("}")
|
||||||
|
else:
|
||||||
|
method_signature += "}"
|
||||||
|
result.append(method_signature)
|
||||||
|
result.append("")
|
||||||
|
|
||||||
# Constructor.
|
# Constructor.
|
||||||
result.append(f"{class_name}::{class_name}() : {inherits}(godot::internal::empty_constructor()) {{")
|
result.append(f"{class_name}::{class_name}() : {inherits}(godot::internal::empty_constructor()) {{")
|
||||||
result.append(
|
result.append(
|
||||||
|
@ -1138,85 +1048,12 @@ def generate_utility_functions(api, output_dir):
|
||||||
vararg = "is_vararg" in function and function["is_vararg"]
|
vararg = "is_vararg" in function and function["is_vararg"]
|
||||||
|
|
||||||
function_signature = "\t"
|
function_signature = "\t"
|
||||||
if vararg:
|
function_signature += make_signature("UtilityFunctions", function, for_header=True, static=True)
|
||||||
function_signature += "private: "
|
header.append(function_signature + ";")
|
||||||
function_signature += "static "
|
|
||||||
|
|
||||||
if "return_type" in function:
|
|
||||||
if not vararg:
|
|
||||||
function_signature += f'{correct_type(function["return_type"])} '
|
|
||||||
else:
|
|
||||||
function_signature += "Variant "
|
|
||||||
else:
|
|
||||||
function_signature += "void "
|
|
||||||
|
|
||||||
function_signature += f'{escape_identifier(function["name"])}'
|
|
||||||
|
|
||||||
if vararg:
|
|
||||||
function_signature += "_internal"
|
|
||||||
|
|
||||||
function_signature += "("
|
|
||||||
|
|
||||||
function_arguments = []
|
|
||||||
if "arguments" in function:
|
|
||||||
function_arguments = function["arguments"]
|
|
||||||
|
|
||||||
if not vararg:
|
|
||||||
function_signature += make_function_parameters(function_arguments, include_default=False)
|
|
||||||
else:
|
|
||||||
function_signature += "const Variant **args, GDNativeInt arg_count"
|
|
||||||
function_signature += ");"
|
|
||||||
|
|
||||||
header.append(function_signature)
|
|
||||||
|
|
||||||
if vararg:
|
if vararg:
|
||||||
# Add templated version.
|
# Add templated version.
|
||||||
method_signature = "\tpublic: template<class... Args> static "
|
header += make_varargs_template(function, static=True)
|
||||||
|
|
||||||
if "return_type" in function:
|
|
||||||
method_signature += correct_type(function["return_type"])
|
|
||||||
else:
|
|
||||||
method_signature += "void"
|
|
||||||
|
|
||||||
if not method_signature.endswith("*"):
|
|
||||||
method_signature += " "
|
|
||||||
|
|
||||||
method_signature += f'{escape_identifier(function["name"])}'
|
|
||||||
|
|
||||||
method_arguments = []
|
|
||||||
if "arguments" in function:
|
|
||||||
method_arguments = function["arguments"]
|
|
||||||
|
|
||||||
method_signature += "("
|
|
||||||
method_signature += make_function_parameters(method_arguments, include_default=True, is_vararg=vararg)
|
|
||||||
method_signature += ")"
|
|
||||||
|
|
||||||
method_signature += " {"
|
|
||||||
header.append(method_signature)
|
|
||||||
|
|
||||||
args_array = f"\t\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ "
|
|
||||||
for argument in method_arguments:
|
|
||||||
if argument["type"] == "Variant":
|
|
||||||
args_array += argument["name"]
|
|
||||||
else:
|
|
||||||
args_array += f'Variant({argument["name"]})'
|
|
||||||
args_array += ", "
|
|
||||||
|
|
||||||
args_array += "Variant(args)... };"
|
|
||||||
header.append(args_array)
|
|
||||||
header.append(f"\t\tstd::array<const Variant *, {len(method_arguments)} + sizeof...(Args)> call_args;")
|
|
||||||
header.append("\t\tfor(size_t i = 0; i < variant_args.size(); i++) {")
|
|
||||||
header.append("\t\t\tcall_args[i] = &variant_args[i];")
|
|
||||||
header.append("\t\t}")
|
|
||||||
|
|
||||||
call_line = "\t\t"
|
|
||||||
|
|
||||||
if "return_type" in function and function["return_type"] != "void":
|
|
||||||
call_line += "return "
|
|
||||||
|
|
||||||
call_line += f'{escape_identifier(function["name"])}_internal(call_args.data(), variant_args.size());'
|
|
||||||
header.append(call_line)
|
|
||||||
header.append("\t}")
|
|
||||||
|
|
||||||
header.append("};")
|
header.append("};")
|
||||||
header.append("")
|
header.append("")
|
||||||
|
@ -1244,34 +1081,8 @@ def generate_utility_functions(api, output_dir):
|
||||||
for function in api["utility_functions"]:
|
for function in api["utility_functions"]:
|
||||||
vararg = "is_vararg" in function and function["is_vararg"]
|
vararg = "is_vararg" in function and function["is_vararg"]
|
||||||
|
|
||||||
function_signature = ""
|
function_signature = make_signature("UtilityFunctions", function)
|
||||||
if "return_type" in function:
|
source.append(function_signature + " {")
|
||||||
if not vararg:
|
|
||||||
function_signature += f'{correct_type(function["return_type"])}'
|
|
||||||
else:
|
|
||||||
function_signature += "Variant"
|
|
||||||
else:
|
|
||||||
function_signature += "void"
|
|
||||||
|
|
||||||
if not function_signature.endswith("*"):
|
|
||||||
function_signature += " "
|
|
||||||
|
|
||||||
function_signature += f'UtilityFunctions::{escape_identifier(function["name"])}'
|
|
||||||
if vararg:
|
|
||||||
function_signature += "_internal"
|
|
||||||
function_signature += "("
|
|
||||||
|
|
||||||
function_arguments = []
|
|
||||||
if "arguments" in function:
|
|
||||||
function_arguments = function["arguments"]
|
|
||||||
|
|
||||||
if not vararg:
|
|
||||||
function_signature += make_function_parameters(function_arguments, include_default=False)
|
|
||||||
else:
|
|
||||||
function_signature += "const Variant **args, GDNativeInt arg_count"
|
|
||||||
function_signature += ") {"
|
|
||||||
|
|
||||||
source.append(function_signature)
|
|
||||||
|
|
||||||
# Function body.
|
# Function body.
|
||||||
|
|
||||||
|
@ -1340,14 +1151,20 @@ def camel_to_snake(name):
|
||||||
def make_function_parameters(parameters, include_default=False, for_builtin=False, is_vararg=False):
|
def make_function_parameters(parameters, include_default=False, for_builtin=False, is_vararg=False):
|
||||||
signature = []
|
signature = []
|
||||||
|
|
||||||
for par in parameters:
|
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 None)
|
||||||
parameter += escape_identifier(par["name"])
|
parameter_name = escape_identifier(par["name"])
|
||||||
|
if len(parameter_name) == 0:
|
||||||
|
parameter_name = "arg_" + str(index + 1)
|
||||||
|
parameter += parameter_name
|
||||||
|
|
||||||
if include_default and "default_value" in par and (not for_builtin or par["type"] != "Variant"):
|
if include_default and "default_value" in par and (not for_builtin or par["type"] != "Variant"):
|
||||||
parameter += " = "
|
parameter += " = "
|
||||||
if is_enum(par["type"]):
|
if is_enum(par["type"]):
|
||||||
parameter += f'({correct_type(par["type"])})'
|
parameter_type = correct_type(par["type"])
|
||||||
|
if parameter_type == "void":
|
||||||
|
parameter_type = "Variant"
|
||||||
|
parameter += f'({parameter_type})'
|
||||||
parameter += correct_default_value(par["default_value"], par["type"])
|
parameter += correct_default_value(par["default_value"], par["type"])
|
||||||
signature.append(parameter)
|
signature.append(parameter)
|
||||||
|
|
||||||
|
@ -1358,7 +1175,9 @@ def make_function_parameters(parameters, include_default=False, for_builtin=Fals
|
||||||
|
|
||||||
|
|
||||||
def type_for_parameter(type_name, meta=None):
|
def type_for_parameter(type_name, meta=None):
|
||||||
if is_pod_type(type_name) and type_name != "Nil" or is_enum(type_name):
|
if type_name == "void":
|
||||||
|
return "Variant "
|
||||||
|
elif is_pod_type(type_name) and type_name != "Nil" or is_enum(type_name):
|
||||||
return f"{correct_type(type_name, meta)} "
|
return f"{correct_type(type_name, meta)} "
|
||||||
elif is_variant(type_name) or is_refcounted(type_name):
|
elif is_variant(type_name) or is_refcounted(type_name):
|
||||||
return f"const {correct_type(type_name)} &"
|
return f"const {correct_type(type_name)} &"
|
||||||
|
@ -1395,6 +1214,135 @@ def get_encoded_arg(arg_name, type_name, type_meta):
|
||||||
return (result, name)
|
return (result, name)
|
||||||
|
|
||||||
|
|
||||||
|
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"]
|
||||||
|
|
||||||
|
if for_header:
|
||||||
|
if "is_virtual" in function_data and function_data["is_virtual"]:
|
||||||
|
function_signature += "virtual "
|
||||||
|
|
||||||
|
if is_vararg:
|
||||||
|
function_signature += "private: "
|
||||||
|
|
||||||
|
if static:
|
||||||
|
function_signature += "static "
|
||||||
|
|
||||||
|
return_type = "void"
|
||||||
|
return_meta = None
|
||||||
|
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
|
||||||
|
|
||||||
|
function_signature += correct_type(
|
||||||
|
return_type,
|
||||||
|
return_meta,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not function_signature.endswith("*"):
|
||||||
|
function_signature += " "
|
||||||
|
|
||||||
|
if not for_header:
|
||||||
|
function_signature += f"{class_name}::"
|
||||||
|
|
||||||
|
function_signature += escape_identifier(function_data["name"])
|
||||||
|
|
||||||
|
if is_vararg or (
|
||||||
|
not for_builtin and use_template_get_node and class_name == "Node" and function_data["name"] == "get_node"
|
||||||
|
):
|
||||||
|
function_signature += "_internal"
|
||||||
|
|
||||||
|
function_signature += "("
|
||||||
|
|
||||||
|
arguments = function_data["arguments"] if "arguments" in function_data else []
|
||||||
|
|
||||||
|
if not is_vararg:
|
||||||
|
function_signature += make_function_parameters(arguments, for_header, for_builtin, is_vararg)
|
||||||
|
else:
|
||||||
|
function_signature += "const Variant **args, GDNativeInt arg_count"
|
||||||
|
|
||||||
|
function_signature += ")"
|
||||||
|
|
||||||
|
if "is_const" in function_data and function_data["is_const"]:
|
||||||
|
function_signature += " const"
|
||||||
|
|
||||||
|
return function_signature
|
||||||
|
|
||||||
|
|
||||||
|
def make_varargs_template(function_data, static=False):
|
||||||
|
result = []
|
||||||
|
|
||||||
|
function_signature = "\tpublic: template<class... Args> "
|
||||||
|
|
||||||
|
if static:
|
||||||
|
function_signature += "static "
|
||||||
|
|
||||||
|
return_type = "void"
|
||||||
|
return_meta = None
|
||||||
|
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
|
||||||
|
|
||||||
|
function_signature += correct_type(
|
||||||
|
return_type,
|
||||||
|
return_meta,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not function_signature.endswith("*"):
|
||||||
|
function_signature += " "
|
||||||
|
|
||||||
|
function_signature += f'{escape_identifier(function_data["name"])}'
|
||||||
|
|
||||||
|
method_arguments = []
|
||||||
|
if "arguments" in function_data:
|
||||||
|
method_arguments = function_data["arguments"]
|
||||||
|
|
||||||
|
function_signature += "("
|
||||||
|
|
||||||
|
is_vararg = "is_vararg" in function_data and function_data["is_vararg"]
|
||||||
|
|
||||||
|
function_signature += make_function_parameters(method_arguments, include_default=True, is_vararg=is_vararg)
|
||||||
|
|
||||||
|
function_signature += ")"
|
||||||
|
|
||||||
|
if "is_const" in function_data and function_data["is_const"]:
|
||||||
|
function_signature += " const"
|
||||||
|
|
||||||
|
function_signature += " {"
|
||||||
|
result.append(function_signature)
|
||||||
|
|
||||||
|
args_array = f"\t\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ "
|
||||||
|
for argument in method_arguments:
|
||||||
|
if argument["type"] == "Variant":
|
||||||
|
args_array += argument["name"]
|
||||||
|
else:
|
||||||
|
args_array += f'Variant({argument["name"]})'
|
||||||
|
args_array += ", "
|
||||||
|
|
||||||
|
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}")
|
||||||
|
|
||||||
|
call_line = "\t\t"
|
||||||
|
|
||||||
|
if "return_value" in function_data and function_data["return_value"]["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}")
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
# Engine idiosyncrasies.
|
# Engine idiosyncrasies.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,11 @@ protected:
|
||||||
\
|
\
|
||||||
m_class(godot::internal::empty_constructor empty) : m_inherits(empty) {} \
|
m_class(godot::internal::empty_constructor empty) : m_inherits(empty) {} \
|
||||||
\
|
\
|
||||||
|
template <class T> \
|
||||||
|
static void register_virtuals() { \
|
||||||
|
m_inherits::register_virtuals<T>(); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
public: \
|
public: \
|
||||||
static void initialize_class() { \
|
static void initialize_class() { \
|
||||||
static bool initialized = false; \
|
static bool initialized = false; \
|
||||||
|
@ -85,6 +90,7 @@ public:
|
||||||
m_inherits::initialize_class(); \
|
m_inherits::initialize_class(); \
|
||||||
if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \
|
if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \
|
||||||
_bind_methods(); \
|
_bind_methods(); \
|
||||||
|
m_inherits::register_virtuals<m_class>(); \
|
||||||
} \
|
} \
|
||||||
initialized = true; \
|
initialized = true; \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -168,12 +168,12 @@ void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class... P>
|
template <class T, class... P>
|
||||||
void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const GDNativeTypePtr *p_args) {
|
void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const GDNativeTypePtr *p_args, void * /*ret*/) {
|
||||||
call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
|
call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class... P>
|
template <class T, class... P>
|
||||||
void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...) const, const GDNativeTypePtr *p_args) {
|
void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...) const, const GDNativeTypePtr *p_args, void * /*ret*/) {
|
||||||
call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
|
call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,12 +123,12 @@ public:
|
||||||
#define BIND_ENUM_CONSTANT(m_constant) \
|
#define BIND_ENUM_CONSTANT(m_constant) \
|
||||||
ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
|
ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
|
||||||
|
|
||||||
#define BIND_VIRTUAL_METHOD(m_method) \
|
#define BIND_VIRTUAL_METHOD(m_class, m_method) \
|
||||||
{ \
|
{ \
|
||||||
auto ___call##m_method = [](GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr p_ret) -> void { \
|
auto ___call##m_method = [](GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr p_ret) -> void { \
|
||||||
call_with_ptr_args(reinterpret_cast<SelfType *>(p_instance), &SelfType::m_method, p_args, p_ret); \
|
call_with_ptr_args(reinterpret_cast<m_class *>(p_instance), &m_class::m_method, p_args, p_ret); \
|
||||||
}; \
|
}; \
|
||||||
ClassDB::bind_virtual_method(get_class_static(), #m_method, ___call##m_method); \
|
ClassDB::bind_virtual_method(m_class::get_class_static(), #m_method, ___call##m_method); \
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
|
@ -260,9 +260,9 @@ public:
|
||||||
}
|
}
|
||||||
virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const {
|
virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const {
|
||||||
#ifdef TYPED_METHOD_BIND
|
#ifdef TYPED_METHOD_BIND
|
||||||
call_with_ptr_args<T, P...>(static_cast<T *>(p_instance), method, p_args);
|
call_with_ptr_args<T, P...>(static_cast<T *>(p_instance), method, p_args, nullptr);
|
||||||
#else
|
#else
|
||||||
call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_instance), method, p_args);
|
call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_instance), method, p_args, nullptr);
|
||||||
#endif // TYPED_METHOD_BIND
|
#endif // TYPED_METHOD_BIND
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,9 +338,9 @@ public:
|
||||||
}
|
}
|
||||||
virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const {
|
virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const {
|
||||||
#ifdef TYPED_METHOD_BIND
|
#ifdef TYPED_METHOD_BIND
|
||||||
call_with_ptr_args<T, P...>(static_cast<T *>(p_instance), method, p_args);
|
call_with_ptr_args<T, P...>(static_cast<T *>(p_instance), method, p_args, nullptr);
|
||||||
#else
|
#else
|
||||||
call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_instance), method, p_args);
|
call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_instance), method, p_args, nullptr);
|
||||||
#endif // TYPED_METHOD_BIND
|
#endif // TYPED_METHOD_BIND
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,6 @@ void Example::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING);
|
BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING);
|
||||||
|
|
||||||
BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
|
BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
|
||||||
|
|
||||||
// Virtual function override.
|
|
||||||
BIND_VIRTUAL_METHOD(_has_point);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods.
|
// Methods.
|
||||||
|
@ -83,7 +80,7 @@ Vector2 Example::get_custom_position() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Virtual function override.
|
// Virtual function override.
|
||||||
bool Example::_has_point(const Vector2 &point) {
|
bool Example::_has_point(const Vector2 &point) const {
|
||||||
Label *label = get_node<Label>("Label");
|
Label *label = get_node<Label>("Label");
|
||||||
label->set_text("Got point: " + Variant(point).stringify());
|
label->set_text("Got point: " + Variant(point).stringify());
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
CONSTANT_WITHOUT_ENUM = 314,
|
CONSTANT_WITHOUT_ENUM = 314,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Functions
|
// Functions.
|
||||||
void simple_func();
|
void simple_func();
|
||||||
void simple_const_func() const;
|
void simple_const_func() const;
|
||||||
String return_something(const String &base);
|
String return_something(const String &base);
|
||||||
|
@ -37,12 +37,12 @@ public:
|
||||||
Variant varargs_func(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error);
|
Variant varargs_func(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error);
|
||||||
void emit_custom_signal(const String &name, int value);
|
void emit_custom_signal(const String &name, int value);
|
||||||
|
|
||||||
// Property
|
// Property.
|
||||||
void set_custom_position(const Vector2 &pos);
|
void set_custom_position(const Vector2 &pos);
|
||||||
Vector2 get_custom_position() const;
|
Vector2 get_custom_position() const;
|
||||||
|
|
||||||
// Virtual function override
|
// Virtual function override (no need to bind manually).
|
||||||
virtual bool _has_point(const Vector2 &point);
|
virtual bool _has_point(const Vector2 &point) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(Example, Constants);
|
VARIANT_ENUM_CAST(Example, Constants);
|
||||||
|
|
Loading…
Reference in New Issue