Skip to content

Commit

Permalink
Merge pull request #274 from FppEpitech/feat/implement-multithreading…
Browse files Browse the repository at this point in the history
…-for-network-and-guiupdater-zappy-gui

Feat/implement multithreading for network and guiupdater zappy gui
  • Loading branch information
Thomaltarix authored Jun 23, 2024
2 parents 6c29b02 + 0fb9893 commit 960e1fd
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 87 deletions.
10 changes: 10 additions & 0 deletions gui/include/Engine/Engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "Parsing/ServerParser.hpp"
#include "GUIUpdater/GUIUpdater.hpp"

#include <thread>
#include <time.h>

#define TIME_UNIT_MAP_UPDATE 20
Expand Down Expand Up @@ -47,6 +48,7 @@ class Gui::Engine {
/**
* @brief Run the engine loop.
*
* @note This method runs in the main thread.
*/
void run();

Expand All @@ -58,6 +60,7 @@ class Gui::Engine {
std::unique_ptr<IEvent> _event; //!< Event class to listen the user's inputs.
std::shared_ptr<GameData> _gameData; //!< GameData class to store the game's data.
std::unique_ptr<IGUIUpdater> _guiUpdater; //!< GUIUpdater class to update the GUI.
std::thread _networkThread; //!< Thread to listen the server and update the GameData.

/**
* @brief Listen the server and update Engine with its commands.
Expand Down Expand Up @@ -85,4 +88,11 @@ class Gui::Engine {
*
*/
void sendUpdateMapMessage();

/**
* @brief Thread loop for the network thread.
*
* @note This method runs in a separate thread.
*/
void threadLoop();
};
53 changes: 49 additions & 4 deletions gui/include/GameDatas/GameData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ class Gui::GameData {
* @brief Add a team to the game.
*
* @param name Name of the team.
* @param playerModelPath Path to the asset of the team for players.
* @param eggModelPath Path to the asset of the team for eggs.
* @param playerColor Color of the team.
*/
void addTeam(const std::string &name, const std::string &playerModelPath, const std::string &eggModelPath, Color playerColor);
void addTeam(const std::string &name, Color playerColor);

/**
* @brief Add a player to a team.
Expand Down Expand Up @@ -280,6 +278,48 @@ class Gui::GameData {
*/
std::string getEndMessage() const;

/**
* @brief Set the Player Model object.
*
* @param playerModel Model asset of the Team.
*/
void setPlayerModel(const Model &playerModel);

/**
* @brief Set the Egg Model object.
*
* @param eggModel Model asset of the Team.
*/
void setEggModel(const Model &eggModel);

/**
* @brief Set the Player Model Animation object.
*
* @param playerModelAnimation Model to animate players.
*/
void setPlayerModelAnimation(ModelAnimation *playerModelAnimation);

/**
* @brief Get the Player Model Animation object.
*
* @return ModelAnimation* - Model to animate players.
*/
void setAnimsCount(int animsCount);

/**
* @brief Get the Anims Count object.
*
* @return int - Animation number of players.
*/
void setServerError(bool isServerError);

/**
* @brief Get the Server Error object.
*
* @return bool - True if the server is in error.
*/
bool getServerError() const;

private:

std::vector<Gui::Team> _teams; //!< Teams of the game.
Expand All @@ -292,5 +332,10 @@ class Gui::GameData {
std::string _lastError; //!< Last error message.
TimeUnitState _timeUnitFromServer; //!< True if the time unit has changed.
std::vector<Gui::Egg> _serverEggs; //!< Eggs from the server.
std::string _endMessage; //!< End message of the game.
std::string _endMessage; //!< End message of the game.
Model _playerModel; //!< Model asset of the Team.
Model _eggModel; //!< Model asset of the Team.
ModelAnimation* _playerModelAnimation; //!< Model to animate players.
int _animsCount; //!< Animation number of players.
bool _isServerError; //!< True if the server is in error.
};
7 changes: 3 additions & 4 deletions gui/include/GameDatas/Team.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ class Gui::Team {
* @brief Construct a new Team object.
*
* @param name Name of the team.
* @param playerModelPath Path to the team model asset for players.
* @param eggSkinPath Path to the skin of the team.
* @param playerModel Model asset of the team.
* @param eggSkin Model asset of the eggs.
* @param playerColor Color of the players.
*/
Team(const std::string &name, const std::string &playerModelPath, const std::string &eggModelPath, Color playerColor);
Team(const std::string &name, Model playerModel, Model eggModel, ModelAnimation *modelAnimation, Color playerColor);

/**
* @brief Destroy the Team object.
Expand Down Expand Up @@ -199,7 +199,6 @@ class Gui::Team {

private:


ModelAnimation* _modelAnimation; //!< Model to animate players.
int _animsCount; //!< Animation number of players.
std::string _name; //!< Name of the team.
Expand Down
16 changes: 12 additions & 4 deletions gui/src/Engine/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ Gui::Engine::Engine(std::shared_ptr<INetwork> network) : _network(network)

void Gui::Engine::run()
{
while (_render->isOpen()) {
listenServer();
_networkThread = std::thread(&Gui::Engine::threadLoop, this);
while (_render->isOpen() && !_gameData->getServerError()) {
_render->draw();
_event->listen();
sendMessageUpdate();
}
if (_networkThread.joinable())
_networkThread.join();
}

void Gui::Engine::listenServer()
Expand All @@ -39,8 +41,8 @@ void Gui::Engine::listenServer()
if (bufferState == Gui::INetwork::BufferState::NONE)
return;
if (bufferState == Gui::INetwork::BufferState::SERVER_ERROR) {
std::cout << STR_RED << SERVER_DOWN_MESSAGE << STR_RESET << std::endl;
_gameData.get()->setIsEndGame(true);
if (!_gameData.get()->getIsEndGame())
_gameData.get()->setServerError(true);
return;
}
try {
Expand Down Expand Up @@ -95,3 +97,9 @@ void Gui::Engine::sendUpdateMapMessage()
_gameData.get()->setNbBCTCommandReceived(0);
_gameData.get()->restartLastTickMctCommand();
}

void Gui::Engine::threadLoop()
{
while (_render->isOpen() && (!_gameData->getServerError()) && (!_gameData.get()->getIsEndGame()))
listenServer();
}
2 changes: 1 addition & 1 deletion gui/src/GUIUpdater/GUIUpdater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ void Gui::GUIUpdater::updateTeamNames(const std::vector<std::string> &data)
{
try {
for (size_t i = 0; i < data.size(); i++) {
_gameData->addTeam(data[i], MODEL_PLAYER, MODEL_EGG, playerColors[_colorIndex]);
_gameData->addTeam(data[i], playerColors[_colorIndex]);
increaseColorIndex();
}
} catch (const std::exception &error) {
Expand Down
35 changes: 33 additions & 2 deletions gui/src/GameDatas/GameData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Gui::GameData::GameData()
_nbBCTCommandReceived = 0;
_timeUnitFromServer = TimeUnitState::NONE;
_endMessage = "";
_isServerError = false;
}

std::vector<Gui::Team> &Gui::GameData::getTeams()
Expand All @@ -44,13 +45,13 @@ void Gui::GameData::addTeam(const Gui::Team &team)
_teams.push_back(team);
}

void Gui::GameData::addTeam(const std::string &name, const std::string &playerModelPath, const std::string &eggModelPath, Color playerColor)
void Gui::GameData::addTeam(const std::string &name, Color playerColor)
{
for (auto &regsiteredTeam : _teams) {
if (regsiteredTeam.getName() == name)
throw Gui::Errors::GuiGameDataException("Team already exists");
}
_teams.push_back(Gui::Team(name, playerModelPath, eggModelPath, playerColor));
_teams.push_back(Gui::Team(name, _playerModel, _eggModel, _playerModelAnimation, playerColor));
}

void Gui::GameData::addPlayerToTeam(const std::string &teamName, const Gui::Player &player)
Expand Down Expand Up @@ -239,3 +240,33 @@ std::string Gui::GameData::getEndMessage() const
{
return _endMessage;
}

void Gui::GameData::setPlayerModel(const Model &playerModel)
{
_playerModel = playerModel;
}

void Gui::GameData::setEggModel(const Model &eggModel)
{
_eggModel = eggModel;
}

void Gui::GameData::setPlayerModelAnimation(ModelAnimation *playerModelAnimation)
{
_playerModelAnimation = playerModelAnimation;
}

void Gui::GameData::setAnimsCount(int count)
{
_animsCount = count;
}

void Gui::GameData::setServerError(bool isServerError)
{
_isServerError = isServerError;
}

bool Gui::GameData::getServerError() const
{
return _isServerError;
}
9 changes: 4 additions & 5 deletions gui/src/GameDatas/Team.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@
#include "GameDatas/Team.hpp"
#include "raymath.h"

Gui::Team::Team(const std::string &name, const std::string &playerModelPath, const std::string &eggModelPath, Color playerColor) : _name(name), _playerColor(playerColor)
Gui::Team::Team(const std::string &name, Model playerModel, Model eggModel, ModelAnimation* modelAnimation, Color playerColor) : _name(name), _playerColor(playerColor)
{
_playerModel = LoadModel(playerModelPath.c_str());
_eggModel = LoadModel(eggModelPath.c_str());
_animsCount = 0;
_modelAnimation = LoadModelAnimations(MODEL_PLAYER, &_animsCount);
_playerModel = playerModel;
_eggModel = eggModel;
_modelAnimation = modelAnimation;
}

const std::string &Gui::Team::getName() const
Expand Down
8 changes: 6 additions & 2 deletions gui/src/Network/Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ Gui::Network::BufferState Gui::Network::listenServer()
selectServer();
BufferState bufferSate = readInfoServer();
if (!_isConnected && _buffer == "WELCOME" && bufferSate == READY) {
_isConnected = true;
sendMessageServer("GRAPHIC\n");
sendMessageServer("sgt\n");
sendMessageServer("msz\n");
sendMessageServer("mct\n");
sendMessageServer("tna\n");
_isConnected = true;
_buffer = "";
return Gui::Network::NONE;
}
Expand All @@ -76,13 +76,17 @@ Gui::Network::BufferState Gui::Network::readInfoServer()
return READY;
_buffer.append(&buffer, 1);
}
if (len == 0)
if (len == 0) {
_isConnected = false;
return SERVER_ERROR;
}
return NONE;
}

void Gui::Network::sendMessageServer(const std::string &message)
{
if (!_isConnected)
return;
if (FD_ISSET(_serverFd, &_writeFd)) {
write(_serverFd, message.c_str(), message.length());
std::cerr << STR_VIOLET << "Send: " << STR_CYAN << message << STR_RESET << std::endl;
Expand Down
13 changes: 12 additions & 1 deletion gui/src/Render/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ Gui::Render::Render(std::shared_ptr<GameData> gameData)
_renderDistance = DEFAULT_RENDER_DISTANCE;
_isHelpMenu = false;
_endHudSet = false;
int animCount = 0;
_gameData.get()->setAnimsCount(animCount);
}

void Gui::Render::LoadModels(void)
void Gui::Render::LoadModels()
{
_tileModel = LoadModel(MODEL_TILE);
_foodModel = LoadModel(MODEL_FOOD);
Expand All @@ -41,6 +43,15 @@ void Gui::Render::LoadModels(void)
_thystameModel = LoadModel(MODEL_THYSTAME);
_deraumereModel = LoadModel(MODEL_DERAUMERE);

int animCount = 0;
Model playerModel = LoadModel(MODEL_PLAYER);
Model eggModel = LoadModel(MODEL_EGG);
ModelAnimation* playerModelAnimation = LoadModelAnimations(MODEL_PLAYER, &animCount);
_gameData.get()->setAnimsCount(animCount);
_gameData.get()->setPlayerModel(playerModel);
_gameData.get()->setEggModel(eggModel);
_gameData.get()->setPlayerModelAnimation(playerModelAnimation);

_cursorTexture = LoadTexture(PNG_CURSOR);
}

Expand Down
2 changes: 2 additions & 0 deletions gui/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
#include "Parsing/ParseCommandLine.hpp"

#include <iostream>
#include <signal.h>

int main(int argc, char **argv)
{
signal(SIGPIPE, SIG_IGN);
try {
Gui::ParseCommandLine parseLine(argc, argv);
Gui::Network net(parseLine.getPort(), parseLine.getHostName());
Expand Down
Loading

0 comments on commit 960e1fd

Please sign in to comment.