#include "lua_type.h"
#include <lua5.1/lauxlib.h>
void lua_type_register (lua_State *L, const struct lua_type *type, const struct lua_method methods[])
{
const struct lua_method *method;
// create the metatable
luaL_newmetatable(L, type->name);
// set the metatable __index to itself
lua_pushvalue(L, -1);
lua_setfield(L, -1, "__index");
// add the methods to the metatable
for (method = methods; method->func; method++) {
lua_pushcfunction(L, method->func);
lua_setfield(L, -2, method->name);
}
}
void* lua_type_create (lua_State *L, const struct lua_type *type, size_t size)
{
// create the new userdata on the stack
void *ud = lua_newuserdata(L, size);
// get the type and set it
luaL_getmetatable(L, type->name);
lua_setmetatable(L, -2);
// ok
return ud;
}
void* lua_type_register_global (lua_State *L, const struct lua_type *type, const struct lua_method methods[],
const char *global_name, size_t size)
{
// allocate the global object
void *obj = lua_newuserdata(L, size);
// create the type metatable
lua_type_register(L, type, methods);
// set the userdata's metatable
lua_setmetatable(L, -2);
// store it as a global
lua_setglobal(L, global_name);
// ok
return obj;
}
void* lua_type_get (lua_State *L, const struct lua_type *type, int index)
{
void *ud;
// validate the userdata arg
// XXX: the luaL_checkudata actually raises an error itself
if ((ud = luaL_checkudata(L, index, type->name)) == NULL) {
luaL_error(L, "bad type argument: `%s` expected", type->name); return NULL;
} else {
// ok
return ud;
}
}