Skip to content

Commit

Permalink
refactor: GameManager to implement Singleton pattern and streamline g…
Browse files Browse the repository at this point in the history
…ame management methods
  • Loading branch information
MasterLaplace committed Nov 7, 2024
1 parent 14f9c87 commit f370cf7
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 165 deletions.
66 changes: 17 additions & 49 deletions Flakkari/Server/Game/GameManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@

namespace Flakkari {

std::shared_ptr<GameManager> GameManager::_instance = nullptr;
std::mutex GameManager::_mutex;

#define STR_ADDRESS std::string(*client->getAddress())

GameManager::GameManager()
Expand Down Expand Up @@ -68,19 +65,8 @@ GameManager::GameManager()
}
}

std::shared_ptr<GameManager> GameManager::getInstance()
{
std::lock_guard<std::mutex> lock(_mutex);
if (!_instance)
_instance = std::make_shared<GameManager>();
return _instance;
}

int GameManager::addGame(std::string gameName)
{
auto &_gamesStore = getInstance()->_gamesStore;
auto _game_dir = getInstance()->_game_dir;

if (_gamesStore.find(gameName) != _gamesStore.end())
return FLAKKARI_LOG_ERROR("game already loaded"), 1;
std::ifstream configFile(_game_dir + "/" + gameName + "/config.cfg");
Expand All @@ -100,15 +86,13 @@ int GameManager::addGame(std::string gameName)

std::shared_ptr<Game> GameManager::getGame(std::string gameName)
{
auto &_gamesStore = getInstance()->_gamesStore;
if (_gamesStore.find(gameName) == _gamesStore.end())
return FLAKKARI_LOG_ERROR("game not found"), nullptr;
return std::make_shared<Game>(gameName, _gamesStore[gameName]);
}

std::vector<std::shared_ptr<Game>> GameManager::getGamesInstances()
{
auto &_gamesInstances = getInstance()->_gamesInstances;
std::vector<std::shared_ptr<Game>> gamesInstances;

for (auto &game : _gamesInstances)
Expand All @@ -118,9 +102,6 @@ std::vector<std::shared_ptr<Game>> GameManager::getGamesInstances()

int GameManager::updateGame(std::string gameName)
{
auto &_gamesStore = getInstance()->_gamesStore;
auto _game_dir = getInstance()->_game_dir;

if (_gamesStore.find(gameName) == _gamesStore.end())
return FLAKKARI_LOG_ERROR("game not found"), 1;
std::ifstream configFile(_game_dir + "/" + gameName + "/config.cfg");
Expand All @@ -137,7 +118,6 @@ int GameManager::updateGame(std::string gameName)

int GameManager::removeGame(std::string gameName)
{
auto &_gamesStore = getInstance()->_gamesStore;
if (_gamesStore.find(gameName) == _gamesStore.end())
return FLAKKARI_LOG_ERROR("game not found"), 1;

Expand All @@ -149,7 +129,6 @@ int GameManager::removeGame(std::string gameName)

void GameManager::listGames()
{
auto &_gamesStore = getInstance()->_gamesStore;
std::string gamesList = "Games list:\n";

for (const auto &game : _gamesStore)
Expand All @@ -159,20 +138,14 @@ void GameManager::listGames()

void GameManager::addClientToGame(std::string gameName, std::shared_ptr<Client> client)
{
auto current = getInstance();
auto &gamesStore = current->_gamesStore;
auto &gamesInstances = current->_gamesInstances;
auto &waitingClients = current->_waitingClients;

if (gamesStore.find(gameName) == gamesStore.end())
{
if (_gamesStore.find(gameName) == _gamesStore.end()) {
FLAKKARI_LOG_ERROR("game not found");
client.reset();
return;
}

auto &gameStore = gamesStore[gameName];
auto &gameInstance = gamesInstances[gameName];
auto &gameStore = _gamesStore[gameName];
auto &gameInstance = _gamesInstances[gameName];

auto minPlayers = gameStore->at("minPlayers").get<size_t>();
auto maxPlayers = gameStore->at("maxPlayers").get<size_t>();
Expand All @@ -188,7 +161,7 @@ void GameManager::addClientToGame(std::string gameName, std::shared_ptr<Client>
if (gameInstance.size() >= maxInstances)
{
FLAKKARI_LOG_ERROR("game \"" + gameName + "\"is full");
waitingClients[gameName].push(client);
_waitingClients[gameName].push(client);
return;
}
gameInstance.push_back(std::make_shared<Game>(gameName, gameStore));
Expand All @@ -209,25 +182,23 @@ void GameManager::addClientToGame(std::string gameName, std::shared_ptr<Client>

void GameManager::removeClientFromGame(std::string gameName, std::shared_ptr<Client> client)
{
auto &gamesStore = getInstance()->_gamesStore;
auto &gamesInstances = getInstance()->_gamesInstances;
auto &waitingClients = getInstance()->_waitingClients;
if (gamesStore.find(gameName) == gamesStore.end())
if (_gamesStore.find(gameName) == _gamesStore.end())
return FLAKKARI_LOG_ERROR("game not found"), void();

auto &waitingQueue = waitingClients[gameName];
auto &waitingQueue = _waitingClients[gameName];

auto minPlayers = gamesStore[gameName]->at("minPlayers").get<size_t>();
auto minPlayers = _gamesStore[gameName]->at("minPlayers").get<size_t>();

for (auto &instance : gamesInstances[gameName])
{
for (auto &instance : _gamesInstances[gameName]) {
if (!instance->removePlayer(client))
continue;

if (instance->getPlayers().empty())
{
gamesInstances[gameName].erase(
std::find(gamesInstances[gameName].begin(), gamesInstances[gameName].end(), instance));
if (instance->getPlayers().empty()) {
_gamesInstances[gameName].erase(
std::find(
_gamesInstances[gameName].begin(), _gamesInstances[gameName].end(), instance
)
);
FLAKKARI_LOG_INFO("game \"" + gameName + "\" removed");
}
else if (instance->getPlayers().size() > minPlayers)
Expand All @@ -252,14 +223,11 @@ void GameManager::removeClientFromGame(std::string gameName, std::shared_ptr<Cli

int GameManager::getIndexInWaitingQueue(std::string gameName, std::shared_ptr<Client> client)
{
auto &waitingClients = getInstance()->_waitingClients;
auto &gamesStore = getInstance()->_gamesStore;
if (gamesStore.find(gameName) == gamesStore.end())
if (_gamesStore.find(gameName) == _gamesStore.end())
return FLAKKARI_LOG_ERROR("game not found"), -1;

auto tmpQueue = waitingClients[gameName];
for (int i = 0; !tmpQueue.empty(); i++)
{
auto tmpQueue = _waitingClients[gameName];
for (int i = 0; !tmpQueue.empty(); i++) {
if (tmpQueue.front() == client)
return FLAKKARI_LOG_INFO("client \"" + STR_ADDRESS + "\" found in waiting queue at " + std::to_string(i)),
i;
Expand Down
191 changes: 87 additions & 104 deletions Flakkari/Server/Game/GameManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,120 +31,103 @@

namespace Flakkari {

class GameManager {
class GameManager : public Singleton<GameManager> {
private:
static std::shared_ptr<GameManager> _instance;
static std::mutex _mutex;
std::unordered_map<std::string /*gameName*/, std::queue<std::shared_ptr<Client>> /*waitingClients*/> _waitingClients;
std::unordered_map<std::string /*gameName*/, std::vector<std::shared_ptr<Game>> /*gamesInstances*/> _gamesInstances;
std::unordered_map<std::string /*gameName*/, std::shared_ptr<nlohmann::json> /*data*/> _gamesStore;
std::string _game_dir;

public:
std::unordered_map<std::string /*gameName*/, std::queue<std::shared_ptr<Client>> /*waitingClients*/>
_waitingClients;
std::unordered_map<std::string /*gameName*/, std::vector<std::shared_ptr<Game>> /*gamesInstances*/> _gamesInstances;
std::unordered_map<std::string /*gameName*/, std::shared_ptr<nlohmann::json> /*data*/> _gamesStore;
std::string _game_dir;

public:
GameManager(const GameManager &) = delete;
GameManager(const std::shared_ptr<GameManager> &) = delete;
void operator=(const GameManager &) = delete;
void operator=(const std::shared_ptr<GameManager> &) = delete;

/**
* @brief Construct a new GameManager object and load all games
* already present in the Games folder
*
*/
GameManager();
/**
* @brief Construct a new GameManager object and load all games
* already present in the Games folder
*
*/
explicit GameManager();

/**
* @brief Destroy the GameManager object
*
*/
~GameManager() = default;

/**
* @brief Get the instance of the GameManager
*
* @return std::shared_ptr<GameManager> instance of the GameManager
*/
static std::shared_ptr<GameManager> getInstance();

/**
* @brief Add a game to the GameManager and load it from the Games folder
*
* @param gameName Game to add
* @return 0 Game added
* @return 1 Game not added (already exists)
* @return 2 Game not added (certificate not valid) (not implemented)
* @return 3 Game not added (corrupted game) (not implemented)
*/
static int addGame(std::string gameName);

/**
* @brief Get the Game object
*
* @param gameName Game to get
* @return std::shared_ptr<Game> Game
*
* @deprecated Use getGameInstance instead
*/
static std::shared_ptr<Game> getGame(std::string gameName);

/**
* @brief Get the Games Instances object (all games loaded)
*
* @return std::vector<std::shared_ptr<Game>> Games Instances
*/
static std::vector<std::shared_ptr<Game>> getGamesInstances();

/**
* @brief Update a game from the GameManager
*
* @param gameName Game to update
* @return 0 Game updated
* @return 1 Game not updated (not found)
*/
static int updateGame(std::string gameName);

/**
* @brief Remove a game from the GameManager
*
* @param gameName Game to remove
* @return 0 Game removed
* @return 1 Game not removed (not found)
*/
static int removeGame(std::string gameName);

/**
* @brief List all games present in the GameManager
*
*/
static void listGames();

/**
* @brief Add a client to a game
*
* @param gameName Game to add the client to
* @param client Client to add to the game
*/
static void addClientToGame(std::string gameName, std::shared_ptr<Client> client);

/**
* @brief Remove a client from a game
*
* @param gameName Game to remove the client from
* @param client Client to remove from the game
*/
static void removeClientFromGame(std::string gameName, std::shared_ptr<Client> client);

/**
* @brief Get the index of a client in the waiting queue
*
* @param gameName Game to get the index from
* @param client Client to get the index of
* @return int Index of the client in the waiting queue
*/
static int getIndexInWaitingQueue(std::string gameName, std::shared_ptr<Client> client);
/**
* @brief Add a game to the GameManager and load it from the Games folder
*
* @param gameName Game to add
* @return 0 Game added
* @return 1 Game not added (already exists)
* @return 2 Game not added (certificate not valid) (not implemented)
* @return 3 Game not added (corrupted game) (not implemented)
*/
int addGame(std::string gameName);

/**
* @brief Get the Game object
*
* @param gameName Game to get
* @return std::shared_ptr<Game> Game
*
* @deprecated Use getGameInstance instead
*/
std::shared_ptr<Game> getGame(std::string gameName);

/**
* @brief Get the Games Instances object (all games loaded)
*
* @return std::vector<std::shared_ptr<Game>> Games Instances
*/
std::vector<std::shared_ptr<Game>> getGamesInstances();

/**
* @brief Update a game from the GameManager
*
* @param gameName Game to update
* @return 0 Game updated
* @return 1 Game not updated (not found)
*/
int updateGame(std::string gameName);

/**
* @brief Remove a game from the GameManager
*
* @param gameName Game to remove
* @return 0 Game removed
* @return 1 Game not removed (not found)
*/
int removeGame(std::string gameName);

/**
* @brief List all games present in the GameManager
*
*/
void listGames();

/**
* @brief Add a client to a game
*
* @param gameName Game to add the client to
* @param client Client to add to the game
*/
void addClientToGame(std::string gameName, std::shared_ptr<Client> client);

/**
* @brief Remove a client from a game
*
* @param gameName Game to remove the client from
* @param client Client to remove from the game
*/
void removeClientFromGame(std::string gameName, std::shared_ptr<Client> client);

/**
* @brief Get the index of a client in the waiting queue
*
* @param gameName Game to get the index from
* @param client Client to get the index of
* @return int Index of the client in the waiting queue
*/
int getIndexInWaitingQueue(std::string gameName, std::shared_ptr<Client> client);
};

} /* namespace Flakkari */
Expand Down
Loading

0 comments on commit f370cf7

Please sign in to comment.