123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- """Functions used to generate source files during build time
- All such functions are invoked in a subprocess on Windows to prevent build flakiness.
- """
- import json
- from platform_methods import subprocess_main
- def _spaced(e):
- return e if e[-1] == "*" else e + " "
- def _build_gdnative_api_struct_header(api):
- gdnative_api_init_macro = ["\textern const godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct;"]
- for ext in api["extensions"]:
- name = ext["name"]
- gdnative_api_init_macro.append(
- "\textern const godot_gdnative_ext_{0}_api_struct *_gdnative_wrapper_{0}_api_struct;".format(name)
- )
- gdnative_api_init_macro.append("\t_gdnative_wrapper_api_struct = options->api_struct;")
- gdnative_api_init_macro.append(
- "\tfor (unsigned int i = 0; i < _gdnative_wrapper_api_struct->num_extensions; i++) { "
- )
- gdnative_api_init_macro.append("\t\tswitch (_gdnative_wrapper_api_struct->extensions[i]->type) {")
- for ext in api["extensions"]:
- name = ext["name"]
- gdnative_api_init_macro.append("\t\t\tcase GDNATIVE_EXT_%s:" % ext["type"])
- gdnative_api_init_macro.append(
- "\t\t\t\t_gdnative_wrapper_{0}_api_struct = (godot_gdnative_ext_{0}_api_struct *)"
- " _gdnative_wrapper_api_struct->extensions[i];".format(name)
- )
- gdnative_api_init_macro.append("\t\t\t\tbreak;")
- gdnative_api_init_macro.append("\t\t}")
- gdnative_api_init_macro.append("\t}")
- out = [
- "/* THIS FILE IS GENERATED DO NOT EDIT */",
- "#ifndef GODOT_GDNATIVE_API_STRUCT_H",
- "#define GODOT_GDNATIVE_API_STRUCT_H",
- "",
- "#include <gdnative/gdnative.h>",
- "#include <android/godot_android.h>",
- "#include <arvr/godot_arvr.h>",
- "#include <nativescript/godot_nativescript.h>",
- "#include <net/godot_net.h>",
- "#include <pluginscript/godot_pluginscript.h>",
- "#include <videodecoder/godot_videodecoder.h>",
- "",
- "#define GDNATIVE_API_INIT(options) do { \\\n" + " \\\n".join(gdnative_api_init_macro) + " \\\n } while (0)",
- "",
- "#ifdef __cplusplus",
- 'extern "C" {',
- "#endif",
- "",
- "enum GDNATIVE_API_TYPES {",
- "\tGDNATIVE_" + api["core"]["type"] + ",",
- ]
- for ext in api["extensions"]:
- out += ["\tGDNATIVE_EXT_" + ext["type"] + ","]
- out += ["};", ""]
- def generate_extension_struct(name, ext, include_version=True):
- ret_val = []
- if ext["next"]:
- ret_val += generate_extension_struct(name, ext["next"])
- ret_val += [
- "typedef struct godot_gdnative_ext_"
- + name
- + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
- + "_api_struct {",
- "\tunsigned int type;",
- "\tgodot_gdnative_api_version version;",
- "\tconst godot_gdnative_api_struct *next;",
- ]
- for funcdef in ext["api"]:
- args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
- ret_val.append("\t%s(*%s)(%s);" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
- ret_val += [
- "} godot_gdnative_ext_"
- + name
- + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
- + "_api_struct;",
- "",
- ]
- return ret_val
- def generate_core_extension_struct(core):
- ret_val = []
- if core["next"]:
- ret_val += generate_core_extension_struct(core["next"])
- ret_val += [
- "typedef struct godot_gdnative_core_"
- + ("{0}_{1}".format(core["version"]["major"], core["version"]["minor"]))
- + "_api_struct {",
- "\tunsigned int type;",
- "\tgodot_gdnative_api_version version;",
- "\tconst godot_gdnative_api_struct *next;",
- ]
- for funcdef in core["api"]:
- args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
- ret_val.append("\t%s(*%s)(%s);" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
- ret_val += [
- "} godot_gdnative_core_"
- + "{0}_{1}".format(core["version"]["major"], core["version"]["minor"])
- + "_api_struct;",
- "",
- ]
- return ret_val
- for ext in api["extensions"]:
- name = ext["name"]
- out += generate_extension_struct(name, ext, False)
- if api["core"]["next"]:
- out += generate_core_extension_struct(api["core"]["next"])
- out += [
- "typedef struct godot_gdnative_core_api_struct {",
- "\tunsigned int type;",
- "\tgodot_gdnative_api_version version;",
- "\tconst godot_gdnative_api_struct *next;",
- "\tunsigned int num_extensions;",
- "\tconst godot_gdnative_api_struct **extensions;",
- ]
- for funcdef in api["core"]["api"]:
- args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
- out.append("\t%s(*%s)(%s);" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
- out += [
- "} godot_gdnative_core_api_struct;",
- "",
- "#ifdef __cplusplus",
- "}",
- "#endif",
- "",
- "#endif // GODOT_GDNATIVE_API_STRUCT_H",
- "",
- ]
- return "\n".join(out)
- def _build_gdnative_api_struct_source(api):
- out = ["/* THIS FILE IS GENERATED DO NOT EDIT */", "", "#include <gdnative_api_struct.gen.h>", ""]
- def get_extension_struct_name(name, ext, include_version=True):
- return (
- "godot_gdnative_ext_"
- + name
- + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
- + "_api_struct"
- )
- def get_extension_struct_instance_name(name, ext, include_version=True):
- return (
- "api_extension_"
- + name
- + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
- + "_struct"
- )
- def get_extension_struct_definition(name, ext, include_version=True):
- ret_val = []
- if ext["next"]:
- ret_val += get_extension_struct_definition(name, ext["next"])
- ret_val += [
- "extern const "
- + get_extension_struct_name(name, ext, include_version)
- + " "
- + get_extension_struct_instance_name(name, ext, include_version)
- + " = {",
- "\tGDNATIVE_EXT_" + ext["type"] + ",",
- "\t{" + str(ext["version"]["major"]) + ", " + str(ext["version"]["minor"]) + "},",
- "\t"
- + (
- "NULL"
- if not ext["next"]
- else ("(const godot_gdnative_api_struct *)&" + get_extension_struct_instance_name(name, ext["next"]))
- )
- + ",",
- ]
- for funcdef in ext["api"]:
- ret_val.append("\t%s," % funcdef["name"])
- ret_val += ["};\n"]
- return ret_val
- def get_core_struct_definition(core):
- ret_val = []
- if core["next"]:
- ret_val += get_core_struct_definition(core["next"])
- ret_val += [
- "extern const godot_gdnative_core_"
- + ("{0}_{1}_api_struct api_{0}_{1}".format(core["version"]["major"], core["version"]["minor"]))
- + " = {",
- "\tGDNATIVE_" + core["type"] + ",",
- "\t{" + str(core["version"]["major"]) + ", " + str(core["version"]["minor"]) + "},",
- "\t"
- + (
- "NULL"
- if not core["next"]
- else (
- "(const godot_gdnative_api_struct *)& api_{0}_{1}".format(
- core["next"]["version"]["major"], core["next"]["version"]["minor"]
- )
- )
- )
- + ",",
- ]
- for funcdef in core["api"]:
- ret_val.append("\t%s," % funcdef["name"])
- ret_val += ["};\n"]
- return ret_val
- for ext in api["extensions"]:
- name = ext["name"]
- out += get_extension_struct_definition(name, ext, False)
- out += ["", "const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {"]
- for ext in api["extensions"]:
- name = ext["name"]
- out += ["\t(godot_gdnative_api_struct *)&api_extension_" + name + "_struct,"]
- out += ["};\n"]
- if api["core"]["next"]:
- out += get_core_struct_definition(api["core"]["next"])
- out += [
- "extern const godot_gdnative_core_api_struct api_struct = {",
- "\tGDNATIVE_" + api["core"]["type"] + ",",
- "\t{" + str(api["core"]["version"]["major"]) + ", " + str(api["core"]["version"]["minor"]) + "},",
- "\t(const godot_gdnative_api_struct *)&api_1_1,",
- "\t" + str(len(api["extensions"])) + ",",
- "\tgdnative_extensions_pointers,",
- ]
- for funcdef in api["core"]["api"]:
- out.append("\t%s," % funcdef["name"])
- out.append("};\n")
- return "\n".join(out)
- def build_gdnative_api_struct(target, source, env):
- with open(source[0], "r") as fd:
- api = json.load(fd)
- header, source = target
- with open(header, "w") as fd:
- fd.write(_build_gdnative_api_struct_header(api))
- with open(source, "w") as fd:
- fd.write(_build_gdnative_api_struct_source(api))
- def _build_gdnative_wrapper_code(api):
- out = [
- "/* THIS FILE IS GENERATED DO NOT EDIT */",
- "",
- "#include <gdnative/gdnative.h>",
- "#include <nativescript/godot_nativescript.h>",
- "#include <pluginscript/godot_pluginscript.h>",
- "#include <arvr/godot_arvr.h>",
- "#include <videodecoder/godot_videodecoder.h>",
- "",
- "#include <gdnative_api_struct.gen.h>",
- "",
- "#ifdef __cplusplus",
- 'extern "C" {',
- "#endif",
- "",
- "godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct = 0;",
- ]
- for ext in api["extensions"]:
- name = ext["name"]
- out.append("godot_gdnative_ext_" + name + "_api_struct *_gdnative_wrapper_" + name + "_api_struct = 0;")
- out += [""]
- for funcdef in api["core"]["api"]:
- args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
- out.append("%s%s(%s) {" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
- args = ", ".join(["%s" % n for t, n in funcdef["arguments"]])
- return_line = "\treturn " if funcdef["return_type"] != "void" else "\t"
- return_line += "_gdnative_wrapper_api_struct->" + funcdef["name"] + "(" + args + ");"
- out.append(return_line)
- out.append("}")
- out.append("")
- for ext in api["extensions"]:
- name = ext["name"]
- for funcdef in ext["api"]:
- args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
- out.append("%s%s(%s) {" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
- args = ", ".join(["%s" % n for t, n in funcdef["arguments"]])
- return_line = "\treturn " if funcdef["return_type"] != "void" else "\t"
- return_line += "_gdnative_wrapper_" + name + "_api_struct->" + funcdef["name"] + "(" + args + ");"
- out.append(return_line)
- out.append("}")
- out.append("")
- out += ["#ifdef __cplusplus", "}", "#endif"]
- return "\n".join(out)
- def build_gdnative_wrapper_code(target, source, env):
- with open(source[0], "r") as fd:
- api = json.load(fd)
- wrapper_file = target[0]
- with open(wrapper_file, "w") as fd:
- fd.write(_build_gdnative_wrapper_code(api))
- if __name__ == "__main__":
- subprocess_main(globals())
|