From fd7ba832e81e26bdb5ad2eeadf0a460e869144a2 Mon Sep 17 00:00:00 2001 From: dgant Date: Tue, 21 Nov 2017 21:14:34 +0000 Subject: [PATCH] Updated BWEnv controller to handle FlatBuffer-serialized frames. Added README describing serialization tests. --- .gitignore | 2 +- BWEnv/include/controller.h | 4 ++-- BWEnv/include/zmq_server.h | 2 +- BWEnv/src/controller.cc | 39 +++++++++++++++++++------------------- BWEnv/src/utils.cc | 5 ++++- BWEnv/src/zmq_server.cc | 4 ++-- replayer/README.md | 5 +++++ 7 files changed, 35 insertions(+), 26 deletions(-) create mode 100644 replayer/README.md diff --git a/.gitignore b/.gitignore index 7b40fd9..9dff0d8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,10 @@ /build.luarocks/ /build/ +/BWEnv/build/ ## VisualStudio ########### -/BWEnv/build/ # User-specific files *.suo *.user diff --git a/BWEnv/include/controller.h b/BWEnv/include/controller.h index 8d9df7c..6f64d8d 100644 --- a/BWEnv/include/controller.h +++ b/BWEnv/include/controller.h @@ -139,7 +139,7 @@ class Controller { bool is_client; private: - void serializeFrameData(torchcraft::fbs::FrameDataT*); + void serializeFrameData(torchcraft::fbs::FrameOrFrameDiffUnion& frameOrFrameDiff); std::unique_ptr config_; bool sent_battle_end_frame = false; bool game_ended = false; @@ -161,7 +161,7 @@ class Controller { bool blocking_ = true; int max_frame_time_ms_ = 50; std::vector, std::string>> draw_cmds_; - torchcraft::fbs::FrameT tcframe_; + torchcraft::fbs::StateUpdateT tcframe_; }; #endif // TORCHCRAFT_CONTROL_H_ diff --git a/BWEnv/include/zmq_server.h b/BWEnv/include/zmq_server.h index 4339d1a..8067ca4 100755 --- a/BWEnv/include/zmq_server.h +++ b/BWEnv/include/zmq_server.h @@ -38,7 +38,7 @@ class ZMQ_server void connect(); void close(); void sendHandshake(const torchcraft::fbs::HandshakeServerT* handshake); - void sendFrame(const torchcraft::fbs::FrameT* frame); + void sendFrame(const torchcraft::fbs::StateUpdateT* stateUpdate); void sendPlayerLeft(const torchcraft::fbs::PlayerLeftT *pl); void sendEndGame(const torchcraft::fbs::EndGameT *endgame); void sendError(const torchcraft::fbs::ErrorT *error); diff --git a/BWEnv/src/controller.cc b/BWEnv/src/controller.cc index 9fc61f8..59ae0d4 100644 --- a/BWEnv/src/controller.cc +++ b/BWEnv/src/controller.cc @@ -578,6 +578,7 @@ int Controller::getAttackFrames(int unitID) { int unitType = BWAPI::Broodwar->getUnit(unitID)->getType().getID(); // From // https://docs.google.com/spreadsheets/d/1bsvPvFil-kpvEUfSG74U3E5PLSTC02JxSkiR8QdLMuw/edit#gid=0 + // Photon Cannons may also have a value. if (unitType == BWAPI::UnitTypes::Enum::Protoss_Dragoon) { attackFrames += 5; } else if (unitType == BWAPI::UnitTypes::Enum::Zerg_Devourer) { @@ -586,21 +587,23 @@ int Controller::getAttackFrames(int unitID) { return attackFrames; } -void Controller::serializeFrameData(torchcraft::fbs::FrameDataT* data) { - std::ostringstream out; - if (prev_sent_frame == nullptr) { - out << *last_frame; - data->is_diff = false; - } else { - out << replayer::frame_diff(last_frame, prev_sent_frame); - data->is_diff = true; +void Controller::serializeFrameData(torchcraft::fbs::FrameOrFrameDiffUnion& frameOrFrameDiff) { + { + flatbuffers::FlatBufferBuilder builder; + if (prev_sent_frame == nullptr) { + frameOrFrameDiff.type = torchcraft::fbs::FrameOrFrameDiff::Frame; + last_frame->addToFlatBufferBuilder(builder); + } else { + frameOrFrameDiff.type = torchcraft::fbs::FrameOrFrameDiff::FrameDiff; + auto frameDiff = replayer::frame_diff(last_frame, prev_sent_frame); + frameDiff.addToFlatBufferBuilder(builder); + } + frameOrFrameDiff.value = builder.GetBufferPointer(); } - if (prev_sent_frame != nullptr) - prev_sent_frame->decref(); + + if (prev_sent_frame) { prev_sent_frame->decref(); } prev_sent_frame = last_frame; last_frame = nullptr; - auto s = out.str(); - data->data.assign(s.data(), s.data() + s.size()); } void Controller::endGame() { @@ -608,9 +611,10 @@ void Controller::endGame() { output_log, "Game ended (%s)", (this->is_winner ? "WON" : "LOST")); torchcraft::fbs::EndGameT endg; - endg.data.reset(new torchcraft::fbs::FrameDataT()); - if (last_frame != nullptr) - this->serializeFrameData(endg.data.get()); + endg.data.Reset(); + if (last_frame != nullptr) { + this->serializeFrameData(endg.data); + } endg.game_won = this->is_winner; clearPendingReceive(); @@ -806,10 +810,7 @@ void Controller::onFrame() { } } - if (!this->tcframe_.data) - this->tcframe_.data.reset(new torchcraft::fbs::FrameDataT()); - this->serializeFrameData(this->tcframe_.data.get()); - + this->serializeFrameData(this->tcframe_.data); this->tcframe_.deaths = this->deaths; this->deaths.clear(); diff --git a/BWEnv/src/utils.cc b/BWEnv/src/utils.cc index d672cd4..add87d3 100644 --- a/BWEnv/src/utils.cc +++ b/BWEnv/src/utils.cc @@ -245,8 +245,11 @@ std::string readIni(const std::string& filename, const std::string& section, con long filesize = ftell(f); data.resize(filesize); fseek(f, 0, SEEK_SET); - fread(data.data(), filesize, 1, f); + auto elementsRead = fread(data.data(), filesize, 1, f); fclose(f); + if (!elementsRead) { + return {}; + } bool correct_section = section.empty(); const char* c = data.data(); const char* e = c + data.size(); diff --git a/BWEnv/src/zmq_server.cc b/BWEnv/src/zmq_server.cc index ae9f2c7..99a7368 100755 --- a/BWEnv/src/zmq_server.cc +++ b/BWEnv/src/zmq_server.cc @@ -189,8 +189,8 @@ void ZMQ_server::sendHandshake(const torchcraft::fbs::HandshakeServerT* handshak sendFBObject(this->sock.get(), handshake); } -void ZMQ_server::sendFrame(const torchcraft::fbs::FrameT* frame) { - sendFBObject(this->sock.get(), frame); +void ZMQ_server::sendFrame(const torchcraft::fbs::StateUpdateT* stateUpdate) { + sendFBObject(this->sock.get(), stateUpdate); } void ZMQ_server::sendPlayerLeft(const torchcraft::fbs::PlayerLeftT* pl) { diff --git a/replayer/README.md b/replayer/README.md new file mode 100644 index 0000000..824eb6d --- /dev/null +++ b/replayer/README.md @@ -0,0 +1,5 @@ +# Replayer + +### Testing + +You can test serialization by running the TorchCraft tests via "make test" in directory where you've constructed Makefiles via CMake. \ No newline at end of file