diff --git a/CAPI/API/include/Communication.h b/CAPI/API/include/Communication.h index b1e678a..dbcdf2e 100644 --- a/CAPI/API/include/Communication.h +++ b/CAPI/API/include/Communication.h @@ -10,7 +10,9 @@ #include "structures.h" #include #include +#include #include +#include #include "ConcurrentQueue.hpp" class Logic; @@ -44,7 +46,6 @@ public: bool TryConnection(int64_t playerID); protobuf::MessageToClient GetMessage2Client(); - bool HaveMessage2Client(); void AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, THUAI6::HumanType humanType, THUAI6::ButcherType butcherType); void ReadMessage(int64_t playerID); @@ -54,6 +55,8 @@ private: bool haveNewMessage = false; protobuf::MessageToClient message2Client; ConcurrentQueue> messageQueue; + std::mutex mtxMessage; + std::condition_variable cvMessage; }; #endif diff --git a/CAPI/API/src/Communication.cpp b/CAPI/API/src/Communication.cpp index e189409..78d659f 100644 --- a/CAPI/API/src/Communication.cpp +++ b/CAPI/API/src/Communication.cpp @@ -2,6 +2,8 @@ #include "utils.hpp" #include "structures.h" #include +#include +#include using grpc::ClientContext; @@ -198,15 +200,13 @@ bool Communication::TryConnection(int64_t playerID) protobuf::MessageToClient Communication::GetMessage2Client() { + std::unique_lock lock(mtxMessage); + cvMessage.wait(lock, [this]() + { return haveNewMessage; }); haveNewMessage = false; return message2Client; } -bool Communication::HaveMessage2Client() -{ - return haveNewMessage; -} - std::optional> Communication::GetMessage() { return messageQueue.tryPop(); @@ -242,7 +242,13 @@ void Communication::AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, T auto MessageReader = THUAI6Stub->AddPlayer(&context, playerMsg); while (MessageReader->Read(&message2Client)) - haveNewMessage = true; + { + { + std::lock_guard lock(mtxMessage); + haveNewMessage = true; + } + cvMessage.notify_one(); + } }; std::thread(tMessage).detach(); } diff --git a/CAPI/API/src/logic.cpp b/CAPI/API/src/logic.cpp index 3ce9a3a..9046c6d 100644 --- a/CAPI/API/src/logic.cpp +++ b/CAPI/API/src/logic.cpp @@ -187,58 +187,54 @@ void Logic::ProcessMessage() pComm->ReadMessage(playerID); while (gameState != THUAI6::GameState::GameEnd) { - if (pComm->HaveMessage2Client()) + auto clientMsg = pComm->GetMessage2Client(); // 在获得新消息之前阻塞 + logger->debug("Get message from server!"); + gameState = Proto2THUAI6::gameStateDict[clientMsg.game_state()]; + switch (gameState) { - logger->debug("Get message from server!"); - auto clientMsg = pComm->GetMessage2Client(); - gameState = Proto2THUAI6::gameStateDict[clientMsg.game_state()]; - switch (gameState) - { - case THUAI6::GameState::GameStart: - logger->info("Game Start!"); - - // 重新读取玩家的guid,guid确保人类在前屠夫在后 - playerGUIDs.clear(); - for (auto human : clientMsg.human_message()) - playerGUIDs.push_back(human.guid()); - for (auto butcher : clientMsg.butcher_message()) - playerGUIDs.push_back(butcher.guid()); - currentState->guids = playerGUIDs; - bufferState->guids = playerGUIDs; - - LoadBuffer(clientMsg); - - AILoop = true; - UnBlockAI(); - - break; - case THUAI6::GameState::GameRunning: - // 重新读取玩家的guid,guid确保人类在前屠夫在后 - playerGUIDs.clear(); - for (auto human : clientMsg.human_message()) - playerGUIDs.push_back(human.guid()); - for (auto butcher : clientMsg.butcher_message()) - playerGUIDs.push_back(butcher.guid()); - currentState->guids = playerGUIDs; - bufferState->guids = playerGUIDs; - - LoadBuffer(clientMsg); - break; - case THUAI6::GameState::GameEnd: - AILoop = false; - { - std::lock_guard lock(mtxBuffer); - bufferUpdated = true; - counterBuffer = -1; - } - cvBuffer.notify_one(); - logger->info("Game End!"); - break; - default: - logger->debug("Unknown GameState!"); - } + case THUAI6::GameState::GameStart: + logger->info("Game Start!"); + + // 重新读取玩家的guid,guid确保人类在前屠夫在后 + playerGUIDs.clear(); + for (auto human : clientMsg.human_message()) + playerGUIDs.push_back(human.guid()); + for (auto butcher : clientMsg.butcher_message()) + playerGUIDs.push_back(butcher.guid()); + currentState->guids = playerGUIDs; + bufferState->guids = playerGUIDs; + + LoadBuffer(clientMsg); + + AILoop = true; + UnBlockAI(); + + break; + case THUAI6::GameState::GameRunning: + // 重新读取玩家的guid,guid确保人类在前屠夫在后 + playerGUIDs.clear(); + for (auto human : clientMsg.human_message()) + playerGUIDs.push_back(human.guid()); + for (auto butcher : clientMsg.butcher_message()) + playerGUIDs.push_back(butcher.guid()); + currentState->guids = playerGUIDs; + bufferState->guids = playerGUIDs; + + LoadBuffer(clientMsg); + break; + default: + logger->debug("Unknown GameState!"); + break; } } + AILoop = false; + { + std::lock_guard lock(mtxBuffer); + bufferUpdated = true; + counterBuffer = -1; + } + cvBuffer.notify_one(); + logger->info("Game End!"); }; std::thread(messageThread).detach(); } @@ -428,8 +424,7 @@ const std::vector Logic::GetPlayerGUIDs() const bool Logic::TryConnection() { logger->info("Try to connect to server..."); - bool result = pComm->TryConnection(playerID); - return result; + return pComm->TryConnection(playerID); } void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool file, bool print, bool warnOnly)