diff --git a/common/map/region_pager_lua.cpp b/common/map/region_pager_lua.cpp index d8fb538..4eeea2b 100644 --- a/common/map/region_pager_lua.cpp +++ b/common/map/region_pager_lua.cpp @@ -23,6 +23,17 @@ #include +RegionPagerLua::~RegionPagerLua() { + //unload all regions + UnloadAll(); + //clear any stored functions + luaL_unref(lua, LUA_REGISTRYINDEX, loadRef); + luaL_unref(lua, LUA_REGISTRYINDEX, saveRef); + luaL_unref(lua, LUA_REGISTRYINDEX, createRef); + luaL_unref(lua, LUA_REGISTRYINDEX, unloadRef); +} + +//return the loaded region, or nullptr on failure Region* RegionPagerLua::LoadRegion(int x, int y) { //get the pager's function from the registry lua_rawgeti(lua, LUA_REGISTRYINDEX, loadRef); @@ -54,6 +65,7 @@ Region* RegionPagerLua::LoadRegion(int x, int y) { } } +//return the saved region, or nullptr on failure Region* RegionPagerLua::SaveRegion(int x, int y) { //get the pager's function from the registry lua_rawgeti(lua, LUA_REGISTRYINDEX, saveRef); @@ -88,6 +100,7 @@ Region* RegionPagerLua::SaveRegion(int x, int y) { } } +//return the created region, or nullptr on failure Region* RegionPagerLua::CreateRegion(int x, int y) { if (FindRegion(x, y)) { throw(std::logic_error("Cannot overwrite an existing region")); @@ -116,6 +129,7 @@ Region* RegionPagerLua::CreateRegion(int x, int y) { return ®ionList.front(); } +//no return void RegionPagerLua::UnloadRegion(int x, int y) { //get the pager's function from the registry lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef); diff --git a/common/map/region_pager_lua.hpp b/common/map/region_pager_lua.hpp index d23260f..656074c 100644 --- a/common/map/region_pager_lua.hpp +++ b/common/map/region_pager_lua.hpp @@ -35,7 +35,7 @@ class RegionPagerLua : public RegionPagerBase { public: RegionPagerLua() = default; - ~RegionPagerLua() = default; + ~RegionPagerLua(); //region manipulation Region* LoadRegion(int x, int y) override; diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index 15526d4..71ebf50 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -11,23 +11,20 @@ local function dumpTable(t) end end -dumpTable(mapMaker) -dumpTable(mapSaver) -dumpTable(roomSystem) -dumpTable(roomSystem.Room) -dumpTable(roomSystem.RoomManager) - --create the overworld, set it's generator, loader & saver -local overworld = roomSystem.RoomManager.CreateRoom("overworld", "overworld.bmp") -roomSystem.Room.SetOnLoad(overworld, 1123) -roomSystem.Room.SetOnUnload(overworld, 458) +--[[ +local t = { + "overworld.bmp", --tileset name + mapSaver.load, --load function + mapSaver.save, --save function + mapMaker.debugIsland, --create function + mapSaver.save --unload function +}]] -if roomSystem.Room.GetOnLoad(overworld) == 1123 then - print("onload retreival works") -end +dumpTable(roomSystem) +dumpTable(roomSystem.RoomManager) +dumpTable(roomSystem.Room) -if roomSystem.Room.GetOnUnload(overworld) == 458 then - print("onunload retreival works") -end +local overworld = roomSystem.RoomManager.CreateRoom("overworld") print("Finished the lua script") diff --git a/server/rooms/room_api.cpp b/server/rooms/room_api.cpp index e443bf8..6edcc38 100644 --- a/server/rooms/room_api.cpp +++ b/server/rooms/room_api.cpp @@ -53,46 +53,28 @@ static int getPager(lua_State* L) { return 1; } -//TODO: GetEntityList? +static int initialize(lua_State* L) { + //set the members of the given room + RoomData* room = static_cast(lua_touserdata(L, 1)); + room->SetRoomName(lua_tostring(L, 2)); -static int setLoadReference(lua_State* L) { - RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); - luaL_unref(L, LUA_REGISTRYINDEX, room->GetLoadReference()); - room->SetLoadReference(luaL_ref(L, LUA_REGISTRYINDEX)); + //set the refs of these parameters (backwards, since it pops from the top of the stack) + room->GetPager()->SetUnloadReference(luaL_ref(L, LUA_REGISTRYINDEX)); + room->GetPager()->SetCreateReference(luaL_ref(L, LUA_REGISTRYINDEX)); + room->GetPager()->SetSaveReference(luaL_ref(L, LUA_REGISTRYINDEX)); + room->GetPager()->SetLoadReference(luaL_ref(L, LUA_REGISTRYINDEX)); + + //more parameters can be added here later return 0; } -static int getLoadReference(lua_State* L) { - RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); - lua_pushinteger(L, room->GetLoadReference()); - lua_gettable(L, LUA_REGISTRYINDEX); - return 1; -} - -static int setUnloadReference(lua_State* L) { - RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); - luaL_unref(L, LUA_REGISTRYINDEX, room->GetUnloadReference()); - room->SetUnloadReference(luaL_ref(L, LUA_REGISTRYINDEX)); - return 0; -} - -static int getUnloadReference(lua_State* L) { - RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); - lua_pushinteger(L, room->GetUnloadReference()); - lua_gettable(L, LUA_REGISTRYINDEX); - return 1; -} - static const luaL_Reg roomLib[] = { {"GetPager",getPager}, {"SetRoomName", setRoomName}, {"GetRoomName", getRoomName}, {"SetTileset", setTilesetName}, {"GetTileset", getTilesetName}, - {"SetOnLoad", setLoadReference}, - {"GetOnLoad", getLoadReference}, - {"SetOnUnload", setUnloadReference}, - {"GetOnUnload", getUnloadReference}, + {"Initialize", initialize}, {nullptr, nullptr} }; diff --git a/server/rooms/room_data.cpp b/server/rooms/room_data.cpp index 7fb9061..ae5f1b8 100644 --- a/server/rooms/room_data.cpp +++ b/server/rooms/room_data.cpp @@ -43,20 +43,4 @@ RegionPagerLua* RoomData::GetPager() { std::list* RoomData::GetEntityList() { return &entityList; -} - -int RoomData::SetLoadReference(int i) { - return loadRef = i; -} - -int RoomData::GetLoadReference() { - return loadRef; -} - -int RoomData::SetUnloadReference(int i) { - return unloadRef = i; -} - -int RoomData::GetUnloadReference() { - return unloadRef; } \ No newline at end of file diff --git a/server/rooms/room_data.hpp b/server/rooms/room_data.hpp index 78612fe..069e84c 100644 --- a/server/rooms/room_data.hpp +++ b/server/rooms/room_data.hpp @@ -49,12 +49,6 @@ public: RegionPagerLua* GetPager(); std::list* GetEntityList(); - //hooks - int SetLoadReference(int); - int GetLoadReference(); - int SetUnloadReference(int); - int GetUnloadReference(); - private: friend class RoomManager; @@ -64,11 +58,6 @@ private: RegionPagerLua pager; std::list entityList; - - //lua references - //TODO: use RoomData's lua references for load and unload functions - int loadRef = LUA_NOREF; - int unloadRef = LUA_NOREF; }; #endif diff --git a/server/rooms/room_manager.cpp b/server/rooms/room_manager.cpp index 26d5042..226a16b 100644 --- a/server/rooms/room_manager.cpp +++ b/server/rooms/room_manager.cpp @@ -23,31 +23,27 @@ #include "room_api.hpp" +#include #include //------------------------- //public access methods //------------------------- -int RoomManager::Create(std::string roomName, std::string tilesetName) { +int RoomManager::Create(std::string roomName) { + std::cout << "Create-1" << std::endl; //create the room RoomData* newRoom = &elementMap[counter]; //implicitly constructs the element + std::cout << "Create-2" << std::endl; + newRoom->SetRoomName(roomName); + std::cout << "Create-3" << std::endl; newRoom->pager.SetLuaState(lua); + std::cout << "Create-4" << std::endl; //finish the routine return counter++; } -int RoomManager::Load(std::string roomName, std::string tilesetName) { - //TODO: RoomManager::Load() - return -1; -} - -int RoomManager::Save(int uid) { - //TODO: RoomManager::Save(uid) - return -1; -} - void RoomManager::Unload(int uid) { //find the room std::map::iterator it = elementMap.find(uid); @@ -59,12 +55,6 @@ void RoomManager::Unload(int uid) { elementMap.erase(uid); } -void RoomManager::Delete(int uid) { - //TODO: RoomManager::Delete(int uid) - //NOTE: aliased to RoomManager::Unload(int uid) - Unload(uid); -} - void RoomManager::UnloadAll() { elementMap.clear(); } diff --git a/server/rooms/room_manager.hpp b/server/rooms/room_manager.hpp index 228b692..2ced715 100644 --- a/server/rooms/room_manager.hpp +++ b/server/rooms/room_manager.hpp @@ -34,15 +34,12 @@ class RoomManager: public Singleton, - public ManagerInterface + public ManagerInterface { public: //common public methods - int Create(std::string, std::string) override; - int Load(std::string, std::string) override; - int Save(int uid) override; + int Create(std::string) override; void Unload(int uid) override; - void Delete(int uid) override; void UnloadAll() override; void UnloadIf(std::function)> fn) override; @@ -63,6 +60,11 @@ private: RoomManager() = default; ~RoomManager() = default; + //EMPTY + int Load(std::string) override { return -1; } + int Save(int uid) override { return -1; } + void Delete(int uid) override {} + lua_State* lua = nullptr; int counter = 0; }; diff --git a/server/rooms/room_manager_api.cpp b/server/rooms/room_manager_api.cpp index 880022f..fc079a6 100644 --- a/server/rooms/room_manager_api.cpp +++ b/server/rooms/room_manager_api.cpp @@ -21,18 +21,71 @@ */ #include "room_manager_api.hpp" +#include "room_system_api.hpp" +#include "room_api.hpp" + #include "room_manager.hpp" +#include +#include +#include + int createRoom(lua_State* L) { + std::cout << "DEBUG: createRoom-1" << std::endl; + //create & get the room RoomManager& roomMgr = RoomManager::GetSingleton(); - int uid = roomMgr.Create("",""); //TODO: All new managers need their internals fleshed out + std::cout << "DEBUG: createRoom-2" << std::endl; + int uid = roomMgr.Create(lua_tostring(L, 1)); + std::cout << "DEBUG: createRoom-3" << std::endl; RoomData* room = roomMgr.Get(uid); + std::cout << "DEBUG: createRoom-4" << std::endl; + //setup the room - //TODO: room parameters only set via lua, fix this - room->SetRoomName(lua_tostring(L, 1)); - room->SetTilesetName(lua_tostring(L, 2)); + if (lua_gettop(L) > 1) { + //ensure there are the correct number of parameters on the stack, including nil values + lua_settop(L, 6); //5 parameters, + RoomName + + //get Room::Initialize() onto the top of the stack + luaL_requiref(L, TORTUGA_ROOM_SYSTEM_API, openRoomSystemAPI, false); + + lua_pushstring(L, TORTUGA_ROOM_API); + lua_gettable(L, -2); //RoomSystem[TORTUGA_ROOM_API] + + lua_pushstring(L, "Initialize"); + lua_gettable(L, -3); //Room[Initialize] + + //push the room onto the stack + lua_pushlightuserdata(L, static_cast(room)); + + //push (copies of) the parameters onto the stack + if (lua_type(L, 2) == LUA_TTABLE) { + //Unroll the table of parameters + for (int i = 1; i <= 5; i++) { //should be 5 members, including nil values + lua_rawgeti(L, 2, i); + } + } + else { + //copy the parameters + for (int i = 2; i <= 6; i++) { //there are 5 parameters, including nil values, due to the call to lua_settop above + lua_pushvalue(L, i); + } + } + + //by this point, the stack should look be ready to call Room::Initialize() with 6 parameters, including the room + int result = lua_pcall(L, 6, 0, 0); + + if (result != LUA_OK) { + //something went wrong + std::ostringstream msg; + msg << "Failed to initialize a room's parameters in RoomManagerAPI::create(): " << lua_tostring(L, -1); + msg << "; Room name: " << lua_tostring(L, 1); + throw(std::runtime_error(msg.str())); + } + + //wow, that was hard + } //return room, uid lua_pushlightuserdata(L, static_cast(room)); @@ -42,21 +95,39 @@ int createRoom(lua_State* L) { } int unloadRoom(lua_State* L) { - //TODO: check authorization for room deletion RoomManager& roomMgr = RoomManager::GetSingleton(); + + //NOTE: the pager calls the unload function itself roomMgr.Unload(lua_tointeger(L, 1)); + return 0; } -//TODO: lua API RoomManager.GetRoom(uid) +int getRoom(lua_State* L) { + RoomManager& roomMgr = RoomManager::GetSingleton(); + + RoomData* room = roomMgr.Get(lua_tointeger(L, 1)); + + if (room) { + lua_pushlightuserdata(L, static_cast(room)); + } + else { + lua_pushnil(L); + } + + return 1; +} static const luaL_Reg roomManagerLib[] = { {"CreateRoom", createRoom}, {"UnloadRoom", unloadRoom}, + {"GetRoom", getRoom}, {nullptr, nullptr} }; LUAMOD_API int openRoomManagerAPI(lua_State* L) { + std::cout << "DEBUG: openRoomManagerAPI" << std::endl; + luaL_newlib(L, roomManagerLib); return 1; }