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