Merge branch 'fun-with-interfaces' into develop

This commit is contained in:
Kayne Ruse
2014-10-07 02:10:23 +11:00
14 changed files with 254 additions and 166 deletions
+18 -16
View File
@@ -87,13 +87,13 @@ int AccountManager::Load(std::string username, int clientIndex) {
int uid = sqlite3_column_int(statement, 0);
//check to see if this account is already loaded
if (accountMap.find(uid) != accountMap.end()) {
if (elementMap.find(uid) != elementMap.end()) {
sqlite3_finalize(statement);
return -1;
}
//extract the data into memory
AccountData& newAccount = accountMap[uid];
AccountData& newAccount = elementMap[uid];
newAccount.username = reinterpret_cast<const char*>(sqlite3_column_text(statement, 1));
newAccount.blackListed = sqlite3_column_int(statement, 2);
newAccount.whiteListed = sqlite3_column_int(statement, 3);
@@ -121,11 +121,11 @@ int AccountManager::Save(int uid) {
//DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID.
//this method fails if this account is not loaded
if (accountMap.find(uid) == accountMap.end()) {
if (elementMap.find(uid) == elementMap.end()) {
return -1;
}
AccountData& account = accountMap[uid];
AccountData& account = elementMap[uid];
sqlite3_stmt* statement = nullptr;
//prep
@@ -163,7 +163,7 @@ void AccountManager::Unload(int uid) {
//save this user account, and then unload it
//NOTE: the associated characters are unloaded externally
Save(uid);
accountMap.erase(uid);
elementMap.erase(uid);
}
void AccountManager::Delete(int uid) {
@@ -190,26 +190,28 @@ void AccountManager::Delete(int uid) {
//finish the routine
sqlite3_finalize(statement);
accountMap.erase(uid);
elementMap.erase(uid);
}
void AccountManager::UnloadAll() {
for (auto& it : accountMap) {
for (auto& it : elementMap) {
Save(it.first);
}
accountMap.clear();
elementMap.clear();
}
void AccountManager::UnloadIf(std::function<bool(std::pair<int, AccountData>)> fn) {
void AccountManager::UnloadIf(std::function<bool(std::pair<const int, AccountData>)> fn) {
//replicate std::remove_if, using custom code
for (std::map<int, AccountData>::iterator it = accountMap.begin(); it != accountMap.end(); /* empty */) {
std::map<int, AccountData>::iterator it = elementMap.begin();
while (it != elementMap.end()) {
if (fn(*it)) {
Save(it->first);
it = accountMap.erase(it);
continue;
it = elementMap.erase(it);
}
else {
++it;
}
}
}
//-------------------------
@@ -218,9 +220,9 @@ void AccountManager::UnloadIf(std::function<bool(std::pair<int, AccountData>)> f
AccountData* AccountManager::Get(int uid) {
//TODO: could this load an account first?
std::map<int, AccountData>::iterator it = accountMap.find(uid);
std::map<int, AccountData>::iterator it = elementMap.find(uid);
if (it == accountMap.end()) {
if (it == elementMap.end()) {
return nullptr;
}
@@ -228,7 +230,7 @@ AccountData* AccountManager::Get(int uid) {
}
int AccountManager::GetLoadedCount() {
return accountMap.size();
return elementMap.size();
}
int AccountManager::GetTotalCount() {
@@ -250,7 +252,7 @@ int AccountManager::GetTotalCount() {
}
std::map<int, AccountData>* AccountManager::GetContainer() {
return &accountMap;
return &elementMap;
}
sqlite3* AccountManager::SetDatabase(sqlite3* db) {
+17 -14
View File
@@ -24,29 +24,33 @@
#include "account_data.hpp"
#include "singleton.hpp"
#include "manager_interface.hpp"
#include "sqlite3/sqlite3.h"
#include <functional>
#include <map>
class AccountManager : public Singleton<AccountManager> {
class AccountManager:
public Singleton<AccountManager>,
public ManagerInterface<AccountData, std::string, int>
{
public:
//public access methods
int Create(std::string username, int clientIndex);
int Load(std::string username, int clientIndex);
int Save(int uid);
void Unload(int uid);
void Delete(int uid);
//common public methods
int Create(std::string username, int clientIndex) override;
int Load(std::string username, int clientIndex) override;
int Save(int uid) override;
void Unload(int uid) override;
void Delete(int uid) override;
void UnloadAll();
void UnloadIf(std::function<bool(std::pair<int, AccountData>)> fn);
void UnloadAll() override;
void UnloadIf(std::function<bool(std::pair<const int, AccountData>)> fn) override;
//accessors and mutators
AccountData* Get(int uid);
int GetLoadedCount();
int GetTotalCount();
std::map<int, AccountData>* GetContainer();
AccountData* Get(int uid) override;
int GetLoadedCount() override;
int GetTotalCount() override;
std::map<int, AccountData>* GetContainer() override;
sqlite3* SetDatabase(sqlite3* db);
sqlite3* GetDatabase();
@@ -57,7 +61,6 @@ private:
AccountManager() = default;
~AccountManager() = default;
std::map<int, AccountData> accountMap;
sqlite3* database = nullptr;
};
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../../common/utilities
INCLUDES+=. ../server_utilities ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+18 -17
View File
@@ -98,7 +98,7 @@ int CharacterManager::Load(int owner, std::string handle, std::string avatar) {
int uid = sqlite3_column_int(statement, 0);
//check to see if this character is already loaded
if (characterMap.find(uid) != characterMap.end()) {
if (elementMap.find(uid) != elementMap.end()) {
sqlite3_finalize(statement);
return -1;
}
@@ -110,7 +110,7 @@ int CharacterManager::Load(int owner, std::string handle, std::string avatar) {
}
//extract the data into memory
CharacterData& newChar = characterMap[uid];
CharacterData& newChar = elementMap[uid];
//metadata
newChar.owner = owner;
@@ -145,11 +145,11 @@ int CharacterManager::Save(int uid) {
//DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID.
//this method fails if this character is not loaded
if (characterMap.find(uid) == characterMap.end()) {
if (elementMap.find(uid) == elementMap.end()) {
return -1;
}
CharacterData& character = characterMap[uid];
CharacterData& character = elementMap[uid];
sqlite3_stmt* statement = nullptr;
//prep
@@ -187,7 +187,7 @@ int CharacterManager::Save(int uid) {
void CharacterManager::Unload(int uid) {
//save this character, then unload it
Save(uid);
characterMap.erase(uid);
elementMap.erase(uid);
}
void CharacterManager::Delete(int uid) {
@@ -213,26 +213,27 @@ void CharacterManager::Delete(int uid) {
//finish the routine
sqlite3_finalize(statement);
characterMap.erase(uid);
elementMap.erase(uid);
}
void CharacterManager::UnloadAll() {
for (auto& it : characterMap) {
for (auto& it : elementMap) {
Save(it.first);
}
characterMap.clear();
elementMap.clear();
}
void CharacterManager::UnloadIf(std::function<bool(std::pair<int, CharacterData>)> fn) {
//replicate std::remove_if, using custom code
for (std::map<int, CharacterData>::iterator it = characterMap.begin(); it != characterMap.end(); /* empty */) {
void CharacterManager::UnloadIf(std::function<bool(std::pair<const int, CharacterData>)> fn) {
std::map<int, CharacterData>::iterator it = elementMap.begin();
while (it != elementMap.end()) {
if (fn(*it)) {
Save(it->first);
it = characterMap.erase(it);
continue;
it = elementMap.erase(it);
}
else {
++it;
}
}
}
//-------------------------
@@ -240,9 +241,9 @@ void CharacterManager::UnloadIf(std::function<bool(std::pair<int, CharacterData>
//-------------------------
CharacterData* CharacterManager::Get(int uid) {
std::map<int, CharacterData>::iterator it = characterMap.find(uid);
std::map<int, CharacterData>::iterator it = elementMap.find(uid);
if (it == characterMap.end()) {
if (it == elementMap.end()) {
return nullptr;
}
@@ -250,7 +251,7 @@ CharacterData* CharacterManager::Get(int uid) {
}
int CharacterManager::GetLoadedCount() {
return characterMap.size();
return elementMap.size();
}
int CharacterManager::GetTotalCount() {
@@ -272,7 +273,7 @@ int CharacterManager::GetTotalCount() {
}
std::map<int, CharacterData>* CharacterManager::GetContainer() {
return &characterMap;
return &elementMap;
}
sqlite3* CharacterManager::SetDatabase(sqlite3* db) {
+17 -14
View File
@@ -24,29 +24,33 @@
#include "character_data.hpp"
#include "singleton.hpp"
#include "manager_interface.hpp"
#include "sqlite3/sqlite3.h"
#include <functional>
#include <map>
class CharacterManager : public Singleton<CharacterManager> {
class CharacterManager:
public Singleton<CharacterManager>,
public ManagerInterface<CharacterData, int, std::string, std::string>
{
public:
//public access methods
int Create(int owner, std::string handle, std::string avatar);
int Load(int owner, std::string handle, std::string avatar);
int Save(int uid);
void Unload(int uid);
void Delete(int uid);
//common public methods
int Create(int owner, std::string handle, std::string avatar) override;
int Load(int owner, std::string handle, std::string avatar) override;
int Save(int uid) override;
void Unload(int uid) override;
void Delete(int uid) override;
void UnloadAll();
void UnloadIf(std::function<bool(std::pair<int, CharacterData>)> fn);
void UnloadAll() override;
void UnloadIf(std::function<bool(std::pair<const int, CharacterData>)> fn) override;
//accessors and mutators
CharacterData* Get(int uid);
int GetLoadedCount();
int GetTotalCount();
std::map<int, CharacterData>* GetContainer();
CharacterData* Get(int uid) override;
int GetLoadedCount() override;
int GetTotalCount() override;
std::map<int, CharacterData>* GetContainer() override;
sqlite3* SetDatabase(sqlite3* db);
sqlite3* GetDatabase();
@@ -57,7 +61,6 @@ private:
CharacterManager() = default;
~CharacterManager() = default;
std::map<int, CharacterData> characterMap;
sqlite3* database = nullptr;
};
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../../common/gameplay ../../common/utilities
INCLUDES+=. ../server_utilities ../../common/gameplay ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../../common/map ../../common/utilities
INCLUDES+=. ../server_utilities ../../common/map ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+22 -7
View File
@@ -29,21 +29,36 @@ static int getPager(lua_State* L) {
return 1;
}
static int create(lua_State* L) {
//EMPTY
//NOTE: This can be used to set defaults for the pager
static int setRoomName(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
room->SetRoomName(lua_tostring(L, 2));
return 0;
}
static int unload(lua_State* L) {
//EMPTY
static int getRoomName(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
lua_pushstring(L, room->GetRoomName().c_str());
return 1;
}
static int setTilesetName(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
room->SetTilesetName(lua_tostring(L, 2));
return 0;
}
static int getTilesetName(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
lua_pushstring(L, room->GetTilesetName().c_str());
return 1;
}
static const luaL_Reg roomLib[] = {
{"GetPager",getPager},
{"Create", create},
{"Unload", unload},
{"SetRoomName", setRoomName},
{"GetRoomName", getRoomName},
{"SetTileset", setTilesetName},
{"GetTileset", getTilesetName},
{nullptr, nullptr}
};
+6
View File
@@ -35,6 +35,9 @@ public:
//accessors and mutators
RegionPagerLua* GetPager() { return &pager; }
std::string SetRoomName(std::string s) { return roomName = s; }
std::string GetRoomName() { return roomName; }
std::string SetTilesetName(std::string s) { return tilesetName = s; }
std::string GetTilesetName() { return tilesetName; }
@@ -43,7 +46,10 @@ private:
//members
RegionPagerLua pager;
std::string roomName;
std::string tilesetName;
//TODO: pass the room name & tileset name to the clients
//TODO: lua references i.e. create, unload, etc.
};
#endif
+56 -58
View File
@@ -29,78 +29,76 @@
//public access methods
//-------------------------
int RoomManager::CreateRoom() {
int RoomManager::Create() {
//create the room
RoomData* newRoom = new RoomData();
newRoom->pager.SetLuaState(luaState);
//register the room
roomMap[counter] = newRoom;
//API hook
lua_getglobal(luaState, TORTUGA_ROOM_NAME);
lua_getfield(luaState, -1, "Create");
lua_pushlightuserdata(luaState, newRoom);
if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
}
lua_pop(luaState, 1);
RoomData* newRoom = &elementMap[counter]; //implicitly constructs the element
newRoom->pager.SetLuaState(lua);
//finish the routine
return counter++;
}
void RoomManager::UnloadRoom(int uid) {
int RoomManager::Load() {
//TODO: RoomManager::Load()
return -1;
}
int RoomManager::Save(int uid) {
//TODO: RoomManager::Save(uid)
return -1;
}
void RoomManager::Unload(int uid) {
//find the room
RoomData* room = FindRoom(uid);
if (!room) {
std::map<int, RoomData>::iterator it = elementMap.find(uid);
if (it == elementMap.end()) {
return;
}
//API hook
lua_getglobal(luaState, TORTUGA_ROOM_NAME);
lua_getfield(luaState, -1, "Unload");
lua_pushlightuserdata(luaState, room);
if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
}
lua_pop(luaState, 1);
//free the memory
delete room;
roomMap.erase(uid);
elementMap.erase(uid);
}
RoomData* RoomManager::GetRoom(int uid) {
return FindRoom(uid);
//TODO: expand this to auto-create the room
}
RoomData* RoomManager::FindRoom(int uid) {
std::map<int, RoomData*>::iterator it = roomMap.find(uid);
if (it == roomMap.end()) {
return nullptr;
}
return it->second;
}
int RoomManager::PushRoom(RoomData* room) {
roomMap[counter++] = room;
return counter;
void RoomManager::Delete(int uid) {
//TODO: RoomManager::Delete(int uid)
//NOTE: aliased to RoomManager::Unload(int uid)
Unload(uid);
}
void RoomManager::UnloadAll() {
lua_getglobal(luaState, TORTUGA_ROOM_NAME);
for (auto& it : roomMap) {
//API hook
lua_getfield(luaState, -1, "Unload");
lua_pushlightuserdata(luaState, it.second);
if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) ));
}
}
lua_pop(luaState, 1);
roomMap.clear();
elementMap.clear();
}
void RoomManager::UnloadIf(std::function<bool(std::pair<const int,RoomData>)> fn) {
std::map<int, RoomData>::iterator it = elementMap.begin();
while (it != elementMap.end()) {
if (fn(*it)) {
it = elementMap.erase(it);
}
else {
++it;
}
}
}
RoomData* RoomManager::Get(int uid) {
std::map<int, RoomData>::iterator it = elementMap.find(uid);
if (it == elementMap.end()) {
return nullptr;
}
return &it->second;
}
int RoomManager::GetLoadedCount() {
return elementMap.size();
}
int RoomManager::GetTotalCount() {
return elementMap.size();
}
std::map<int, RoomData>* RoomManager::GetContainer() {
return &elementMap;
}
+21 -16
View File
@@ -24,28 +24,34 @@
#include "room_data.hpp"
#include "singleton.hpp"
#include "manager_interface.hpp"
#include "lua/lua.hpp"
#include <map>
class RoomManager : public Singleton<RoomManager> {
class RoomManager:
public Singleton<RoomManager>,
public ManagerInterface<RoomData>
{
public:
//public access methods
int CreateRoom();
void UnloadRoom(int uid);
//common public methods
int Create() override;
int Load() override;
int Save(int uid) override;
void Unload(int uid) override;
void Delete(int uid) override;
RoomData* GetRoom(int uid);
RoomData* FindRoom(int uid);
int PushRoom(RoomData*);
void UnloadAll();
void UnloadAll() override;
void UnloadIf(std::function<bool(std::pair<const int,RoomData>)> fn) override;
//accessors and mutators
std::map<int, RoomData*>* GetContainer() { return &roomMap; }
RoomData* Get(int uid) override;
int GetLoadedCount() override;
int GetTotalCount() override;
std::map<int, RoomData>* GetContainer() override;
lua_State* SetLuaState(lua_State* L) { return luaState = L; }
lua_State* GetLuaState() { return luaState; }
//hooks
lua_State* SetLuaState(lua_State* L) { return lua = L; }
lua_State* GetLuaState() { return lua; }
private:
friend Singleton<RoomManager>;
@@ -53,8 +59,7 @@ private:
RoomManager() = default;
~RoomManager() = default;
std::map<int, RoomData*> roomMap;
lua_State* luaState = nullptr;
lua_State* lua = nullptr;
int counter = 0;
};
+21 -21
View File
@@ -23,34 +23,34 @@
#include "room_manager.hpp"
#include <string>
int createRoom(lua_State* L) {
//create & get the room
RoomManager& roomMgr = RoomManager::GetSingleton();
int uid = roomMgr.Create();
RoomData* room = roomMgr.Get(uid);
static int getRoom(lua_State* L) {
//find, push and return the room
RoomData* room = RoomManager::GetSingleton().GetRoom(lua_tointeger(L, -2));
lua_pushlightuserdata(L, reinterpret_cast<void*>(room));
return 1;
//setup the room
//TODO: room parameters only set via lua, fix this
room->SetRoomName(lua_tostring(L, 1));
room->SetTilesetName(lua_tostring(L, 2));
//return room, uid
lua_pushlightuserdata(L, static_cast<void*>(room));
lua_pushinteger(L, uid);
return 2;
}
static int createRoom(lua_State* L) {
//TODO: check parameter count for the glue functions
//create, find and return the room
int uid = RoomManager::GetSingleton().CreateRoom();
lua_pushlightuserdata(L, RoomManager::GetSingleton().FindRoom(uid));
return 1;
}
static int unloadRoom(lua_State* L) {
//unload the specified room
RoomManager::GetSingleton().UnloadRoom(lua_tointeger(L, -2));
int unloadRoom(lua_State* L) {
//TODO: check authorization for room deletion
RoomManager& roomMgr = RoomManager::GetSingleton();
roomMgr.Unload(lua_tointeger(L, 1));
return 0;
}
static const luaL_Reg roomManagerLib[] = {
{"GetRoom",getRoom},
{"CreateRoom",createRoom},
{"UnloadRoom",unloadRoom},
{"CreateRoom", createRoom},
{"UnloadRoom", unloadRoom},
{nullptr, nullptr}
};
+1 -1
View File
@@ -161,7 +161,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) {
newPacket.y = argPacket->y;
//BUG: possibly related to #35
newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->GetPager()->GetRegion(argPacket->x, argPacket->y);
newPacket.region = roomMgr.Get(argPacket->roomIndex)->GetPager()->GetRegion(argPacket->x, argPacket->y);
//send the content
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
@@ -0,0 +1,55 @@
/* 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 MANAGERINTERFACE_HPP_
#define MANAGERINTERFACE_HPP_
#include <functional>
#include <map>
template<typename T, typename... Arguments>
class ManagerInterface {
public:
//common public methods
virtual int Create(Arguments... parameters) = 0;
virtual int Load(Arguments... parameters) = 0;
virtual int Save(int uid) = 0;
virtual void Unload(int uid) = 0;
virtual void Delete(int uid) = 0;
virtual void UnloadAll() = 0;
virtual void UnloadIf(std::function<bool(std::pair<const int, T>)> fn) = 0;
//accessors & mutators
virtual T* Get(int uid) = 0;
virtual int GetLoadedCount() = 0;
virtual int GetTotalCount() = 0; //can be an alias of GetLoadedCount()
virtual std::map<int, T>* GetContainer() = 0;
protected:
ManagerInterface() = default;
~ManagerInterface() = default;
//members
std::map<int, T> elementMap;
};
#endif