diff --git a/common/map/map_file_format.cpp b/common/map/map_file_format.cpp index ac1b79e..879d14e 100644 --- a/common/map/map_file_format.cpp +++ b/common/map/map_file_format.cpp @@ -21,7 +21,9 @@ */ #include "map_file_format.hpp" -void DummyFormat::Load(Region** const ptr, int x, int y) { +#include + +void DummyFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) { //TODO } @@ -44,4 +46,34 @@ void CompactFormat::Load(Region** const ptr, int x, int y) { void CompactFormat::Save(Region* const ptr) { //TODO } -*/ \ No newline at end of file +*/ +void LuaFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) { + //something to load into + (*ptr) = new Region(width, height, depth, x, y); + + //API hook + lua_getglobal(state, "Region"); + lua_getfield(state, -1, "Load"); + lua_pushlightuserdata(state, *ptr); + lua_pushstring(state, saveDir.c_str()); + if (lua_pcall(state, 2, 1, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) )); + } + if (lua_toboolean(state, -1) == false) { + delete (*ptr); + (*ptr) = nullptr; + } + lua_pop(state, 2); +} + +void LuaFormat::Save(Region* const ptr) { + //API hook + lua_getglobal(state, "Region"); + lua_getfield(state, -1, "Save"); + lua_pushlightuserdata(state, ptr); + lua_pushstring(state, saveDir.c_str()); + if (lua_pcall(state, 2, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) )); + } + lua_pop(state, 1); +} \ No newline at end of file diff --git a/common/map/map_file_format.hpp b/common/map/map_file_format.hpp index 576dc50..50345e5 100644 --- a/common/map/map_file_format.hpp +++ b/common/map/map_file_format.hpp @@ -24,28 +24,56 @@ #include "region.hpp" +#include "lua/lua.hpp" + +#include + class DummyFormat { public: - void Load(Region** const, int x, int y); + void Load(Region** const, int width, int height, int depth, int x, int y); void Save(Region* const); + + std::string SetSaveDir(std::string s) { return saveDir = s; } + std::string GetSaveDir() { return saveDir; } private: - // + std::string saveDir; }; /* class VerboseFormat { public: - void Load(Region** const, int x, int y); + void Load(Region** const, int width, int height, int depth, int x, int y); void Save(Region* const); + + std::string SetSaveDir(std::string s) { return saveDir = s; } + std::string GetSaveDir() { return saveDir; } private: - // + std::string saveDir; }; class CompactFormat { public: - void Load(Region** const, int x, int y); + void Load(Region** const, int width, int height, int depth, int x, int y); void Save(Region* const); + + std::string SetSaveDir(std::string s) { return saveDir = s; } + std::string GetSaveDir() { return saveDir; } private: - // + std::string saveDir; }; */ +class LuaFormat { +public: + void Load(Region** const, int width, int height, int depth, int x, int y); + void Save(Region* const); + + std::string SetSaveDir(std::string s) { return saveDir = s; } + std::string GetSaveDir() { return saveDir; } + + lua_State* SetLuaState(lua_State* L) { return state = L; } + lua_State* GetLuaState() { return state; } +private: + std::string saveDir; + lua_State* state = nullptr; +}; + #endif diff --git a/common/map/map_generator.cpp b/common/map/map_generator.cpp index 8f7a9ad..eef4b16 100644 --- a/common/map/map_generator.cpp +++ b/common/map/map_generator.cpp @@ -21,6 +21,8 @@ */ #include "map_generator.hpp" +#include + void BlankGenerator::Create(Region** const ptr, int width, int height, int depth, int x, int y) { (*ptr) = new Region(width, height, depth, x, y); } @@ -38,14 +40,29 @@ void PerlinGenerator::Unload(Region* const ptr) { } */ void LuaGenerator::Create(Region** const ptr, int width, int height, int depth, int x, int y) { + //something to work on (*ptr) = new Region(width, height, depth, x, y); - //generate the lua-driven maps - lua_getglobal(state, "CreateRegion"); + //API hook + lua_getglobal(state, "Region"); + lua_getfield(state, -1, "Create"); lua_pushlightuserdata(state, *ptr); - lua_pcall(state, 1, 0, 0); + if (lua_pcall(state, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) )); + } + lua_pop(state, 1); } void LuaGenerator::Unload(Region* const ptr) { + //API hook + lua_getglobal(state, "Region"); + lua_getfield(state, -1, "Unload"); + lua_pushlightuserdata(state, ptr); + if (lua_pcall(state, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) )); + } + lua_pop(state, 1); + + //clean up the memory delete ptr; } diff --git a/common/map/region_pager.hpp b/common/map/region_pager.hpp index 46fc612..bbf1d42 100644 --- a/common/map/region_pager.hpp +++ b/common/map/region_pager.hpp @@ -43,6 +43,7 @@ public: virtual Region* SaveRegion(int x, int y) = 0; virtual Region* CreateRegion(int x, int y) = 0; virtual void UnloadRegion(int x, int y) = 0; + virtual void UnloadAll() = 0; //accessors //NOTE: don't change the sizes mid-program, it will cause issues @@ -69,7 +70,9 @@ public: { //EMPTY } - ~RegionPager() = default; + ~RegionPager() { + UnloadAll(); + } Region* LoadRegion(int x, int y) { //snap the coords @@ -78,7 +81,7 @@ public: //load the region if possible Region* ptr = nullptr; - format.Load(&ptr, x, y); + format.Load(&ptr, regionWidth, regionHeight, regionDepth, x, y); if (ptr) { regionList.push_back(ptr); return ptr; @@ -130,6 +133,12 @@ public: ++it; } } + void UnloadAll() { + for (auto& it : regionList) { + generator.Unload(it); + } + regionList.clear(); + } //accessors MapGenerator* GetGenerator() { return &generator; } diff --git a/common/script/region_api.cpp b/common/script/region_api.cpp index 2f5a3c1..48380d3 100644 --- a/common/script/region_api.cpp +++ b/common/script/region_api.cpp @@ -24,24 +24,34 @@ #include "region.hpp" static int setTile(lua_State* L) { -// Region* ptr = lua_touserdata(L, 1); -// ptr->SetTile + Region* ptr = (Region*)lua_touserdata(L, 1); + ptr->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5)); + return 0; } static int getTile(lua_State* L) { - //TODO + Region* ptr = (Region*)lua_touserdata(L, 1); + int ret = ptr->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1); + lua_pushnumber(L, ret); + return 1; } static int getWidth(lua_State* L) { - //TODO + Region* ptr = (Region*)lua_touserdata(L, 1); + lua_pushinteger(L, ptr->GetWidth()); + return 1; } static int getHeight(lua_State* L) { - //TODO + Region* ptr = (Region*)lua_touserdata(L, 1); + lua_pushinteger(L, ptr->GetHeight()); + return 1; } static int getDepth(lua_State* L) { - //TODO + Region* ptr = (Region*)lua_touserdata(L, 1); + lua_pushinteger(L, ptr->GetDepth()); + return 1; } static int getX(lua_State* L) { @@ -56,6 +66,10 @@ static int getY(lua_State* L) { return 1; } +static int dummy(lua_State* L) { + return 0; +} + static const luaL_Reg regionlib[] = { {"SetTile",setTile}, {"GetTile",getTile}, @@ -64,6 +78,10 @@ static const luaL_Reg regionlib[] = { {"GetDepth",getDepth}, {"GetX",getX}, {"GetY",getY}, + {"Create", dummy}, + {"Unload", dummy}, + {"Load", dummy}, + {"Save", dummy}, {nullptr, nullptr} }; diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index 448b25f..4daf1f4 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -1,5 +1,19 @@ print("Lua script check OK (./rsc)") -function CreateRegion(r) - print(Region.GetX(r), Region.GetY(r)) -end \ No newline at end of file +function Region.Create(r) + print("Region:Create(r", Region.GetX(r), Region.GetY(r), ")") +end + +function Region.Unload(r) + print("Region:Unload(r", Region.GetX(r), Region.GetY(r), ")") +end + +--return true if file loaded, otherwise return false +function Region.Load(r, saveDir) + print("Region:Load(r,", saveDir, Region.GetX(r), Region.GetY(r), ")") + return false +end + +function Region.Save(r, saveDir) + print("Region:Save(r,", saveDir, Region.GetX(r), Region.GetY(r), ")") +end diff --git a/server/server_application.cpp b/server/server_application.cpp index d39223b..9466ce8 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -101,6 +101,8 @@ void ServerApplication::Init(int argc, char** argv) { mapPager.SetRegionHeight(REGION_HEIGHT); mapPager.SetRegionDepth(REGION_DEPTH); mapPager.GetGenerator()->SetLuaState(luaState); + mapPager.GetFormat()->SetLuaState(luaState); + mapPager.GetFormat()->SetSaveDir("save/mapname/"); //TODO: pass args to the generator & format as needed //NOTE: I might need to rearrange the init process so that lua & SQL can interact // with the map system as needed. @@ -112,8 +114,7 @@ void ServerApplication::Init(int argc, char** argv) { cout << "Startup completed successfully" << endl; //debugging - mapPager.GetRegion(0,0); - mapPager.GetRegion(128,256); + // } void ServerApplication::Loop() { @@ -136,6 +137,7 @@ void ServerApplication::Loop() { void ServerApplication::Quit() { cout << "Shutting down" << endl; //empty the members + mapPager.UnloadAll(); //TODO: player manager //TODO: client manager diff --git a/server/server_application.hpp b/server/server_application.hpp index 4d969a0..d3d30fa 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -85,7 +85,7 @@ private: void PumpPacket(NetworkPacket); //maps - RegionPager mapPager; + RegionPager mapPager; //networking UDPNetworkUtility network;