static int w__release(lua_State *L) { Proxy *p = (Proxy *) lua_touserdata(L, 1); Object *object = p->object; if (object != nullptr) { p->object = nullptr; object->release(); // Fetch the registry table of instantiated objects. luax_getregistry(L, REGISTRY_OBJECTS); if (lua_istable(L, -1)) { // loveobjects[object] = nil lua_pushlightuserdata(L, object); lua_pushnil(L); lua_settable(L, -3); } lua_pop(L, 1); } luax_pushboolean(L, object != nullptr); return 1; }
void luax_pushtype(lua_State *L, love::Type &type, love::Object *object) { if (object == nullptr) { lua_pushnil(L); return; } // Fetch the registry table of instantiated objects. luax_getregistry(L, REGISTRY_OBJECTS); // The table might not exist - it should be insisted in luax_register_type. if (!lua_istable(L, -1)) { lua_pop(L, 1); return luax_rawnewtype(L, type, object); } // Get the value of loveobjects[object] on the stack. lua_pushlightuserdata(L, object); lua_gettable(L, -2); // If the Proxy userdata isn't in the instantiated types table yet, add it. if (lua_type(L, -1) != LUA_TUSERDATA) { lua_pop(L, 1); luax_rawnewtype(L, type, object); lua_pushlightuserdata(L, object); lua_pushvalue(L, -2); // loveobjects[object] = Proxy. lua_settable(L, -4); } // Remove the loveobjects table from the stack. lua_remove(L, -2); // Keep the Proxy userdata on the stack. }
int luax_register_module(lua_State *L, const WrappedModule &m) { // Put a reference to the C++ module in Lua. luax_getregistry(L, REGISTRY_MODULES); Proxy *p = (Proxy *)lua_newuserdata(L, sizeof(Proxy)); p->own = true; p->data = m.module; p->flags = m.flags; luaL_newmetatable(L, m.module->getName()); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, w__gc); lua_setfield(L, -2, "__gc"); lua_setmetatable(L, -2); lua_setfield(L, -2, m.name); // _modules[name] = proxy lua_pop(L, 1); // Gets the love table. luax_insistglobal(L, "love"); // Create new table for module. lua_newtable(L); // Register all the functions. luaL_register(L, 0, m.functions); // Register types. if (m.types != 0) for (const lua_CFunction *t = m.types; *t != 0; t++) (*t)(L); lua_pushvalue(L, -1); lua_setfield(L, -3, m.name); // love.graphics = table lua_remove(L, -2); // love return 1; }
int luax_register_type(lua_State *L, love::Type *type, ...) { type->init(); // Get the place for storing and re-using instantiated love types. luax_getregistry(L, REGISTRY_OBJECTS); // Create registry._loveobjects if it doesn't exist yet. if (!lua_istable(L, -1)) { lua_newtable(L); lua_replace(L, -2); // Create a metatable. lua_newtable(L); // metatable.__mode = "v". Weak userdata values. lua_pushliteral(L, "v"); lua_setfield(L, -2, "__mode"); // setmetatable(newtable, metatable) lua_setmetatable(L, -2); // registry._loveobjects = newtable lua_setfield(L, LUA_REGISTRYINDEX, "_loveobjects"); } else lua_pop(L, 1); luaL_newmetatable(L, type->getName()); // m.__index = m lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); // setup gc lua_pushcfunction(L, w__gc); lua_setfield(L, -2, "__gc"); // Add equality lua_pushcfunction(L, w__eq); lua_setfield(L, -2, "__eq"); // Add tostring function. lua_pushstring(L, type->getName()); lua_pushcclosure(L, w__tostring, 1); lua_setfield(L, -2, "__tostring"); // Add type lua_pushstring(L, type->getName()); lua_pushcclosure(L, w__type, 1); lua_setfield(L, -2, "type"); // Add typeOf lua_pushcfunction(L, w__typeOf); lua_setfield(L, -2, "typeOf"); // Add release lua_pushcfunction(L, w__release); lua_setfield(L, -2, "release"); va_list fs; va_start(fs, type); for (const luaL_Reg *f = va_arg(fs, const luaL_Reg *); f; f = va_arg(fs, const luaL_Reg *)) luax_setfuncs(L, f); va_end(fs); lua_pop(L, 1); // Pops metatable. return 0; }
int luax_register_type(lua_State *L, const char *tname, const luaL_Reg *f) { // Verify that this type name has a matching Type ID and type name mapping. love::Type ltype; if (!love::getType(tname, ltype)) printf("Missing type entry for type name: %s\n", tname); // Get the place for storing and re-using instantiated love types. luax_getregistry(L, REGISTRY_TYPES); // Create registry._lovetypes if it doesn't exist yet. if (!lua_istable(L, -1)) { lua_newtable(L); lua_replace(L, -2); // Create a metatable. lua_newtable(L); // metatable.__mode = "v". Weak userdata values. lua_pushliteral(L, "v"); lua_setfield(L, -2, "__mode"); // setmetatable(newtable, metatable) lua_setmetatable(L, -2); // registry._lovetypes = newtable lua_setfield(L, LUA_REGISTRYINDEX, "_lovetypes"); } else lua_pop(L, 1); luaL_newmetatable(L, tname); // m.__index = m lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); // setup gc lua_pushcfunction(L, w__gc); lua_setfield(L, -2, "__gc"); // Add equality lua_pushcfunction(L, w__eq); lua_setfield(L, -2, "__eq"); // Add tostring function. lua_pushstring(L, tname); lua_pushcclosure(L, w__tostring, 1); lua_setfield(L, -2, "__tostring"); // Add tostring to as type() as well. lua_pushstring(L, tname); lua_pushcclosure(L, w__tostring, 1); lua_setfield(L, -2, "type"); // Add typeOf lua_pushcfunction(L, w__typeOf); lua_setfield(L, -2, "typeOf"); if (f != 0) luax_setfuncs(L, f); lua_pop(L, 1); // Pops metatable. return 0; }