diff --git a/common/map/region_pager_lua.cpp b/common/map/region_pager_lua.cpp index e74c59a..278bdb4 100644 --- a/common/map/region_pager_lua.cpp +++ b/common/map/region_pager_lua.cpp @@ -21,48 +21,75 @@ */ #include "region_pager_lua.hpp" -#include "region_api.hpp" #include "utility.hpp" #include +//TODO: Could I push the pager to the API functions too? + Region* RegionPagerLua::LoadRegion(int x, int y) { - //load the region if possible + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, loadRef); + + //check if this function is available + if (lua_isnil(lua, -1)) { + lua_pop(lua, 1); + return nullptr; + } //something to work on Region tmpRegion(x, y); - - //API hook - lua_getglobal(lua, TORTUGA_REGION_NAME); - lua_getfield(lua, -1, "Load"); lua_pushlightuserdata(lua, &tmpRegion); + + //call the funtion, 1 arg, 1 return if (lua_pcall(lua, 1, 1, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } - //success or failure - if (!lua_toboolean(lua, -1)) { - lua_pop(lua, 2); + + //check the return value, success or failure + if (lua_toboolean(lua, -1)) { + lua_pop(lua, 1); + regionList.push_front(tmpRegion); + return ®ionList.front(); + } + else { + lua_pop(lua, 1); return nullptr; } - lua_pop(lua, 2); - regionList.push_front(tmpRegion); - return ®ionList.front(); } Region* RegionPagerLua::SaveRegion(int x, int y) { - //find & save the region - Region* ptr = FindRegion(x, y); - if (ptr) { - //API hook - lua_getglobal(lua, TORTUGA_REGION_NAME); - lua_getfield(lua, -1, "Save"); - lua_pushlightuserdata(lua, ptr); - if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); - } + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, saveRef); + + //check if this function is available + if (lua_isnil(lua, -1)) { lua_pop(lua, 1); + return nullptr; + } + + //find the specified region + Region* ptr = FindRegion(x, y); + if (!ptr) { + lua_pop(lua, 1); + return nullptr; + } + lua_pushlightuserdata(lua, ptr); + + //call the function, 1 arg, 1 return + if (lua_pcall(lua, 1, 1, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); + } + + //check the return value, success or failure + if (lua_toboolean(lua, -1)) { + lua_pop(lua, 1); + return ptr; + } + else { + lua_pop(lua, 1); + return nullptr; } - return ptr; } Region* RegionPagerLua::CreateRegion(int x, int y) { @@ -70,55 +97,87 @@ Region* RegionPagerLua::CreateRegion(int x, int y) { throw(std::logic_error("Cannot overwrite an existing region")); } + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, createRef); + + //check if this function is available + if (lua_isnil(lua, -1)) { + lua_pop(lua, 1); + return nullptr; + } + //something to work on Region tmpRegion(x, y); - - //API hook - lua_getglobal(lua, TORTUGA_REGION_NAME); - lua_getfield(lua, -1, "Create"); lua_pushlightuserdata(lua, &tmpRegion); - //TODO: parameters + + //call the function, 1 arg, 0 return if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } - lua_pop(lua, 1); + + //return the new region regionList.push_front(tmpRegion); return ®ionList.front(); } void RegionPagerLua::UnloadRegion(int x, int y) { - lua_getglobal(lua, TORTUGA_REGION_NAME); + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef); + //check if this function is available + if (lua_isnil(lua, -1)) { + lua_pop(lua, 1); + return; + } + + //run each region through this lambda regionList.remove_if([&](Region& region) -> bool { if (region.GetX() == x && region.GetY() == y) { - //API hook - lua_getfield(lua, -1, "Unload"); + //push a copy of the function onto the stack with the region + lua_pushvalue(lua, -1); lua_pushlightuserdata(lua, ®ion); + + //call the function, 1 arg, 0 return if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } + //signal to the container return true; } + //signal to the container return false; }); + //pop the base copy of the function lua_pop(lua, 1); } void RegionPagerLua::UnloadAll() { - lua_getglobal(lua, TORTUGA_REGION_NAME); + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef); + + //check if this function is available + if (lua_isnil(lua, -1)) { + lua_pop(lua, 1); + return; + } for (auto& it : regionList) { - //API hook - lua_getfield(lua, -1, "Unload"); + //push a copy of the function onto the stack with the region + lua_pushvalue(lua, -1); lua_pushlightuserdata(lua, &it); + + //call the function, 1 arg, 0 return if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } } + //pop the base copy of the function lua_pop(lua, 1); + + //remove from memory regionList.clear(); } \ No newline at end of file diff --git a/common/map/region_pager_lua.hpp b/common/map/region_pager_lua.hpp index 8543e2d..18a0fb0 100644 --- a/common/map/region_pager_lua.hpp +++ b/common/map/region_pager_lua.hpp @@ -44,8 +44,25 @@ public: //accessors & mutators lua_State* SetLuaState(lua_State* L) { return lua = L; } lua_State* GetLuaState() { return lua; } + + //utilities for the API + int SetLoadReference(int i) { return loadRef = i; } + int SetSaveReference(int i) { return saveRef = i; } + int SetCreateReference(int i) { return createRef = i; } + int SetUnloadReference(int i) { return unloadRef = i; } + + int GetLoadReference() { return loadRef; } + int GetSaveReference() { return saveRef; } + int GetCreateReference() { return createRef; } + int GetUnloadReference() { return unloadRef; } + protected: lua_State* lua = nullptr; + + int loadRef; + int saveRef; + int createRef; + int unloadRef; }; #endif