diff --git a/common/luaclass.c b/common/luaclass.c index 2b16c7ba..329e38e9 100644 --- a/common/luaclass.c +++ b/common/luaclass.c @@ -32,6 +32,43 @@ DO_ARRAY(lua_class_id_t, lua_class_id, DO_NOTHING) static lua_class_id_array_t luaA_classes; +/* This has to be initialized to the highest natural type of Lua */ +#define LUA_HIGHEST_TYPE LUA_TTHREAD + +/** Enhanced version of lua_type that recognizes setup Lua classes. + * \param L The Lua VM state. + * \param idx The index of the object on the stack. + */ +int +luaA_type(lua_State *L, int idx) +{ + int type = lua_type(L, idx); + + if(type == LUA_TUSERDATA) + foreach(class, luaA_classes) + if(luaA_toudata(L, idx, class->class->name)) + return class->id; + + return type; +} + +/** Enhanced version of lua_typename that recognizes setup Lua classes. + * \param L The Lua VM state. + * \param idx The index of the object on the stack. + */ +const char * +luaA_typename(lua_State *L, int idx) +{ + int type = luaA_type(L, idx); + + if(type > LUA_HIGHEST_TYPE) + foreach(class, luaA_classes) + if(class->id == type) + return class->class->name; + + return lua_typename(L, type); +} + void luaA_openlib(lua_State *L, const char *name, const struct luaL_reg methods[], @@ -55,7 +92,7 @@ luaA_class_setup(lua_State *L, lua_class_t *class, const struct luaL_reg methods[], const struct luaL_reg meta[]) { - static int class_type_counter = LUA_TTHREAD + 1; + static int class_type_counter = LUA_HIGHEST_TYPE; luaA_openlib(L, name, methods, meta); diff --git a/common/luaclass.h b/common/luaclass.h index f7dd1e1d..f04f48e7 100644 --- a/common/luaclass.h +++ b/common/luaclass.h @@ -46,6 +46,9 @@ typedef struct lua_class_allocator_t allocator; } lua_class_t; +int luaA_type(lua_State *, int); +const char * luaA_typename(lua_State *, int); + void luaA_class_add_signal(lua_State *, lua_class_t *, const char *, int); void luaA_class_remove_signal(lua_State *, lua_class_t *, const char *, int); void luaA_class_emit_signal(lua_State *, lua_class_t *, const char *, int); diff --git a/common/lualib.h b/common/lualib.h index 2db68b96..a09badbb 100644 --- a/common/lualib.h +++ b/common/lualib.h @@ -63,6 +63,27 @@ luaA_dofunction(lua_State *L, int nargs, int nret) return true; } +/** Convert a object to a udata if possible. + * \param L The Lua VM state. + * \param ud The index. + * \param tname The type name. + * \return A pointer to the object, NULL otherwise. + */ +static inline void * +luaA_toudata(lua_State *L, int ud, const char *tname) +{ + void *p = lua_touserdata(L, ud); + if(p) /* value is a userdata? */ + if(lua_getmetatable(L, ud)) /* does it have a metatable? */ + { + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ + if(!lua_rawequal(L, -1, -2)) /* does it have the correct mt? */ + p = NULL; + lua_pop(L, 2); /* remove both metatables */ + } + return p; +} + #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/luaa.c b/luaa.c index 25336a11..f26f69d2 100644 --- a/luaa.c +++ b/luaa.c @@ -246,23 +246,7 @@ static int luaAe_type(lua_State *L) { luaL_checkany(L, 1); -#define CHECK_TYPE(type) \ - do { \ - if(luaA_toudata(L, 1, #type)) \ - { \ - lua_pushliteral(L, #type); \ - return 1; \ - } \ - } while(0) -CHECK_TYPE(wibox); -CHECK_TYPE(client); -CHECK_TYPE(image); -CHECK_TYPE(key); -CHECK_TYPE(button); -CHECK_TYPE(tag); -CHECK_TYPE(widget); -#undef CHECK_TYPE - lua_pushstring(L, luaL_typename(L, 1)); + lua_pushstring(L, luaA_typename(L, 1)); return 1; } diff --git a/luaa.h b/luaa.h index 5f0975f0..a0475979 100644 --- a/luaa.h +++ b/luaa.h @@ -90,27 +90,6 @@ luaA_dumpstack(lua_State *L) fprintf(stderr, "------- Lua stack dump end ------\n"); } -/** Convert a object to a udata if possible. - * \param L The Lua VM state. - * \param ud The index. - * \param tname The type name. - * \return A pointer to the object, NULL otherwise. - */ -static inline void * -luaA_toudata(lua_State *L, int ud, const char *tname) -{ - void *p = lua_touserdata(L, ud); - if(p) /* value is a userdata? */ - if(lua_getmetatable(L, ud)) /* does it have a metatable? */ - { - lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ - if(!lua_rawequal(L, -1, -2)) /* does it have the correct mt? */ - p = NULL; - lua_pop(L, 2); /* remove both metatables */ - } - return p; -} - static inline bool luaA_checkboolean(lua_State *L, int n) {