From 065f819487aec6382ee9f87cb9c8d16d76b4b104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Wed, 22 Feb 2017 20:34:07 +0100 Subject: vis-lua: expose type meta tables through vis.types This should allow the Lua code to add new methods even if it has no existing object references. --- vis-lua.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'vis-lua.c') diff --git a/vis-lua.c b/vis-lua.c index 43957af..46f3a24 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -276,6 +276,14 @@ static bool func_ref_get(lua_State *L, const void *addr) { */ static void obj_type_new(lua_State *L, const char *type) { luaL_newmetatable(L, type); + lua_getglobal(L, "vis"); + if (!lua_isnil(L, -1)) { + lua_getfield(L, -1, "types"); + lua_pushvalue(L, -3); + lua_setfield(L, -2, type); + lua_pop(L, 1); + } + lua_pop(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "vis.types"); lua_pushvalue(L, -2); lua_pushstring(L, type); @@ -526,6 +534,11 @@ static const char *keymapping(Vis *vis, const char *keys, const Arg *arg) { * @tfield string VERSION * version information in `git describe` format, same as reported by `vis -v`. */ +/*** + * Lua API object types + * @field types meta tables of userdata objects used for type checking + * @internal + */ /*** * User interface. * @tfield Ui ui the user interface being used @@ -2243,6 +2256,16 @@ void vis_lua_init(Vis *vis) { lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "vis.functions"); /* metatable used to type check user data */ + obj_type_new(L, "vis"); + luaL_setfuncs(L, vis_lua, 0); + lua_newtable(L); + lua_setfield(L, -2, "types"); + /* create reference to main vis object, such that the further + * calls to obj_type_new can register the type meta tables in + * vis.types[name] */ + obj_ref_new(L, vis, "vis"); + lua_setglobal(L, "vis"); + obj_type_new(L, "vis.file"); const struct { @@ -2304,8 +2327,8 @@ void vis_lua_init(Vis *vis) { obj_type_new(L, "vis.keyaction"); - obj_type_new(L, "vis"); - luaL_setfuncs(L, vis_lua, 0); + lua_getglobal(L, "vis"); + lua_getmetatable(L, -1); lua_pushstring(L, VERSION); lua_setfield(L, -2, "VERSION"); @@ -2331,9 +2354,6 @@ void vis_lua_init(Vis *vis) { lua_setfield(L, -2, "modes"); - obj_ref_new(L, vis, "vis"); - lua_setglobal(L, "vis"); - if (!package_exist(vis, L, "visrc")) { vis_info_show(vis, "WARNING: failed to load visrc.lua"); } else { -- cgit v1.2.3