From 3814103a1ef32547be95b84b19162f466a0d5ce1 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Thu, 7 Aug 2008 15:48:26 +0200 Subject: [PATCH] lua: implement objecttable Signed-off-by: Julien Danjou --- lib/awful.lua.in | 21 ++------------------- lua.c | 42 ++++++++++++++++++++++++++++++++++++++++++ lua.h | 22 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 19 deletions(-) diff --git a/lib/awful.lua.in b/lib/awful.lua.in index 93bb1778c..64cac9f42 100644 --- a/lib/awful.lua.in +++ b/lib/awful.lua.in @@ -16,6 +16,7 @@ local io = io local math = math local setmetatable = setmetatable local table = table +local otable = otable local capi = { screen = screen, @@ -31,24 +32,6 @@ local capi = --- awful: AWesome Functions very UsefuL module("awful") --- The ObjectTable class -ObjectTable = {} -ObjectTable.__index = ObjectTable ---- Lookup in a table indexed by objects -function ObjectTable.__index(self, key) - for k, v in pairs(self) do - if k == key then - return v - end - end -end - -function ObjectTable.new() - local o = {} - setmetatable(o, ObjectTable) - return o -end - -- Local variable handling theme local theme = {} @@ -70,7 +53,7 @@ tag.history.data = {} tag.history.data.past = {} tag.history.data.current = {} titlebar = {} -titlebar.data = ObjectTable.new() +titlebar.data = otable() widget = {} widget.taglist = {} widget.taglist.label = {} diff --git a/lua.c b/lua.c index a4613815d..485e7f9e9 100644 --- a/lua.c +++ b/lua.c @@ -436,6 +436,35 @@ luaA_fixups(lua_State *L) lua_pop(L, 1); } +/** Object table. + * This table can use safely object as key. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + */ +int +luaA_otable_index(lua_State *L) +{ + void **obj, **v; + + if((obj = lua_touserdata(L, 2))) + { + /* begins at nil */ + lua_pushnil(L); + while(lua_next(L, 1)) + { + if((v = lua_touserdata(L, -2)) + && *v == *obj) + return 1; + /* removes 'value'; keeps 'key' for next iteration */ + lua_pop(L, 1); + } + return 0; + } + + lua_rawget(L, 1); + return 1; +} + /** Initialize the Lua VM */ void @@ -443,6 +472,16 @@ luaA_init(void) { lua_State *L; + static const struct luaL_reg otable_methods[] = + { + { "__call", luaA_otable_new }, + { NULL, NULL } + }; + static const struct luaL_reg otable_meta[] = + { + { "__index", luaA_otable_index }, + { NULL, NULL } + }; static const struct luaL_reg awesome_lib[] = { { "quit", luaA_quit }, @@ -493,6 +532,9 @@ luaA_init(void) /* Export keygrabber lib */ luaL_register(L, "keygrabber", awesome_keygrabber_lib); + /* Export otable lib */ + luaA_openlib(L, "otable", otable_methods, otable_meta); + /* Export mouse */ luaA_openlib(L, "mouse", awesome_mouse_methods, awesome_mouse_meta); diff --git a/lua.h b/lua.h index bf4cbd385..837c4956e 100644 --- a/lua.h +++ b/lua.h @@ -220,6 +220,28 @@ luaA_dofunction(lua_State *L, luaA_function f, int nargs, int nret) return false; } +int luaA_otable_index(lua_State *); + +/** Create a new object table with a metatable. + * This is useful to compare table with objects (udata) as keys. + * \param L The Lua stack. + * \return The number of elements pushed on stack. + */ +static inline int +luaA_otable_new(lua_State *L) +{ + /* Our object */ + lua_newtable(L); + /* The meta table */ + lua_newtable(L); + lua_pushcfunction(L, luaA_otable_index); + /* Register index into the metatable */ + lua_setfield(L, -2, "__index"); + /* Set the meta table */ + lua_setmetatable(L, -2); + return 1; +} + void luaA_init(void); void luaA_parserc(const char *); void luaA_pushpointer(lua_State *, void *, awesome_type_t);