luaobject: add type recognition
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
706d545076
commit
284338532b
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
18
luaa.c
18
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;
|
||||
}
|
||||
|
||||
|
|
21
luaa.h
21
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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue