/apps/twnlua: expose ctx
This commit is contained in:
		| @@ -36,6 +36,8 @@ def to_table(typedesc, variable, indent = 0): | ||||
|     for field in typedesc["fields"]: | ||||
|         if field["type"] == "float": | ||||
|             binding += ' ' * indent + "lua_pushnumber(L, (double)(%s));\n" % (variable + ".%s" % field["name"]) | ||||
|         elif field["type"] == "bool": | ||||
|             binding += ' ' * indent + "lua_pushboolean(L, (%s));\n" % (variable + ".%s" % field["name"]) | ||||
|         elif field["type"] in api["types"]: | ||||
|             binding += to_table(api["types"][field["type"]], variable + ".%s" % field["name"], indent + 4) | ||||
|         else: | ||||
| @@ -52,9 +54,68 @@ print('#include <lua.h>') | ||||
| print('#include <lualib.h>') | ||||
| print('#include <lauxlib.h>\n') | ||||
|  | ||||
| bindings, used_converters = [], {} | ||||
| for procedure, procedure_desc in api["procedures"].items(): | ||||
|     binding = "static int binding_%s(lua_State *L) {\n" % procedure | ||||
|     binding += "    luaL_checktype(L, 1, LUA_TTABLE);\n" | ||||
|  | ||||
|     if "params" in procedure_desc: | ||||
|         for parameter in procedure_desc["params"]: | ||||
|             basetype = parameter["type"].rsplit(' *', 1)[0] | ||||
|  | ||||
|             if parameter["type"].endswith("*"): | ||||
|                 binding += "    %s %s_value;\n" % (basetype, parameter["name"]) | ||||
|             binding += "    %s %s;\n" % (parameter["type"], parameter["name"]) | ||||
|             binding += "    lua_getfield(L, 1, \"%s\");\n" % parameter["name"] | ||||
|  | ||||
|             if "default" in parameter: | ||||
|                 binding += "    if (lua_isnoneornil(L, -1))\n" | ||||
|                 binding += "        %s = %s;\n" % (parameter["name"], default(parameter)) | ||||
|                 binding += "    else\n    " | ||||
|  | ||||
|             if parameter["type"] == "float": | ||||
|                 binding += "    %s = (float)lua_tonumber(L, -1);\n" % (parameter["name"]); | ||||
|             elif parameter["type"] == "bool": | ||||
|                 binding += "    %s = lua_toboolean(L, -1);\n" % (parameter["name"]); | ||||
|             elif parameter["type"] == "char *": | ||||
|                 binding += "    %s = lua_tostring(L, -1);\n" % (parameter["name"]); | ||||
|             elif basetype in api["types"]: | ||||
|                 used_converters[basetype] = api["types"][basetype] | ||||
|                 if parameter["type"].endswith(" *"): | ||||
|                     binding += "    { %s_value = to_%s(L, -1); %s = &%s_value; }\n" % (parameter["name"], basetype.lower(), parameter["name"], parameter["name"]); | ||||
|                 else: | ||||
|                     binding += "    %s = to_%s(L, -1);\n" % (parameter["name"], basetype.lower()); | ||||
|             else: | ||||
|                 raise BaseException("Unhandled parameter type '%s'" % (parameter["type"])) | ||||
|  | ||||
|     if "return" in procedure_desc: | ||||
|         if procedure_desc["return"] == "bool": | ||||
|             binding += "    lua_pushboolean(L, (int)%s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|         elif procedure_desc["return"] == "float": | ||||
|             binding += "    lua_pushnumber(L, (double)%s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|         elif procedure_desc["return"] == "char *": | ||||
|             binding += "    lua_pushstring(L, %s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|         elif type(procedure_desc["return"]) is dict or procedure_desc["return"] in api["types"]: | ||||
|             # TODO: handle enums | ||||
|             type_desc = procedure_desc["return"] if type(procedure_desc["return"]) is dict else api["types"][procedure_desc["return"]] | ||||
|             binding += "    %s result = %s(%s);\n" % (type_desc["c_type"], procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|             binding += to_table(type_desc, "result", 4) | ||||
|         else: | ||||
|             raise BaseException("Unhandled return type '%s'" % (procedure_desc["return"])) | ||||
|         binding += "    return 1;\n}\n" | ||||
|     else: | ||||
|         binding += "    %s(%s);\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|         binding += "    return 0;\n}\n" | ||||
|  | ||||
|     bindings += [binding] | ||||
|  | ||||
|  | ||||
| storages, converters, initializers, deinitializers = [], [], [], [] | ||||
|  | ||||
| for typename, typedesc in api["types"].items(): | ||||
| for typename, typedesc in used_converters.items(): | ||||
|     if "no_convert" in typedesc and typedesc["no_convert"]: | ||||
|         continue | ||||
|  | ||||
|     converter = "static %s to_%s(lua_State *L, int idx) {\n" % (typename, typename.lower()) | ||||
|     converter += "    %s %s;\n" % (typename, typename.lower()); | ||||
|  | ||||
| @@ -87,63 +148,11 @@ for typename, typedesc in api["types"].items(): | ||||
|     converter += "    return %s;\n}\n" % (typename.lower()) | ||||
|     converters += [converter] | ||||
|  | ||||
|  | ||||
| print('\n'.join(storages)) | ||||
| print("void bindgen_init(void) {\n" + '\n'.join(initializers) + "\n}\n") | ||||
| print('\n'.join(converters)) | ||||
|  | ||||
| bindings = [] | ||||
| for procedure, procedure_desc in api["procedures"].items(): | ||||
|     binding = "static int binding_%s(lua_State *L) {\n" % procedure | ||||
|     binding += "    luaL_checktype(L, 1, LUA_TTABLE);\n" | ||||
|  | ||||
|     if "params" in procedure_desc: | ||||
|         for parameter in procedure_desc["params"]: | ||||
|             basetype = parameter["type"].rsplit(' *', 1)[0] | ||||
|  | ||||
|             if parameter["type"].endswith("*"): | ||||
|                 binding += "    %s %s_value;\n" % (basetype, parameter["name"]) | ||||
|             binding += "    %s %s;\n" % (parameter["type"], parameter["name"]) | ||||
|             binding += "    lua_getfield(L, 1, \"%s\");\n" % parameter["name"] | ||||
|  | ||||
|             if "default" in parameter: | ||||
|                 binding += "    if (lua_isnoneornil(L, -1))\n" | ||||
|                 binding += "        %s = %s;\n" % (parameter["name"], default(parameter)) | ||||
|                 binding += "    else\n    " | ||||
|  | ||||
|             if parameter["type"] == "float": | ||||
|                 binding += "    %s = (float)lua_tonumber(L, -1);\n" % (parameter["name"]); | ||||
|             elif parameter["type"] == "bool": | ||||
|                 binding += "    %s = lua_toboolean(L, -1);\n" % (parameter["name"]); | ||||
|             elif parameter["type"] == "char *": | ||||
|                 binding += "    %s = lua_tostring(L, -1);\n" % (parameter["name"]); | ||||
|             elif basetype in api["types"]: | ||||
|                 if parameter["type"].endswith(" *"): | ||||
|                     binding += "    { %s_value = to_%s(L, -1); %s = &%s_value; }\n" % (parameter["name"], basetype.lower(), parameter["name"], parameter["name"]); | ||||
|                 else: | ||||
|                     binding += "    %s = to_%s(L, -1);\n" % (parameter["name"], basetype.lower()); | ||||
|             else: | ||||
|                 raise BaseException("Unhandled parameter type '%s'" % (parameter["type"])) | ||||
|  | ||||
|     if "return" in procedure_desc: | ||||
|         if procedure_desc["return"] == "bool": | ||||
|             binding += "    lua_pushboolean(L, (int)%s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|         elif procedure_desc["return"] == "float": | ||||
|             binding += "    lua_pushnumber(L, (double)%s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|         elif procedure_desc["return"] == "char *": | ||||
|             binding += "    lua_pushstring(L, %s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|         elif type(procedure_desc["return"]) is dict or procedure_desc["return"] in api["types"]: | ||||
|             # TODO: handle enums | ||||
|             type_desc = procedure_desc["return"] if type(procedure_desc["return"]) is dict else api["types"][procedure_desc["return"]] | ||||
|             binding += "    %s result = %s(%s);\n" % (type_desc["c_type"], procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|             binding += to_table(type_desc, "result", 4) | ||||
|         else: | ||||
|             raise BaseException("Unhandled return type '%s'" % (procedure_desc["return"])) | ||||
|         binding += "    return 1;\n}\n" | ||||
|     else: | ||||
|         binding += "    %s(%s);\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"])) | ||||
|         binding += "    return 0;\n}\n" | ||||
|  | ||||
|     print(binding) | ||||
| print('\n'.join(bindings)) | ||||
|  | ||||
|  | ||||
| loader = "void bindgen_load_%s(lua_State *L) {\n" % api["name"] | ||||
| @@ -157,11 +166,20 @@ for module in modules: | ||||
|             loader += "    lua_setfield(L, -2, \"%s\");\n" % procedure_desc["symbol"] | ||||
|     loader += "    lua_setglobal(L, \"%s\");\n" % module | ||||
|  | ||||
| loader += "}" | ||||
| loader += "}\n" | ||||
| print(loader) | ||||
|  | ||||
|  | ||||
| unloader = "void bindgen_unload_%s(lua_State *L) {\n" % api["name"] | ||||
| unloader += '\n'.join(deinitializers) | ||||
| unloader += "}" | ||||
| unloader += "}\n" | ||||
| print(unloader) | ||||
|  | ||||
|  | ||||
| # exceptions for the base townengine api | ||||
| # TODO: is there a way to generalize it? or rather, is there any need to do so? | ||||
| if api["name"] == "twn": | ||||
|     contexter = "void bindgen_build_context(lua_State *L) {\n" | ||||
|     contexter += to_table(api["types"]["Context"], "ctx", 4) | ||||
|     contexter += "}" | ||||
|     print(contexter) | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
| /* generated by bindgen.py */ | ||||
| void bindgen_load_twn(lua_State *L); | ||||
| void bindgen_unload_twn(lua_State *L); | ||||
| void bindgen_build_context(lua_State *L); | ||||
|  | ||||
|  | ||||
| /* require will go through physicsfs exclusively so that scripts can be in the data dir */ | ||||
| @@ -110,6 +111,9 @@ void game_tick(void) { | ||||
|  | ||||
|     State *state = ctx.udata; | ||||
|  | ||||
|     bindgen_build_context(state->L); | ||||
|     lua_setglobal(state->L, "ctx"); | ||||
|  | ||||
|     lua_getglobal(state->L, "game_tick"); | ||||
|     if (lua_pcall(state->L, 0, 0, 0) != LUA_OK) { | ||||
|         log_critical("%s", lua_tostring(state->L, -1)); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user