From 414a0896c9683f1bb71a346aa1c35f0cb6fe3ab5 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 30 Jul 2014 21:10:43 +1000 Subject: [PATCH 01/10] Began merging the jam branch into the development (read more) The list of changes committed: * Removed SimpleRNG * Added Timer (for debugging) * Added BoundingBox * Added floating point snapToBase() * Added error check to Vector2::Normalize() * Updated makefiles, project compiles --- client/makefile | 2 +- common/debugging/makefile | 37 +++++++++ .../simple_rng.hpp => debugging/timer.cpp} | 27 ++----- common/debugging/timer.hpp | 54 +++++++++++++ common/makefile | 1 + common/utilities/bounding_box.hpp | 77 +++++++++++++++++++ common/utilities/utility.cpp | 4 + common/utilities/utility.hpp | 2 + common/utilities/vector2.hpp | 2 + server/makefile | 2 +- 10 files changed, 186 insertions(+), 22 deletions(-) create mode 100644 common/debugging/makefile rename common/{utilities/simple_rng.hpp => debugging/timer.cpp} (70%) create mode 100644 common/debugging/timer.hpp create mode 100644 common/utilities/bounding_box.hpp diff --git a/client/makefile b/client/makefile index 97d8949..f318d52 100644 --- a/client/makefile +++ b/client/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. scenes ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/ui ../common/utilities +INCLUDES+=. scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/ui ../common/utilities LIBS+=client.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/common/debugging/makefile b/common/debugging/makefile new file mode 100644 index 0000000..a4efd0c --- /dev/null +++ b/common/debugging/makefile @@ -0,0 +1,37 @@ +#config +INCLUDES+=. +LIBS+= +CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) + +#source +CXXSRC=$(wildcard *.cpp) + +#objects +OBJDIR=obj +OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) + +#output +OUTDIR=.. +OUT=$(addprefix $(OUTDIR)/,libcommon.a) + +#targets +all: $(OBJ) $(OUT) + ar -crs $(OUT) $(OBJ) + +$(OBJ): | $(OBJDIR) + +$(OUT): | $(OUTDIR) + +$(OBJDIR): + mkdir $(OBJDIR) + +$(OUTDIR): + mkdir $(OUTDIR) + +$(OBJDIR)/%.o: %.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +clean: + $(RM) *.o *.a *.exe + +rebuild: clean all diff --git a/common/utilities/simple_rng.hpp b/common/debugging/timer.cpp similarity index 70% rename from common/utilities/simple_rng.hpp rename to common/debugging/timer.cpp index 52ca91b..be3636a 100644 --- a/common/utilities/simple_rng.hpp +++ b/common/debugging/timer.cpp @@ -19,24 +19,11 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef SIMPLERNG_HPP_ -#define SIMPLERNG_HPP_ +#include "timer.hpp" -//a simple, stateless, random number generator -class SimpleRNG { -public: - SimpleRNG() { SetSeed(8891.0); } - SimpleRNG(double x) { SetSeed(x); } - - double SetSeed(double s) { return seed = s; } - double GetSeed() { return seed; } - - double operator()(double x) { - return (x + seed) * 11235.0 + 81321.0; - }; - -private: - double seed; -}; - -#endif \ No newline at end of file +std::ostream& operator<<(std::ostream& os, Timer& t) { + os << t.GetName() << ": "; + os << std::chrono::duration_cast(t.GetTime()).count(); + os << "ns"; + return os; +} diff --git a/common/debugging/timer.hpp b/common/debugging/timer.hpp new file mode 100644 index 0000000..7f8f38b --- /dev/null +++ b/common/debugging/timer.hpp @@ -0,0 +1,54 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef TIMER_HPP_ +#define TIMER_HPP_ + +#include +#include +#include + +class Timer { +public: + typedef std::chrono::high_resolution_clock Clock; + + Timer() = default; + Timer(std::string s) : name(s), start(Clock::now()) {}; + ~Timer() = default; + + inline void Start() { start = Clock::now(); } + inline void Stop() { time = Clock::now() - start; } + + //accessors and mutators + Clock::duration GetTime() { return time; } + + std::string SetName(std::string s) { return name = s; } + std::string GetName() { return name; } + +private: + std::string name; + Clock::time_point start; + Clock::duration time; +}; + +std::ostream& operator<<(std::ostream& os, Timer& t); + +#endif diff --git a/common/makefile b/common/makefile index b670b7d..bdb1406 100644 --- a/common/makefile +++ b/common/makefile @@ -1,4 +1,5 @@ all: + $(MAKE) -C debugging $(MAKE) -C gameplay $(MAKE) -C graphics $(MAKE) -C map diff --git a/common/utilities/bounding_box.hpp b/common/utilities/bounding_box.hpp new file mode 100644 index 0000000..1d32887 --- /dev/null +++ b/common/utilities/bounding_box.hpp @@ -0,0 +1,77 @@ +/* Copyright: (c) Kayne Ruse 2013, 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef BOUNDINGBOX_HPP_ +#define BOUNDINGBOX_HPP_ + +#include +#include + +class BoundingBox { +public: + //This is explicitly a POD + int x, y; + int w, h; + + BoundingBox() = default; + BoundingBox(int i, int j, int k, int l): x(i), y(j), w(k), h(l) {}; + ~BoundingBox() = default; + BoundingBox& operator=(BoundingBox const&) = default; + + int Size() { + return std::max(w*h,0); + } + + bool CheckOverlap(BoundingBox rhs) { + return !( + x >= rhs.x + rhs.w || + y >= rhs.y + rhs.h || + rhs.x >= x + w || + rhs.y >= y + h); + } + + BoundingBox CalcOverlap(BoundingBox rhs) { + if (!CheckOverlap(rhs)) { + return {0, 0, 0, 0}; + } + BoundingBox ret; + ret.x = std::max(x, rhs.x); + ret.y = std::max(y, rhs.y); + ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x; + ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y; + return ret; + } +}; + +//This is explicitly a POD +static_assert(std::is_pod::value, "BoundingBox is not a POD"); + +#include "vector2.hpp" + +//operators +inline BoundingBox operator+(BoundingBox b, Vector2 v) { + return {b.x + (int)v.x, b.y + (int)v.y, b.w, b.h}; +} +inline BoundingBox operator+(Vector2 v, BoundingBox b) { + return b + v; +} + +#endif diff --git a/common/utilities/utility.cpp b/common/utilities/utility.cpp index a8a7270..bbba99c 100644 --- a/common/utilities/utility.cpp +++ b/common/utilities/utility.cpp @@ -32,6 +32,10 @@ int snapToBase(int base, int x) { return x / base * base; } +double snapToBase(double base, double x) { + return floor(x / base) * base; +} + std::string truncatePath(std::string pathname) { return std::string( std::find_if( diff --git a/common/utilities/utility.hpp b/common/utilities/utility.hpp index 3589c01..3346136 100644 --- a/common/utilities/utility.hpp +++ b/common/utilities/utility.hpp @@ -25,6 +25,8 @@ #include int snapToBase(int base, int x); +double snapToBase(double base, double x); + std::string truncatePath(std::string pathname); //fixing known bugs in g++ diff --git a/common/utilities/vector2.hpp b/common/utilities/vector2.hpp index 2be3d34..57c716c 100644 --- a/common/utilities/vector2.hpp +++ b/common/utilities/vector2.hpp @@ -43,6 +43,8 @@ public: } void Normalize() { double l = Length(); + if (l == 0) + throw(std::domain_error("Divide by zero")); x /= l; y /= l; } diff --git a/server/makefile b/server/makefile index 3d0de76..807cd13 100644 --- a/server/makefile +++ b/server/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. accounts characters combat enemies mapgen mapgen/generators rooms ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities +INCLUDES+=. accounts characters combat enemies mapgen mapgen/generators rooms ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities LIBS+=server.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) From 46f02dcfddd315f2b1869c6e2487e7a1e6aecf80 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 31 Jul 2014 17:14:40 +1000 Subject: [PATCH 02/10] Minor tweak to ConfigUtility --- common/utilities/config_utility.cpp | 20 ++++++++++---------- common/utilities/config_utility.hpp | 12 +++--------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/common/utilities/config_utility.cpp b/common/utilities/config_utility.cpp index 02970b1..7fb174b 100644 --- a/common/utilities/config_utility.cpp +++ b/common/utilities/config_utility.cpp @@ -25,25 +25,25 @@ #include #include -using namespace std; - -void ConfigUtility::Load(string fname) { - ifstream is(fname); +void ConfigUtility::Load(std::string fname) { + std::ifstream is(fname); if (!is.is_open()) { - throw(runtime_error("Failed to open config file")); + throw(std::runtime_error("Failed to open config file")); } - string key, val; + std::string key, val; - for (;;) { //forever + while(true) { //forever //eat whitespace - while(isspace(is.peek())) + while(isspace(is.peek())) { is.ignore(); + } //end of file - if (is.eof()) + if (is.eof()) { break; + } //skip comment lines if (is.peek() == '#') { @@ -64,7 +64,7 @@ void ConfigUtility::Load(string fname) { while(key.size() && isspace(*(key.end()-1))) key.erase(key.end() - 1); while(val.size() && isspace(*(val.end()-1))) val.erase(val.end() - 1); - //allow empty/wiped values + //disallow empty/wiped values if (key.size() == 0) { continue; } diff --git a/common/utilities/config_utility.hpp b/common/utilities/config_utility.hpp index 6e944ef..3ea8448 100644 --- a/common/utilities/config_utility.hpp +++ b/common/utilities/config_utility.hpp @@ -39,15 +39,9 @@ public: bool Boolean(std::string); //shorthand - std::string& operator[](std::string s) { - return String(s); - } - int Int(std::string s) { - return Integer(s); - } - bool Bool(std::string s) { - return Boolean(s); - } + inline std::string& operator[](std::string s) { return String(s); } + inline int Int(std::string s) { return Integer(s); } + inline bool Bool(std::string s) { return Boolean(s); } //OO breaker std::map* GetMap() { From 66815016ba3a913ccb40791d9941ecce65264291 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 31 Jul 2014 17:18:25 +1000 Subject: [PATCH 03/10] Fixed the debugging makefile's output directory --- common/debugging/makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/debugging/makefile b/common/debugging/makefile index a4efd0c..9013447 100644 --- a/common/debugging/makefile +++ b/common/debugging/makefile @@ -11,7 +11,7 @@ OBJDIR=obj OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) #output -OUTDIR=.. +OUTDIR=../.. OUT=$(addprefix $(OUTDIR)/,libcommon.a) #targets From 2b3ea5eb80f29568f8879cdbf6ff74af46fa13b4 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 31 Jul 2014 18:01:50 +1000 Subject: [PATCH 04/10] Updated map system (read more) Project compiles and runs, multiplayer works, but the map is not visible There are a number of major changes to the map system, beth directly from the jam branch and from the splicing process. The changes that are listed here have been noted as they were added to the index for committing. * tile_sheet.*pp moved from 'common/graphics/' to 'common/map/' * Minor method and member name changes to TileSheet * TileSheet has a lua API, but it isn't used anywhere NOTE: Nothing uses both lua and graphics, but a theoretical editor might * Region API's glue functions have been changed from triggers to simple dummy methods. These should simply be over written. * RegionPagerBase::GetRegion(int x, int y) now snaps it's parameters Presicely why is unknown, but I do remember there was a bug without it * RegionPagerLua has been rewritten to use the Region API's methods, rather than the triggers. * RegionPagerLua no longer stores the map's save directory, or passes it to the the Region API's methods. * RegionPagerLua::luaState renamed to RegionPagerLua::lua conforms to changes elsewhere * Removed the directory glue functions from the RegionPager API * region_pager_api.hpp preprocessor guard changed * Adjusted makefiles to account for TileSheet's movement --- common/graphics/makefile | 2 +- common/map/makefile | 2 +- common/map/region_api.cpp | 25 ++++----- common/map/region_pager_api.cpp | 23 +------- common/map/region_pager_api.hpp | 4 +- common/map/region_pager_base.cpp | 3 + common/map/region_pager_lua.cpp | 68 +++++++++++----------- common/map/region_pager_lua.hpp | 10 +--- common/{graphics => map}/tile_sheet.cpp | 22 ++++---- common/{graphics => map}/tile_sheet.hpp | 12 ++-- common/map/tile_sheet_api.cpp | 75 +++++++++++++++++++++++++ common/map/tile_sheet_api.hpp | 30 ++++++++++ 12 files changed, 179 insertions(+), 97 deletions(-) rename common/{graphics => map}/tile_sheet.cpp (73%) rename common/{graphics => map}/tile_sheet.hpp (82%) create mode 100644 common/map/tile_sheet_api.cpp create mode 100644 common/map/tile_sheet_api.hpp diff --git a/common/graphics/makefile b/common/graphics/makefile index afcde11..9013447 100644 --- a/common/graphics/makefile +++ b/common/graphics/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../map +INCLUDES+=. LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/common/map/makefile b/common/map/makefile index 769709e..24e7779 100644 --- a/common/map/makefile +++ b/common/map/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../utilities +INCLUDES+=. ../graphics ../utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/common/map/region_api.cpp b/common/map/region_api.cpp index 014a873..2fd3dbb 100644 --- a/common/map/region_api.cpp +++ b/common/map/region_api.cpp @@ -78,28 +78,27 @@ static int getDepth(lua_State* L) { return 1; } -static int onLoad(lua_State* L) { - //TODO: onLoad() +static int load(lua_State* L) { + //EMPTY lua_pushboolean(L, false); return 1; } -static int onSave(lua_State* L) { - //TODO: onSave() +static int save(lua_State* L) { + //EMPTY return 0; } -static int onCreate(lua_State* L) { - //TODO: onCreate() +static int create(lua_State* L) { + //EMPTY return 0; } -static int onUnload(lua_State* L) { - //TODO: onUnload() +static int unload(lua_State* L) { + //EMPTY return 0; } -//TODO: wrappers for the collision map static const luaL_Reg regionLib[] = { {"SetTile",setTile}, {"GetTile",getTile}, @@ -110,10 +109,10 @@ static const luaL_Reg regionLib[] = { {"GetWidth",getWidth}, {"GetHeight",getHeight}, {"GetDepth",getDepth}, - {"OnLoad",onLoad}, - {"OnSave",onSave}, - {"OnCreate",onCreate}, - {"OnUnload",onUnload}, + {"Load",load}, + {"Save",save}, + {"Create",create}, + {"Unload",unload}, {nullptr, nullptr} }; diff --git a/common/map/region_pager_api.cpp b/common/map/region_pager_api.cpp index 40c4d76..3932421 100644 --- a/common/map/region_pager_api.cpp +++ b/common/map/region_pager_api.cpp @@ -24,10 +24,9 @@ #include "region_pager_lua.hpp" #include "region.hpp" -#include #include -//DOCS: These functions are just wrappers for the RegionPagerLua class +//DOCS: These glue functions simply wrap RegionPagerLua's methods static int setTile(lua_State* L) { RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); @@ -64,20 +63,6 @@ static int getRegion(lua_State* L) { return 1; } -static int setDirectory(lua_State* L) { - RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); - std::string s = pager->SetDirectory(lua_tostring(L, 2)); - lua_pushstring(L, s.c_str()); - return 1; -} - -static int getDirectory(lua_State* L) { - RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); - std::string s = pager->GetDirectory(); - lua_pushstring(L, s.c_str()); - return 1; -} - static int loadRegion(lua_State* L) { RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); Region* region = pager->LoadRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); @@ -105,14 +90,12 @@ static int unloadRegion(lua_State* L) { return 0; } -static const luaL_Reg pagerlib[] = { +static const luaL_Reg regionPagerLib[] = { {"SetTile", setTile}, {"GetTile", getTile}, {"SetSolid", setSolid}, {"GetSolid", getSolid}, {"GetRegion", getRegion}, - {"SetDirectory", setDirectory}, - {"GetDirectory", getDirectory}, {"LoadRegion", loadRegion}, {"SaveRegion", saveRegion}, {"CreateRegion", createRegion}, @@ -121,6 +104,6 @@ static const luaL_Reg pagerlib[] = { }; LUAMOD_API int openRegionPagerAPI(lua_State* L) { - luaL_newlib(L, pagerlib); + luaL_newlib(L, regionPagerLib); return 1; } \ No newline at end of file diff --git a/common/map/region_pager_api.hpp b/common/map/region_pager_api.hpp index 466af61..3636c5a 100644 --- a/common/map/region_pager_api.hpp +++ b/common/map/region_pager_api.hpp @@ -19,8 +19,8 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef PAGERAPI_HPP_ -#define PAGERAPI_HPP_ +#ifndef REGIONPAGERAPI_HPP_ +#define REGIONPAGERAPI_HPP_ #include "lua/lua.hpp" diff --git a/common/map/region_pager_base.cpp b/common/map/region_pager_base.cpp index fbe633d..8c31df1 100644 --- a/common/map/region_pager_base.cpp +++ b/common/map/region_pager_base.cpp @@ -47,6 +47,9 @@ bool RegionPagerBase::GetSolid(int x, int y) { } Region* RegionPagerBase::GetRegion(int x, int y) { + x = snapToBase(REGION_WIDTH, x); + y = snapToBase(REGION_HEIGHT, y); + //get the region by various means Region* ptr = nullptr; ptr = FindRegion(x, y); diff --git a/common/map/region_pager_lua.cpp b/common/map/region_pager_lua.cpp index 85ea167..368f950 100644 --- a/common/map/region_pager_lua.cpp +++ b/common/map/region_pager_lua.cpp @@ -32,19 +32,18 @@ Region* RegionPagerLua::LoadRegion(int x, int y) { Region tmpRegion(x, y); //API hook - lua_getglobal(luaState, "Region"); - lua_getfield(luaState, -1, "OnLoad"); - lua_pushlightuserdata(luaState, &tmpRegion); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 1, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getglobal(lua, "Region"); + lua_getfield(lua, -1, "Load"); + lua_pushlightuserdata(lua, &tmpRegion); + 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(luaState, -1)) { - lua_pop(luaState, 2); + if (!lua_toboolean(lua, -1)) { + lua_pop(lua, 2); return nullptr; } - lua_pop(luaState, 2); + lua_pop(lua, 2); regionList.push_front(tmpRegion); return ®ionList.front(); } @@ -54,14 +53,13 @@ Region* RegionPagerLua::SaveRegion(int x, int y) { Region* ptr = FindRegion(x, y); if (ptr) { //API hook - lua_getglobal(luaState, "Region"); - lua_getfield(luaState, -1, "OnSave"); - lua_pushlightuserdata(luaState, ptr); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getglobal(lua, "Region"); + 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) )); } - lua_pop(luaState, 1); + lua_pop(lua, 1); } return ptr; } @@ -75,30 +73,29 @@ Region* RegionPagerLua::CreateRegion(int x, int y) { Region tmpRegion(x, y); //API hook - lua_getglobal(luaState, "Region"); - lua_getfield(luaState, -1, "OnCreate"); - lua_pushlightuserdata(luaState, &tmpRegion); + lua_getglobal(lua, "Region"); + lua_getfield(lua, -1, "Create"); + lua_pushlightuserdata(lua, &tmpRegion); //TODO: parameters - if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } - lua_pop(luaState, 1); + lua_pop(lua, 1); regionList.push_front(tmpRegion); return ®ionList.front(); } void RegionPagerLua::UnloadRegion(int x, int y) { - lua_getglobal(luaState, "Region"); + lua_getglobal(lua, "Region"); regionList.remove_if([&](Region& region) -> bool { if (region.GetX() == x && region.GetY() == y) { //API hook - lua_getfield(luaState, -1, "OnUnload"); - lua_pushlightuserdata(luaState, ®ion); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getfield(lua, -1, "Unload"); + lua_pushlightuserdata(lua, ®ion); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } return true; @@ -106,22 +103,21 @@ void RegionPagerLua::UnloadRegion(int x, int y) { return false; }); - lua_pop(luaState, 1); + lua_pop(lua, 1); } void RegionPagerLua::UnloadAll() { - lua_getglobal(luaState, "Region"); + lua_getglobal(lua, "Region"); for (auto& it : regionList) { //API hook - lua_getfield(luaState, -1, "OnUnload"); - lua_pushlightuserdata(luaState, &it); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getfield(lua, -1, "Unload"); + lua_pushlightuserdata(lua, &it); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } } - lua_pop(luaState, 1); + lua_pop(lua, 1); 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 9468a18..8543e2d 100644 --- a/common/map/region_pager_lua.hpp +++ b/common/map/region_pager_lua.hpp @@ -42,14 +42,10 @@ public: void UnloadAll() override; //accessors & mutators - std::string SetDirectory(std::string s) { return directory = s; } - std::string GetDirectory() { return directory; } - - lua_State* SetLuaState(lua_State* L) { return luaState = L; } - lua_State* GetLuaState() { return luaState; } + lua_State* SetLuaState(lua_State* L) { return lua = L; } + lua_State* GetLuaState() { return lua; } protected: - std::string directory; - lua_State* luaState = nullptr; + lua_State* lua = nullptr; }; #endif diff --git a/common/graphics/tile_sheet.cpp b/common/map/tile_sheet.cpp similarity index 73% rename from common/graphics/tile_sheet.cpp rename to common/map/tile_sheet.cpp index bb9a4cb..819d709 100644 --- a/common/graphics/tile_sheet.cpp +++ b/common/map/tile_sheet.cpp @@ -21,24 +21,24 @@ */ #include "tile_sheet.hpp" -void TileSheet::Load(std::string fname, int xc, int yc) { - XCount = xc; - YCount = yc; +void TileSheet::Load(std::string fname, int tileWidth, int tileHeight) { image.LoadSurface(fname); - image.SetClipW(image.GetClipW()/XCount); - image.SetClipH(image.GetClipH()/YCount); + image.SetClipW(tileWidth); + image.SetClipH(tileHeight); + xCount = image.GetSurface()->w / image.GetClipW(); + yCount = image.GetSurface()->h / image.GetClipH(); } void TileSheet::Unload() { image.FreeSurface(); - XCount = YCount = 0; + xCount = yCount = 0; } -void TileSheet::DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) { +void TileSheet::DrawTileTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) { //0 is invisible if (tile == 0) return; - image.SetClipX((tile-1) % XCount * image.GetClipW()); - image.SetClipY((tile-1) / XCount * image.GetClipH()); + image.SetClipX((tile-1) % xCount * image.GetClipW()); + image.SetClipY((tile-1) / xCount * image.GetClipH()); image.DrawTo(dest, x, y); } @@ -50,8 +50,8 @@ void TileSheet::DrawRegionTo(SDL_Surface* const dest, Region* const region, int tile = region->GetTile(i, j, k); //0 is invisible if (tile == 0) continue; - image.SetClipX((tile-1) % XCount * image.GetClipW()); - image.SetClipY((tile-1) / XCount * image.GetClipH()); + image.SetClipX((tile-1) % xCount * image.GetClipW()); + image.SetClipY((tile-1) / xCount * image.GetClipH()); image.DrawTo(dest, (region->GetX() + i) * image.GetClipW() - camX, (region->GetY() + j) * image.GetClipH() - camY); diff --git a/common/graphics/tile_sheet.hpp b/common/map/tile_sheet.hpp similarity index 82% rename from common/graphics/tile_sheet.hpp rename to common/map/tile_sheet.hpp index 368fcec..f9bf8ea 100644 --- a/common/graphics/tile_sheet.hpp +++ b/common/map/tile_sheet.hpp @@ -31,24 +31,24 @@ class TileSheet { public: TileSheet() = default; - TileSheet(std::string f, int x, int y) { Load(f, x, y); } + TileSheet(std::string f, int w, int h) { Load(f, w, h); } ~TileSheet() = default; - void Load(std::string fname, int XCount, int YCount); + void Load(std::string fname, int tileWidth, int tileHeight); void Unload(); - void DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile); + void DrawTileTo(SDL_Surface* const dest, int x, int y, Region::type_t tile); void DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY); //accessors Image* GetImage() { return ℑ } - int GetXCount() { return XCount; } - int GetYCount() { return YCount; } + int GetXCount() { return xCount; } + int GetYCount() { return yCount; } int GetTileW() { return image.GetClipW(); } int GetTileH() { return image.GetClipH(); } private: Image image; - int XCount = 0, YCount = 0; + int xCount = 0, yCount = 0; }; #endif diff --git a/common/map/tile_sheet_api.cpp b/common/map/tile_sheet_api.cpp new file mode 100644 index 0000000..5ee280f --- /dev/null +++ b/common/map/tile_sheet_api.cpp @@ -0,0 +1,75 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "tile_sheet_api.hpp" + +#include "tile_sheet.hpp" + +static int load(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + sheet->Load(lua_tostring(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4)); + return 0; +} + +static int unload(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + sheet->Unload(); + return 0; +} + +static int getXCount(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetXCount()); + return 1; +} + +static int getYCount(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetYCount()); + return 1; +} + +static int getTileW(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetTileW()); + return 1; +} + +static int getTileH(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetTileH()); + return 1; +} + +static const luaL_Reg tileSheetLib[] = { + {"Load",load}, + {"Unload",unload}, + {"GetXCount",getXCount}, + {"GetYCount",getYCount}, + {"GetTileW",getTileW}, + {"GetTileH",getTileH}, + {nullptr, nullptr} +}; + +LUAMOD_API int openTileSheetAPI(lua_State* L) { + luaL_newlib(L, tileSheetLib); + return 1; +} \ No newline at end of file diff --git a/common/map/tile_sheet_api.hpp b/common/map/tile_sheet_api.hpp new file mode 100644 index 0000000..0788535 --- /dev/null +++ b/common/map/tile_sheet_api.hpp @@ -0,0 +1,30 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef TILESHEETAPI_HPP_ +#define TILESHEETAPI_HPP_ + +#include "lua/lua.hpp" + +#define TORTUGA_TILE_SHEET_NAME "TileSheet" +LUAMOD_API int openTileSheetAPI(lua_State* L); + +#endif From 555abf9c9520c22b696dbed8a1bd78e592a3d987 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 31 Jul 2014 19:17:29 +1000 Subject: [PATCH 05/10] Fixed the map issue (read more) The map generation was being written to a trigger function instead of a glue method. Fixed, map is being drawn correctly now. --- client/scenes/in_world.cpp | 3 ++- common/utilities/config_utility.cpp | 1 + rsc/scripts/setup_server.lua | 35 +++++++++++++++-------------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index 4f997a0..e8f2d62 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -71,7 +71,8 @@ InWorld::InWorld( //load the tilesheet //TODO: add the tilesheet to the map system? - tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15); + //TODO: Tile size and tile sheet should be loaded elsewhere + tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 32, 32); //request a sync RequestSynchronize(); diff --git a/common/utilities/config_utility.cpp b/common/utilities/config_utility.cpp index 7fb174b..4b1f797 100644 --- a/common/utilities/config_utility.cpp +++ b/common/utilities/config_utility.cpp @@ -26,6 +26,7 @@ #include void ConfigUtility::Load(std::string fname) { + //TODO: recursive rerouting? std::ifstream is(fname); if (!is.is_open()) { diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index 582cacf..ce07f88 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -1,38 +1,39 @@ print("Lua script check") --uber lazy declarations -function square(x) return x*x end -function distance(x, y, i, j) return math.sqrt(square(x - i) + square(y - j)) end +function math.sqr(x) return x*x end +function math.dist(x, y, i, j) return math.sqrt(math.sqr(x - i) + math.sqr(y - j)) end --tile macros, mapped to the tilesheet local base = 14 local shift = 36 -plains = base + shift * 0 -grass = base + shift * 1 -dirt = base + shift * 2 -sand = base + shift * 3 -water = base + shift * 4 +tiles = { + plains = base + shift * 0, + grass = base + shift * 1, + dirt = base + shift * 2, + sand = base + shift * 3, + water = base + shift * 4 +} ---Overwrite the original OnCreate with my own version -Region.hcOnCreate = Region.OnCreate -Region.OnCreate = function(region) - local ret = Region.hcOnCreate(region) --best practices +--could set custom generation systems here, that differ from the global generators, etc. +function Region.Create(region) for i = 1, Region.GetWidth() do for j = 1, Region.GetHeight() do - local dist = distance(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1) + local dist = math.dist(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1) if dist < 10 then - Region.SetTile(region, i, j, 1, plains) + Region.SetTile(region, i, j, 1, tiles.plains) elseif dist < 12 then - Region.SetTile(region, i, j, 1, sand) + Region.SetTile(region, i, j, 1, tiles.sand) else - Region.SetTile(region, i, j, 1, water) + Region.SetTile(region, i, j, 1, tiles.water) + Region.SetSolid(region, i, j, true) end end end - return ret end --Get some regions +--BUG: The server fails without this newRoom = RoomMgr.CreateRoom("overworld") pager = Room.GetPager(newRoom) regionTable = { @@ -42,4 +43,4 @@ regionTable = { RegionPager.GetRegion(pager, Region.GetWidth() *-1, Region.GetHeight() *-1) } -print("Finished the lua script") \ No newline at end of file +print("Finished the lua script") From 0b512305a9cba4dba65e9035e114730144605a0e Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 31 Jul 2014 20:04:53 +1000 Subject: [PATCH 06/10] Added last additions from jam (read more) I should also mention that the client is throwing up a warning that HandleCharacterUpdate() is passing to HandleCharacterNew(). --- client/character.hpp | 7 ++++--- client/scenes/in_world.cpp | 42 ++++++++++++++++++++++++++++++------- client/scenes/main_menu.cpp | 1 + server/linit.cpp | 2 ++ 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/client/character.hpp b/client/character.hpp index ca2d9a4..bde4268 100644 --- a/client/character.hpp +++ b/client/character.hpp @@ -25,6 +25,7 @@ //components #include "character_defines.hpp" #include "vector2.hpp" +#include "bounding_box.hpp" #include "statistics.hpp" //graphics @@ -64,8 +65,8 @@ public: Vector2 GetOrigin() const { return origin; } Vector2 SetMotion(Vector2 v) { return motion = v; } Vector2 GetMotion() const { return motion; } - Vector2 SetBounds(Vector2 v) { return bounds = v; } - Vector2 GetBounds() const { return bounds; } + BoundingBox SetBounds(BoundingBox b) { return bounds = b; } + BoundingBox GetBounds() { return bounds; } private: //graphics @@ -84,7 +85,7 @@ private: //position Vector2 origin = {0.0,0.0}; Vector2 motion = {0.0,0.0}; - Vector2 bounds = {CHARACTER_BOUNDS_WIDTH,CHARACTER_BOUNDS_HEIGHT}; + BoundingBox bounds; }; //tmp diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index e8f2d62..59f43ba 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -106,16 +106,41 @@ void InWorld::Update(double delta) { it.second.Update(delta); } - //TODO: Check collisions here - - //update the camera - if(localCharacter) { - camera.x = localCharacter->GetOrigin().x - camera.marginX; - camera.y = localCharacter->GetOrigin().y - camera.marginY; - } - //check the map UpdateMap(); + + //skip the rest + if (!localCharacter) { + return; + } + + //check for collisions with the map + BoundingBox wallBounds = {0, 0, tileSheet.GetTileW(), tileSheet.GetTileH()}; + const int xCount = localCharacter->GetBounds().w / wallBounds.w + 1; + const int yCount = localCharacter->GetBounds().h / wallBounds.h + 1; + + for (int i = -1; i <= xCount; ++i) { + for (int j = -1; j <= yCount; ++j) { + //set the wall's position + wallBounds.x = wallBounds.w * i + snapToBase((double)wallBounds.w, localCharacter->GetOrigin().x); + wallBounds.y = wallBounds.h * j + snapToBase((double)wallBounds.h, localCharacter->GetOrigin().y); + + if (!regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) { + continue; + } + + if ((localCharacter->GetOrigin() + localCharacter->GetBounds()).CheckOverlap(wallBounds)) { + localCharacter->SetOrigin(localCharacter->GetOrigin() - (localCharacter->GetMotion() * delta)); + localCharacter->SetMotion({0,0}); + localCharacter->CorrectSprite(); + SendPlayerUpdate(); + } + } + } + + //update the camera + camera.x = localCharacter->GetOrigin().x - camera.marginX; + camera.y = localCharacter->GetOrigin().y - camera.marginY; } void InWorld::FrameEnd() { @@ -281,6 +306,7 @@ void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) { newCharacter.SetOrigin(argPacket->origin); newCharacter.SetMotion(argPacket->motion); + newCharacter.SetBounds({0, 16, 32, 32}); //TODO: magic numbers, fix this (*newCharacter.GetStats()) = argPacket->stats; diff --git a/client/scenes/main_menu.cpp b/client/scenes/main_menu.cpp index 735e2fb..d722141 100644 --- a/client/scenes/main_menu.cpp +++ b/client/scenes/main_menu.cpp @@ -101,6 +101,7 @@ void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) { } void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { + //TODO: Buttons should only register as "selected" when the left button is used if (startButton.MouseButtonUp(button) == Button::State::HOVER) { SetNextScene(SceneList::LOBBYMENU); } diff --git a/server/linit.cpp b/server/linit.cpp index 1d79c96..072120f 100644 --- a/server/linit.cpp +++ b/server/linit.cpp @@ -38,6 +38,7 @@ #include "region_api.hpp" #include "region_pager_api.hpp" +#include "tile_sheet_api.hpp" #include "room_api.hpp" #include "room_mgr_api.hpp" @@ -58,6 +59,7 @@ static const luaL_Reg loadedlibs[] = { //Tortuga's API {TORTUGA_REGION_NAME, openRegionAPI}, {TORTUGA_REGION_PAGER_NAME, openRegionPagerAPI}, + {TORTUGA_TILE_SHEET_NAME, openTileSheetAPI}, {TORTUGA_ROOM_NAME, openRoomAPI}, {TORTUGA_ROOM_MGR_NAME, openRoomMgrAPI}, From c830fa053727a0e64cc16445da6a9a18d6f09dba Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 3 Aug 2014 23:14:56 +1000 Subject: [PATCH 07/10] ConfigUtility now supports recursion; is a Singleton If you have "config.next" set, the config system will load that as another config file. Higher config files have a higher precedence over subfiles when conflicting keys are encountered. * Added singleton.hpp, containing Singleton * ConfigUtility now inherits from Singleton * Tweaked timer.*pp layouts --- common/debugging/timer.cpp | 20 ++++++++- common/debugging/timer.hpp | 12 +++--- common/utilities/config_utility.cpp | 44 +++++++++++++++----- common/utilities/config_utility.hpp | 24 ++++++----- common/utilities/singleton.hpp | 63 +++++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 28 deletions(-) create mode 100644 common/utilities/singleton.hpp diff --git a/common/debugging/timer.cpp b/common/debugging/timer.cpp index be3636a..29d107a 100644 --- a/common/debugging/timer.cpp +++ b/common/debugging/timer.cpp @@ -21,9 +21,25 @@ */ #include "timer.hpp" +Timer::Timer(): start(Timer::Clock::now()) { + // +} + +Timer::Timer(std::string s): name(s), start(Timer::Clock::now()) { + // +} + +void Timer::Start() { + start = Clock::now(); +} + +void Timer::Stop() { + timeSpan = Clock::now() - start; +} + std::ostream& operator<<(std::ostream& os, Timer& t) { os << t.GetName() << ": "; - os << std::chrono::duration_cast(t.GetTime()).count(); - os << "ns"; + os << std::chrono::duration_cast(t.GetTime()).count(); + os << "ms"; return os; } diff --git a/common/debugging/timer.hpp b/common/debugging/timer.hpp index 7f8f38b..dfafec9 100644 --- a/common/debugging/timer.hpp +++ b/common/debugging/timer.hpp @@ -30,15 +30,15 @@ class Timer { public: typedef std::chrono::high_resolution_clock Clock; - Timer() = default; - Timer(std::string s) : name(s), start(Clock::now()) {}; + Timer(); + Timer(std::string s); ~Timer() = default; - inline void Start() { start = Clock::now(); } - inline void Stop() { time = Clock::now() - start; } + inline void Start(); + inline void Stop(); //accessors and mutators - Clock::duration GetTime() { return time; } + Clock::duration GetTime() { return timeSpan; } std::string SetName(std::string s) { return name = s; } std::string GetName() { return name; } @@ -46,7 +46,7 @@ public: private: std::string name; Clock::time_point start; - Clock::duration time; + Clock::duration timeSpan; }; std::ostream& operator<<(std::ostream& os, Timer& t); diff --git a/common/utilities/config_utility.cpp b/common/utilities/config_utility.cpp index 4b1f797..e34a2db 100644 --- a/common/utilities/config_utility.cpp +++ b/common/utilities/config_utility.cpp @@ -26,11 +26,22 @@ #include void ConfigUtility::Load(std::string fname) { - //TODO: recursive rerouting? + //clear the stored configuration + configMap.clear(); + //pass to the recursive method + configMap = Read(fname); +} + +ConfigUtility::table_t ConfigUtility::Read(std::string fname) { + //read in and return this file's data + table_t retTable; std::ifstream is(fname); if (!is.is_open()) { - throw(std::runtime_error("Failed to open config file")); + std::string msg; + msg += "Failed to open a config file: "; + msg += fname; + throw(std::runtime_error(msg)); } std::string key, val; @@ -71,35 +82,48 @@ void ConfigUtility::Load(std::string fname) { } //save the pair - table[key] = val; + retTable[key] = val; } is.close(); + + //load in any subordinate config files + //TODO: Possibility of nesting config levels? + if (retTable.find("config.next") != retTable.end()) { + table_t subTable = Read(retTable["config.next"]); + retTable.insert(subTable.begin(), subTable.end()); + } + + return retTable; } +//------------------------- +//Convert to a type +//------------------------- + std::string& ConfigUtility::String(std::string s) { - return table[s]; + return configMap[s]; } int ConfigUtility::Integer(std::string s) { - std::map::iterator it = table.find(s); - if (it == table.end()) { + table_t::iterator it = configMap.find(s); + if (it == configMap.end()) { return 0; } return atoi(it->second.c_str()); } double ConfigUtility::Double(std::string s) { - std::map::iterator it = table.find(s); - if (it == table.end()) { + table_t::iterator it = configMap.find(s); + if (it == configMap.end()) { return 0.0; } return atof(it->second.c_str()); } bool ConfigUtility::Boolean(std::string s) { - std::map::iterator it = table.find(s); - if (it == table.end()) { + table_t::iterator it = configMap.find(s); + if (it == configMap.end()) { return false; } return it->second == "true"; diff --git a/common/utilities/config_utility.hpp b/common/utilities/config_utility.hpp index 3ea8448..8b85528 100644 --- a/common/utilities/config_utility.hpp +++ b/common/utilities/config_utility.hpp @@ -22,14 +22,13 @@ #ifndef CONFIGUTILITY_HPP_ #define CONFIGUTILITY_HPP_ +#include "singleton.hpp" + #include #include -class ConfigUtility { +class ConfigUtility : public Singleton { public: - ConfigUtility() = default; - ConfigUtility(std::string s) { Load(s); } - void Load(std::string fname); //convert to a type @@ -39,16 +38,21 @@ public: bool Boolean(std::string); //shorthand - inline std::string& operator[](std::string s) { return String(s); } + inline std::string& operator[](std::string s) { return configMap[s]; } inline int Int(std::string s) { return Integer(s); } inline bool Bool(std::string s) { return Boolean(s); } - //OO breaker - std::map* GetMap() { - return &table; - } private: - std::map table; + typedef std::map table_t; + + friend Singleton; + + ConfigUtility() = default; + ~ConfigUtility() = default; + + table_t Read(std::string fname); + + table_t configMap; }; #endif diff --git a/common/utilities/singleton.hpp b/common/utilities/singleton.hpp new file mode 100644 index 0000000..379003a --- /dev/null +++ b/common/utilities/singleton.hpp @@ -0,0 +1,63 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef SINGLETON_HPP_ +#define SINGLETON_HPP_ + +#include + +template +class Singleton { +public: + static T& GetSingleton() { + if (!ptr) { + throw(std::logic_error("This singleton has not been created")); + } + return *ptr; + } + static void Create() { + if (ptr) { + throw(std::logic_error("This singleton has already been created")); + } + ptr = new T(); + } + static void Delete() { + if (!ptr) { + throw(std::logic_error("A non-existant singleton cannot be deleted")); + } + delete ptr; + ptr = nullptr; + } + +protected: + Singleton() = default; + Singleton(Singleton const&) = default; + Singleton(Singleton&&) = default; + ~Singleton() = default; + +private: + static T* ptr; +}; + +template +T* Singleton::ptr = nullptr; + +#endif \ No newline at end of file From fd320767c5b3c5061a71e46675c373a3001380d5 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 3 Aug 2014 23:20:39 +1000 Subject: [PATCH 08/10] Implemented the changes to ConfigUtility in the client and server The server's changes were easy. The clients means that the constructors for each scene have one less argument, and each scene has one less member. The exception to this is LobbyMenu, where the config is used in multiple places, so it was easier to have the config's reference as a member. To replace the config's usage, I added this line in most cases: ConfigUtility& config = ConfigUtility::GetSingleton(); The only requirement is that ConfigUtility::Create() and ConfigUtility::Delete() are called from the main() function. --- client/client_application.cpp | 16 +++++++++------- client/client_application.hpp | 2 -- client/main.cpp | 12 +++++++++++- client/scenes/clean_up.cpp | 5 +++-- client/scenes/clean_up.hpp | 3 --- client/scenes/in_combat.cpp | 3 +-- client/scenes/in_combat.hpp | 3 --- client/scenes/in_world.cpp | 7 ++++--- client/scenes/in_world.hpp | 3 --- client/scenes/lobby_menu.cpp | 2 -- client/scenes/lobby_menu.hpp | 3 +-- client/scenes/main_menu.cpp | 8 +++++--- client/scenes/main_menu.hpp | 6 +----- client/scenes/options_menu.cpp | 8 +++++--- client/scenes/options_menu.hpp | 6 +----- client/scenes/splash_screen.cpp | 8 ++++---- client/scenes/splash_screen.hpp | 6 +----- rsc/config.cfg | 2 ++ server/main.cpp | 10 ++++++++++ server/server_application.hpp | 2 +- 20 files changed, 59 insertions(+), 56 deletions(-) diff --git a/client/client_application.cpp b/client/client_application.cpp index 991cfd6..d50dcd2 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -22,6 +22,7 @@ #include "client_application.hpp" #include "serial.hpp" +#include "config_utility.hpp" #include #include @@ -48,6 +49,7 @@ void ClientApplication::Init(int argc, char** argv) { std::cout << "Beginning " << argv[0] << std::endl; //load the prerequisites + ConfigUtility& config = ConfigUtility::GetSingleton(); config.Load("rsc\\config.cfg"); //------------------------- @@ -165,25 +167,25 @@ void ClientApplication::LoadScene(SceneList sceneIndex) { //add scene creation calls here case SceneList::FIRST: case SceneList::SPLASHSCREEN: - activeScene = new SplashScreen(&config); + activeScene = new SplashScreen(); break; case SceneList::MAINMENU: - activeScene = new MainMenu(&config); + activeScene = new MainMenu(); break; case SceneList::OPTIONSMENU: - activeScene = new OptionsMenu(&config); + activeScene = new OptionsMenu(); break; case SceneList::LOBBYMENU: - activeScene = new LobbyMenu(&config, &network, &clientIndex, &accountIndex); + activeScene = new LobbyMenu(&network, &clientIndex, &accountIndex); break; case SceneList::INWORLD: - activeScene = new InWorld(&config, &network, &clientIndex, &accountIndex, &characterIndex, &characterMap); + activeScene = new InWorld(&network, &clientIndex, &accountIndex, &characterIndex, &characterMap); break; case SceneList::INCOMBAT: - activeScene = new InCombat(&config, &network, &clientIndex, &accountIndex, &characterIndex, &characterMap); + activeScene = new InCombat(&network, &clientIndex, &accountIndex, &characterIndex, &characterMap); break; case SceneList::CLEANUP: - activeScene = new CleanUp(&config, &network, &clientIndex, &accountIndex, &characterIndex, &characterMap); + activeScene = new CleanUp(&network, &clientIndex, &accountIndex, &characterIndex, &characterMap); break; default: throw(std::logic_error("Failed to recognize the scene index")); diff --git a/client/client_application.hpp b/client/client_application.hpp index 2efb742..e0e67c7 100644 --- a/client/client_application.hpp +++ b/client/client_application.hpp @@ -25,7 +25,6 @@ #include "scene_list.hpp" #include "base_scene.hpp" -#include "config_utility.hpp" #include "udp_network_utility.hpp" #include "character.hpp" @@ -48,7 +47,6 @@ private: BaseScene* activeScene = nullptr; //shared parameters - ConfigUtility config; UDPNetworkUtility network; int clientIndex = -1; int accountIndex = -1; diff --git a/client/main.cpp b/client/main.cpp index 156adff..cc3fc08 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -21,6 +21,9 @@ */ #include "client_application.hpp" +//singletons +#include "config_utility.hpp" + #include #include @@ -28,14 +31,21 @@ using namespace std; int main(int argc, char** argv) { try { + //create the singletons + ConfigUtility::Create(); + + //call the server's routines ClientApplication app; app.Init(argc, argv); app.Proc(); app.Quit(); + + //delete the singletons + ConfigUtility::Delete(); } catch(exception& e) { cerr << "Fatal exception thrown: " << e.what() << endl; return 1; } return 0; -} +} \ No newline at end of file diff --git a/client/scenes/clean_up.cpp b/client/scenes/clean_up.cpp index 42ab69c..87846d5 100644 --- a/client/scenes/clean_up.cpp +++ b/client/scenes/clean_up.cpp @@ -22,6 +22,7 @@ #include "clean_up.hpp" #include "channels.hpp" +#include "config_utility.hpp" #include @@ -30,20 +31,20 @@ //------------------------- CleanUp::CleanUp( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, int* const argCharacterIndex, CharacterMap* argCharacterMap ): - config(*argConfig), network(*argNetwork), clientIndex(*argClientIndex), accountIndex(*argAccountIndex), characterIndex(*argCharacterIndex), characterMap(*argCharacterMap) { + ConfigUtility& config = ConfigUtility::GetSingleton(); + //setup the utility objects image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); image.SetClipH(image.GetClipH()/3); diff --git a/client/scenes/clean_up.hpp b/client/scenes/clean_up.hpp index 5586f5c..3ba76ce 100644 --- a/client/scenes/clean_up.hpp +++ b/client/scenes/clean_up.hpp @@ -31,7 +31,6 @@ #include "button.hpp" //common -#include "config_utility.hpp" #include "frame_rate.hpp" #include "character.hpp" @@ -46,7 +45,6 @@ class CleanUp : public BaseScene { public: //Public access members CleanUp( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, @@ -70,7 +68,6 @@ protected: void KeyUp(SDL_KeyboardEvent const&); //shared parameters - ConfigUtility& config; UDPNetworkUtility& network; int& clientIndex; int& accountIndex; diff --git a/client/scenes/in_combat.cpp b/client/scenes/in_combat.cpp index 68c1bec..358bd08 100644 --- a/client/scenes/in_combat.cpp +++ b/client/scenes/in_combat.cpp @@ -23,6 +23,7 @@ #include "channels.hpp" #include "utility.hpp" +#include "config_utility.hpp" #include @@ -31,14 +32,12 @@ //------------------------- InCombat::InCombat( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, int* const argCharacterIndex, CharacterMap* argCharacterMap ): - config(*argConfig), network(*argNetwork), clientIndex(*argClientIndex), accountIndex(*argAccountIndex), diff --git a/client/scenes/in_combat.hpp b/client/scenes/in_combat.hpp index 6a84851..2f5cd20 100644 --- a/client/scenes/in_combat.hpp +++ b/client/scenes/in_combat.hpp @@ -31,7 +31,6 @@ #include "button.hpp" //common -#include "config_utility.hpp" #include "frame_rate.hpp" #include "character.hpp" @@ -43,7 +42,6 @@ class InCombat : public BaseScene { public: //Public access members InCombat( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, @@ -79,7 +77,6 @@ protected: void RequestShutdown(); //shared parameters - ConfigUtility& config; UDPNetworkUtility& network; int& clientIndex; int& accountIndex; diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index 59f43ba..dac3bce 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -23,6 +23,7 @@ #include "channels.hpp" #include "utility.hpp" +#include "config_utility.hpp" #include #include @@ -34,20 +35,20 @@ //------------------------- InWorld::InWorld( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, int* const argCharacterIndex, CharacterMap* argCharacterMap ): - config(*argConfig), network(*argNetwork), clientIndex(*argClientIndex), accountIndex(*argAccountIndex), characterIndex(*argCharacterIndex), characterMap(*argCharacterMap) { + ConfigUtility& config = ConfigUtility::GetSingleton(); + //setup the utility objects buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp"); buttonImage.SetClipH(buttonImage.GetClipH()/3); @@ -302,7 +303,7 @@ void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) { newCharacter.SetHandle(argPacket->handle); newCharacter.SetAvatar(argPacket->avatar); - newCharacter.GetSprite()->LoadSurface(config["dir.sprites"] + newCharacter.GetAvatar(), 4, 4); + newCharacter.GetSprite()->LoadSurface(ConfigUtility::GetSingleton()["dir.sprites"] + newCharacter.GetAvatar(), 4, 4); newCharacter.SetOrigin(argPacket->origin); newCharacter.SetMotion(argPacket->motion); diff --git a/client/scenes/in_world.hpp b/client/scenes/in_world.hpp index 34ce942..8dddfdf 100644 --- a/client/scenes/in_world.hpp +++ b/client/scenes/in_world.hpp @@ -35,7 +35,6 @@ #include "tile_sheet.hpp" //common -#include "config_utility.hpp" #include "frame_rate.hpp" #include "character.hpp" @@ -50,7 +49,6 @@ class InWorld : public BaseScene { public: //Public access members InWorld( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex, @@ -94,7 +92,6 @@ protected: void UpdateMap(); //shared parameters - ConfigUtility& config; UDPNetworkUtility& network; int& clientIndex; int& accountIndex; diff --git a/client/scenes/lobby_menu.cpp b/client/scenes/lobby_menu.cpp index f4b5e32..2e71a89 100644 --- a/client/scenes/lobby_menu.cpp +++ b/client/scenes/lobby_menu.cpp @@ -31,12 +31,10 @@ //------------------------- LobbyMenu::LobbyMenu( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex ): - config(*argConfig), network(*argNetwork), clientIndex(*argClientIndex), accountIndex(*argAccountIndex) diff --git a/client/scenes/lobby_menu.hpp b/client/scenes/lobby_menu.hpp index a27c1a9..96afaa0 100644 --- a/client/scenes/lobby_menu.hpp +++ b/client/scenes/lobby_menu.hpp @@ -41,7 +41,6 @@ class LobbyMenu : public BaseScene { public: //Public access members LobbyMenu( - ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, int* const argAccountIndex @@ -68,7 +67,7 @@ protected: void HandleJoinResponse(ClientPacket* const); //shared parameters - ConfigUtility& config; + ConfigUtility& config = ConfigUtility::GetSingleton(); UDPNetworkUtility& network; int& clientIndex; int& accountIndex; diff --git a/client/scenes/main_menu.cpp b/client/scenes/main_menu.cpp index d722141..ca82ef8 100644 --- a/client/scenes/main_menu.cpp +++ b/client/scenes/main_menu.cpp @@ -21,13 +21,15 @@ */ #include "main_menu.hpp" +#include "config_utility.hpp" + //------------------------- //Public access members //------------------------- -MainMenu::MainMenu(ConfigUtility* const argConfig): - config(*argConfig) -{ +MainMenu::MainMenu() { + ConfigUtility& config = ConfigUtility::GetSingleton(); + //setup the utility objects image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); image.SetClipH(image.GetClipH()/3); diff --git a/client/scenes/main_menu.hpp b/client/scenes/main_menu.hpp index 3816482..2dec3ae 100644 --- a/client/scenes/main_menu.hpp +++ b/client/scenes/main_menu.hpp @@ -24,7 +24,6 @@ #include "base_scene.hpp" -#include "config_utility.hpp" #include "image.hpp" #include "raster_font.hpp" #include "button.hpp" @@ -32,7 +31,7 @@ class MainMenu : public BaseScene { public: //Public access members - MainMenu(ConfigUtility* const); + MainMenu(); ~MainMenu(); protected: @@ -49,9 +48,6 @@ protected: void KeyDown(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&); - //shared parameters - ConfigUtility& config; - //members Image image; RasterFont font; diff --git a/client/scenes/options_menu.cpp b/client/scenes/options_menu.cpp index 19b3b9e..4a991f7 100644 --- a/client/scenes/options_menu.cpp +++ b/client/scenes/options_menu.cpp @@ -21,13 +21,15 @@ */ #include "options_menu.hpp" +#include "config_utility.hpp" + //------------------------- //Public access members //------------------------- -OptionsMenu::OptionsMenu(ConfigUtility* const argConfig): - config(*argConfig) -{ +OptionsMenu::OptionsMenu() { + ConfigUtility& config = ConfigUtility::GetSingleton(); + //setup the utility objects image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); image.SetClipH(image.GetClipH()/3); diff --git a/client/scenes/options_menu.hpp b/client/scenes/options_menu.hpp index 37e4e64..8570644 100644 --- a/client/scenes/options_menu.hpp +++ b/client/scenes/options_menu.hpp @@ -24,7 +24,6 @@ #include "base_scene.hpp" -#include "config_utility.hpp" #include "image.hpp" #include "raster_font.hpp" #include "button.hpp" @@ -33,7 +32,7 @@ class OptionsMenu : public BaseScene { public: //Public access members - OptionsMenu(ConfigUtility* const); + OptionsMenu(); ~OptionsMenu(); protected: @@ -50,9 +49,6 @@ protected: void KeyDown(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&); - //shared parameters - ConfigUtility& config; - //members Image image; RasterFont font; diff --git a/client/scenes/splash_screen.cpp b/client/scenes/splash_screen.cpp index a363a2c..2c3b233 100644 --- a/client/scenes/splash_screen.cpp +++ b/client/scenes/splash_screen.cpp @@ -21,14 +21,14 @@ */ #include "splash_screen.hpp" +#include "config_utility.hpp" + //------------------------- //Public access members //------------------------- -SplashScreen::SplashScreen(ConfigUtility* const argConfig): - config(*argConfig) -{ - logo.LoadSurface(config["dir.logos"] + "krstudios.bmp"); +SplashScreen::SplashScreen() { + logo.LoadSurface(ConfigUtility::GetSingleton()["dir.logos"] + "krstudios.bmp"); startTick = std::chrono::steady_clock::now(); } diff --git a/client/scenes/splash_screen.hpp b/client/scenes/splash_screen.hpp index 2b2000b..9d55c0c 100644 --- a/client/scenes/splash_screen.hpp +++ b/client/scenes/splash_screen.hpp @@ -24,7 +24,6 @@ #include "base_scene.hpp" -#include "config_utility.hpp" #include "image.hpp" #include @@ -32,7 +31,7 @@ class SplashScreen : public BaseScene { public: //Public access members - SplashScreen(ConfigUtility* const); + SplashScreen(); ~SplashScreen(); protected: @@ -40,9 +39,6 @@ protected: void Update(double delta); void Render(SDL_Surface* const); - //shared parameters - ConfigUtility& config; - //members std::chrono::steady_clock::time_point startTick; Image logo; diff --git a/rsc/config.cfg b/rsc/config.cfg index b2f34d9..bbe6611 100644 --- a/rsc/config.cfg +++ b/rsc/config.cfg @@ -8,6 +8,8 @@ server.name = local server.dbname = database.db #client specific settings +#client.screen.w = 800 +#client.screen.h = 600 client.screen.f = false client.username = Kayne Ruse diff --git a/server/main.cpp b/server/main.cpp index 5c01971..bfa7f7c 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -21,6 +21,9 @@ */ #include "server_application.hpp" +//singletons +#include "config_utility.hpp" + #include #include @@ -28,10 +31,17 @@ using namespace std; int main(int argc, char** argv) { try { + //create the singletons + ConfigUtility::Create(); + + //call the server's routines ServerApplication app; app.Init(argc, argv); app.Proc(); app.Quit(); + + //delete the singletons + ConfigUtility::Delete(); } catch(exception& e) { cerr << "Fatal exception thrown: " << e.what() << endl; diff --git a/server/server_application.hpp b/server/server_application.hpp index c5d0c1d..74b8777 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -83,7 +83,7 @@ private: sqlite3* database = nullptr; lua_State* luaState = nullptr; UDPNetworkUtility network; - ConfigUtility config; + ConfigUtility& config = ConfigUtility::GetSingleton(); //simple tables std::map clientMap; From 908f91d6744258861d176bc0e4a35204c0e6ab8f Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 4 Aug 2014 00:45:09 +1000 Subject: [PATCH 09/10] ClientApplication and ServerApplication are now Singletons --- client/client_application.hpp | 13 +++++++++---- client/main.cpp | 4 +++- server/main.cpp | 4 +++- server/server_application.hpp | 11 +++++++---- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/client/client_application.hpp b/client/client_application.hpp index e0e67c7..eea274f 100644 --- a/client/client_application.hpp +++ b/client/client_application.hpp @@ -28,18 +28,23 @@ #include "udp_network_utility.hpp" #include "character.hpp" +#include "singleton.hpp" + #include -class ClientApplication { +class ClientApplication: public Singleton { public: - ClientApplication() = default; - ~ClientApplication() = default; - + //public methods void Init(int argc, char** argv); void Proc(); void Quit(); private: + friend Singleton; + + ClientApplication() = default; + ~ClientApplication() = default; + //Private access members void LoadScene(SceneList sceneIndex); void UnloadScene(); diff --git a/client/main.cpp b/client/main.cpp index cc3fc08..57154b6 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -32,16 +32,18 @@ using namespace std; int main(int argc, char** argv) { try { //create the singletons + ClientApplication::Create(); ConfigUtility::Create(); //call the server's routines - ClientApplication app; + ClientApplication& app = ClientApplication::GetSingleton(); app.Init(argc, argv); app.Proc(); app.Quit(); //delete the singletons ConfigUtility::Delete(); + ClientApplication::Delete(); } catch(exception& e) { cerr << "Fatal exception thrown: " << e.what() << endl; diff --git a/server/main.cpp b/server/main.cpp index bfa7f7c..4fbc24a 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -33,15 +33,17 @@ int main(int argc, char** argv) { try { //create the singletons ConfigUtility::Create(); + ServerApplication::Create(); //call the server's routines - ServerApplication app; + ServerApplication& app = ServerApplication::GetSingleton(); app.Init(argc, argv); app.Proc(); app.Quit(); //delete the singletons ConfigUtility::Delete(); + ServerApplication::Delete(); } catch(exception& e) { cerr << "Fatal exception thrown: " << e.what() << endl; diff --git a/server/server_application.hpp b/server/server_application.hpp index 74b8777..6c99d2d 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -31,6 +31,7 @@ //common utilities #include "udp_network_utility.hpp" #include "config_utility.hpp" +#include "singleton.hpp" //APIs #include "lua/lua.hpp" @@ -42,17 +43,19 @@ #include //The main application class -class ServerApplication { +class ServerApplication: public Singleton { public: //public methods - ServerApplication() = default; - ~ServerApplication() = default; - void Init(int argc, char** argv); void Proc(); void Quit(); private: + friend Singleton; + + ServerApplication() = default; + ~ServerApplication() = default; + //handle incoming traffic void HandlePacket(SerialPacket* const); From 956e920b7ae292171acc4be7d8a1bbd6d7ac9027 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 4 Aug 2014 01:04:13 +1000 Subject: [PATCH 10/10] Added the debug and release targets --- makefile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 56e39a3..3a5a667 100644 --- a/makefile +++ b/makefile @@ -4,9 +4,9 @@ #RM=del /y #CXXFLAGS+=-static-libgcc -static-libstdc++ -g -fno-inline-functions -Wall -CXXFLAGS+=-static-libgcc -static-libstdc++ +#CXXFLAGS+=-static-libgcc -static-libstdc++ -export +#export OUTDIR=out @@ -15,6 +15,12 @@ all: $(OUTDIR) $(MAKE) -C server $(MAKE) -C client +debug: export CXXFLAGS+=-g +debug: clean all + +release: export CXXFLAGS+=-static-libgcc -static-libstdc++ +release: clean all + $(OUTDIR): mkdir $(OUTDIR)