Browse Source

Merge pull request #35 from DragonAura/dev

refactor(CAPI): 🎨 unbind  logic and communication
tags/0.1.0
wihn GitHub 3 years ago
parent
commit
8c8fede4d3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 331 additions and 102 deletions
  1. +1
    -3
      CAPI/API/include/API.h
  2. +40
    -0
      CAPI/API/include/Communication.h
  3. +2
    -1
      CAPI/API/include/logic.h
  4. +6
    -0
      CAPI/API/src/API.cpp
  5. +152
    -0
      CAPI/API/src/Communication.cpp
  6. +130
    -98
      CAPI/API/src/logic.cpp

+ 1
- 3
CAPI/API/include/API.h View File

@@ -173,9 +173,7 @@ public:
} }
void Play(IAI& ai) override; void Play(IAI& ai) override;


std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override
{
}
std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;


[[nodiscard]] int GetFrameCount() const override [[nodiscard]] int GetFrameCount() const override
{ {


+ 40
- 0
CAPI/API/include/Communication.h View File

@@ -0,0 +1,40 @@
#ifndef COMMUNICATION_H
#define COMMUNICATION_H

#include "Message2Server.pb.h"
#include "Message2Clients.pb.h"
#include "MessageType.pb.h"
#include "Services.grpc.pb.h"
#include "Services.pb.h"
#include <grpcpp/grpcpp.h>
#include "structures.h"

class Logic;

class Communication
{
public:
Communication(std::string sIP, std::string sPort);
~Communication()
{
}
bool Move(int64_t time, double angle, int64_t playerID);
bool PickProp(THUAI6::PropType prop, int64_t playerID);
bool UseProp(int64_t playerID);
bool UseSkill(int64_t playerID);
bool SendMessage(int64_t toID, std::string message, int64_t playerID);
bool HaveMessage(int64_t playerID);
std::pair<std::string, int64_t> GetMessage(int64_t playerID);
bool Escape(int64_t playerID);
bool TryConnection(int64_t playerID);
protobuf::MessageToClient GetMessage2Client();
bool HaveMessage2Client();
void AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, THUAI6::HumanType humanType, THUAI6::ButcherType butcherType);

private:
std::unique_ptr<protobuf::AvailableService::Stub> THUAI6Stub;
bool haveNewMessage = false;
protobuf::MessageToClient message2Client;
};

#endif

+ 2
- 1
CAPI/API/include/logic.h View File

@@ -23,13 +23,14 @@
#include "AI.h" #include "AI.h"
#include "structures.h" #include "structures.h"
#include "state.h" #include "state.h"
#include "Communication.h"


// 封装了通信组件和对AI对象进行操作 // 封装了通信组件和对AI对象进行操作
class Logic : public ILogic class Logic : public ILogic
{ {
private: private:
// gRPC客户端的stub,所有与服务端之间的通信操作都需要基于stub完成。 // gRPC客户端的stub,所有与服务端之间的通信操作都需要基于stub完成。
std::unique_ptr<protobuf::AvailableService::Stub> THUAI6Stub;
std::unique_ptr<Communication> pComm;
// ID、阵营记录 // ID、阵营记录
int64_t playerID; int64_t playerID;
THUAI6::PlayerType playerType; THUAI6::PlayerType playerType;


+ 6
- 0
CAPI/API/src/API.cpp View File

@@ -1,6 +1,12 @@
#include "AI.h" #include "AI.h"
#include "API.h" #include "API.h"


std::future<bool> HumanAPI::Move(int64_t timeInMilliseconds, double angleInRadian)
{
return std::async(std::launch::async, [&]()
{ return logic.Move(timeInMilliseconds, angleInRadian); });
}

void HumanAPI::Play(IAI& ai) void HumanAPI::Play(IAI& ai)
{ {
ai.play(*this); ai.play(*this);


+ 152
- 0
CAPI/API/src/Communication.cpp View File

@@ -0,0 +1,152 @@
#include "Communication.h"
#include "utils.hpp"
#include "structures.h"
#include <thread>

using grpc::ClientContext;

Communication::Communication(std::string sIP, std::string sPort)
{
std::string aim = sIP + ':' + sPort;
auto channel = grpc::CreateChannel(aim, grpc::InsecureChannelCredentials());
THUAI6Stub = protobuf::AvailableService::NewStub(channel);
}

bool Communication::Move(int64_t time, double angle, int64_t playerID)
{
protobuf::MoveRes moveResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufMove(time, angle, playerID);
std::cout << "Move request sent" << std::endl;
auto status = THUAI6Stub->Move(&context, request, &moveResult);
if (status.ok())
return moveResult.act_success();
else
return false;
}

bool Communication::PickProp(THUAI6::PropType prop, int64_t playerID)
{
protobuf::BoolRes pickPropResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufPick(prop, playerID);
auto status = THUAI6Stub->PickProp(&context, request, &pickPropResult);
if (status.ok())
return pickPropResult.act_success();
else
return false;
}

bool Communication::UseProp(int64_t playerID)
{
protobuf::BoolRes usePropResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->UseProp(&context, request, &usePropResult);
if (status.ok())
return usePropResult.act_success();
else
return false;
}

bool Communication::UseSkill(int64_t playerID)
{
protobuf::BoolRes useSkillResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->UseSkill(&context, request, &useSkillResult);
if (status.ok())
return useSkillResult.act_success();
else
return false;
}

bool Communication::SendMessage(int64_t toID, std::string message, int64_t playerID)
{
protobuf::BoolRes sendMessageResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufSend(message, toID, playerID);
auto status = THUAI6Stub->SendMessage(&context, request, &sendMessageResult);
if (status.ok())
return sendMessageResult.act_success();
else
return false;
}

bool Communication::HaveMessage(int64_t playerID)
{
protobuf::BoolRes haveMessageResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->HaveMessage(&context, request, &haveMessageResult);
if (status.ok())
return haveMessageResult.act_success();
else
return false;
}

std::pair<std::string, int64_t> Communication::GetMessage(int64_t playerID)
{
protobuf::MsgRes getMessageResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->GetMessage(&context, request, &getMessageResult);
if (status.ok())
{
if (getMessageResult.have_message())
return std::make_pair(getMessageResult.message_received(), getMessageResult.from_player_id());
else
return std::make_pair("", -1);
}
else
return std::make_pair("", -1);
}

bool Communication::Escape(int64_t playerID)
{
protobuf::BoolRes escapeResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->Escape(&context, request, &escapeResult);
if (status.ok())
return escapeResult.act_success();
else
return false;
}

bool Communication::TryConnection(int64_t playerID)
{
protobuf::BoolRes reply;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->TryConnection(&context, request, &reply);
if (status.ok())
return true;
else
return false;
}

protobuf::MessageToClient Communication::GetMessage2Client()
{
haveNewMessage = false;
return message2Client;
}

bool Communication::HaveMessage2Client()
{
return haveNewMessage;
}

void Communication::AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, THUAI6::HumanType humanType, THUAI6::ButcherType butcherType)
{
auto msgThread = [&]()
{
protobuf::PlayerMsg playerMsg = THUAI62Proto::THUAI62ProtobufPlayer(playerID, playerType, humanType, butcherType);
grpc::ClientContext context;
auto MessageReader = THUAI6Stub->AddPlayer(&context, playerMsg);

while (MessageReader->Read(&message2Client))
haveNewMessage = true;
};
std::thread(msgThread).detach();
}

+ 130
- 98
CAPI/API/src/logic.cpp View File

@@ -3,9 +3,10 @@
#include <grpcpp/grpcpp.h> #include <grpcpp/grpcpp.h>
#include <functional> #include <functional>
#include "utils.hpp" #include "utils.hpp"
using namespace protobuf;
using grpc::ClientContext;
using grpc::Status;
#include "Communication.h"

// using grpc::ClientContext;
// using grpc::Status;


extern const THUAI6::PlayerType playerType; extern const THUAI6::PlayerType playerType;


@@ -57,119 +58,145 @@ std::vector<std::vector<THUAI6::PlaceType>> Logic::GetFullMap() const


bool Logic::Move(int64_t time, double angle) bool Logic::Move(int64_t time, double angle)
{ {
protobuf::MoveRes moveResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufMove(time, angle, playerID);
auto status = THUAI6Stub->Move(&context, request, &moveResult);
if (status.ok())
return moveResult.act_success();
else
return false;
// protobuf::MoveRes moveResult;
// ClientContext context;
// auto request = THUAI62Proto::THUAI62ProtobufMove(time, angle, playerID);
// auto status = THUAI6Stub->Move(&context, request, &moveResult);
// if (status.ok())
// return moveResult.act_success();
// else
// return false;
return pComm->Move(time, angle, playerID);
} }


bool Logic::PickProp(THUAI6::PropType prop) bool Logic::PickProp(THUAI6::PropType prop)
{ {
protobuf::BoolRes pickPropResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufPick(prop, playerID);
auto status = THUAI6Stub->PickProp(&context, request, &pickPropResult);
if (status.ok())
return pickPropResult.act_success();
else
return false;
// protobuf::BoolRes pickPropResult;
// ClientContext context;
// auto request = THUAI62Proto::THUAI62ProtobufPick(prop, playerID);
// auto status = THUAI6Stub->PickProp(&context, request, &pickPropResult);
// if (status.ok())
// return pickPropResult.act_success();
// else
// return false;

return pComm->PickProp(prop, playerID);
} }


bool Logic::UseProp() bool Logic::UseProp()
{ {
protobuf::BoolRes usePropResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->UseProp(&context, request, &usePropResult);
if (status.ok())
return usePropResult.act_success();
else
return false;
// protobuf::BoolRes usePropResult;
// ClientContext context;
// auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
// auto status = THUAI6Stub->UseProp(&context, request, &usePropResult);
// if (status.ok())
// return usePropResult.act_success();
// else
// return false;
return pComm->UseProp(playerID);
} }


bool Logic::UseSkill() bool Logic::UseSkill()
{ {
protobuf::BoolRes useSkillResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->UseSkill(&context, request, &useSkillResult);
if (status.ok())
return useSkillResult.act_success();
else
return false;
// protobuf::BoolRes useSkillResult;
// ClientContext context;
// auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
// auto status = THUAI6Stub->UseSkill(&context, request, &useSkillResult);
// if (status.ok())
// return useSkillResult.act_success();
// else
// return false;

return pComm->UseSkill(playerID);
} }


bool Logic::SendMessage(int64_t toID, std::string message) bool Logic::SendMessage(int64_t toID, std::string message)
{ {
protobuf::BoolRes sendMessageResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufSend(message, toID, playerID);
auto status = THUAI6Stub->SendMessage(&context, request, &sendMessageResult);
if (status.ok())
return sendMessageResult.act_success();
else
return false;
// protobuf::BoolRes sendMessageResult;
// ClientContext context;
// auto request = THUAI62Proto::THUAI62ProtobufSend(message, toID, playerID);
// auto status = THUAI6Stub->SendMessage(&context, request, &sendMessageResult);
// if (status.ok())
// return sendMessageResult.act_success();
// else
// return false;

return pComm->SendMessage(toID, message, playerID);
} }


bool Logic::HaveMessage() bool Logic::HaveMessage()
{ {
protobuf::BoolRes haveMessageResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->HaveMessage(&context, request, &haveMessageResult);
if (status.ok())
return haveMessageResult.act_success();
else
return false;
// protobuf::BoolRes haveMessageResult;
// ClientContext context;
// auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
// auto status = THUAI6Stub->HaveMessage(&context, request, &haveMessageResult);
// if (status.ok())
// return haveMessageResult.act_success();
// else
// return false;

return pComm->HaveMessage(playerID);
} }


std::pair<std::string, int64_t> Logic::GetMessage() std::pair<std::string, int64_t> Logic::GetMessage()
{ {
protobuf::MsgRes getMessageResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->GetMessage(&context, request, &getMessageResult);
if (status.ok())
{
if (getMessageResult.have_message())
return std::make_pair(getMessageResult.message_received(), getMessageResult.from_player_id());
else
return std::make_pair("", -1);
}
else
return std::make_pair("", -1);
// protobuf::MsgRes getMessageResult;
// ClientContext context;
// auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
// auto status = THUAI6Stub->GetMessage(&context, request, &getMessageResult);
// if (status.ok())
// {
// if (getMessageResult.have_message())
// return std::make_pair(getMessageResult.message_received(), getMessageResult.from_player_id());
// else
// return std::make_pair("", -1);
// }
// else
// return std::make_pair("", -1);

return pComm->GetMessage(playerID);
} }


bool Logic::Escape() bool Logic::Escape()
{ {
protobuf::BoolRes escapeResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->Escape(&context, request, &escapeResult);
if (status.ok())
return escapeResult.act_success();
else
return false;
// protobuf::BoolRes escapeResult;
// ClientContext context;
// auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
// auto status = THUAI6Stub->Escape(&context, request, &escapeResult);
// if (status.ok())
// return escapeResult.act_success();
// else
// return false;

return pComm->Escape(playerID);
} }


void Logic::ProcessMessage() void Logic::ProcessMessage()
{ {
auto messageThread = [&]() auto messageThread = [&]()
{ {
// 首先设置消息、通过加入游戏,开始与服务端建立联系
protobuf::MessageToClient clientMsg;
protobuf::PlayerMsg playerMsg = THUAI62Proto::THUAI62ProtobufPlayer(playerID, playerType, humanType, butcherType);
grpc::ClientContext context;
auto MessageReader = THUAI6Stub->AddPlayer(&context, playerMsg);

// 持续读取服务端的消息
while (MessageReader->Read(&clientMsg))
// // 首先设置消息、通过加入游戏,开始与服务端建立联系
// protobuf::MessageToClient clientMsg;
// protobuf::PlayerMsg playerMsg = THUAI62Proto::THUAI62ProtobufPlayer(playerID, playerType, humanType, butcherType);
// grpc::ClientContext context;
// auto MessageReader = THUAI6Stub->AddPlayer(&context, playerMsg);

// // 持续读取服务端的消息
// while (MessageReader->Read(&clientMsg))
// {
// LoadBuffer(clientMsg);
// }

std::cout << "Join Player!" << std::endl;
pComm->AddPlayer(playerID, playerType, humanType, butcherType);
while (true)
{ {
LoadBuffer(clientMsg);
if (pComm->HaveMessage2Client())
{
std::cout << "Get Message!" << std::endl;
auto clientMsg = pComm->GetMessage2Client();
LoadBuffer(clientMsg);
}
} }
}; };
std::thread(messageThread).detach(); std::thread(messageThread).detach();
@@ -186,6 +213,8 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message)
bufferState->butchers.clear(); bufferState->butchers.clear();
bufferState->props.clear(); bufferState->props.clear();


std::cout << "Buffer clear!" << std::endl;

// 读取新的信息 // 读取新的信息
// 读取消息的选择待补充,之后需要另外判断;具体做法应该是先读到自己,然后按照自己的视野做处理。此处暂时全部读了进来 // 读取消息的选择待补充,之后需要另外判断;具体做法应该是先读到自己,然后按照自己的视野做处理。此处暂时全部读了进来
for (auto itr = message.human_message().begin(); itr != message.human_message().end(); itr++) for (auto itr = message.human_message().begin(); itr != message.human_message().end(); itr++)
@@ -196,7 +225,10 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message)
bufferState->humans.push_back(Proto2THUAI6::Protobuf2THUAI6Human(*itr)); bufferState->humans.push_back(Proto2THUAI6::Protobuf2THUAI6Human(*itr));
} }
else else
{
bufferState->humans.push_back(Proto2THUAI6::Protobuf2THUAI6Human(*itr)); bufferState->humans.push_back(Proto2THUAI6::Protobuf2THUAI6Human(*itr));
std::cout << "Add Human!" << std::endl;
}
} }
for (auto itr = message.butcher_message().begin(); itr != message.butcher_message().end(); itr++) for (auto itr = message.butcher_message().begin(); itr != message.butcher_message().end(); itr++)
{ {
@@ -220,24 +252,25 @@ void Logic::Update() noexcept


void Logic::PlayerWrapper(std::function<void()> player) void Logic::PlayerWrapper(std::function<void()> player)
{ {
{
std::unique_lock<std::mutex> lock(mtxAI);
cvAI.wait(lock, [this]()
{ return AIStart; });
}
// {
// std::unique_lock<std::mutex> lock(mtxAI);
// cvAI.wait(lock, [this]()
// { return AIStart; });
// }
player(); player();
} }


bool Logic::TryConnection() bool Logic::TryConnection()
{ {
IDMsg request = THUAI62Proto::THUAI62ProtobufID(playerID);
BoolRes reply;
ClientContext context;
auto status = THUAI6Stub->TryConnection(&context, request, &reply);
if (status.ok())
return true;
else
return false;
// IDMsg request = THUAI62Proto::THUAI62ProtobufID(playerID);
// BoolRes reply;
// ClientContext context;
// auto status = THUAI6Stub->TryConnection(&context, request, &reply);
// if (status.ok())
// return true;
// else
// return false;
return pComm->TryConnection(playerID);
} }


void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port) void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
@@ -245,10 +278,8 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
// 构造AI // 构造AI
pAI = createAI(); pAI = createAI();


// 建立与服务器之间通信的Stub
std::string aim = IP + ':' + port;
auto channel = grpc::CreateChannel(aim, grpc::InsecureChannelCredentials());
THUAI6Stub = protobuf::AvailableService::NewStub(channel);
// 建立与服务器之间通信的组件
pComm = std::make_unique<Communication>(IP, port);


// 构造timer // 构造timer
if (playerType == THUAI6::PlayerType::HumanPlayer) if (playerType == THUAI6::PlayerType::HumanPlayer)
@@ -260,6 +291,7 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
auto AIThread = [&, this]() auto AIThread = [&, this]()
{ {
auto ai = createAI(); auto ai = createAI();
ProcessMessage();
while (AILoop) while (AILoop)
{ {
Update(); Update();


Loading…
Cancel
Save