#pragma once #include "gui.hpp" #include "game_engine.hpp" #include #include "fsm.hpp" #include #include #include #include "watcher.hpp" using std::string; struct MatchResult { bool match = false; string file_name = ""; string lnumber = ""; string col = ""; string type = ""; string message = ""; }; enum class BuildState { START, WAITING, BUILDING, DONE, FORKING, READING, EXIT, ERROR }; enum BuildEvent { GO, QUIT, CRASH }; class Builder : DeadSimpleFSM { // FOUND BUG: this was interesting, it got copied but the gui kept working until the refactor GUI &gui; GameEngine &game; string git_path = "NOT SET"; string build_cmd = "NOT SET"; efsw::FileWatcher* fileWatcher = NULL; UpdateListener* listener = NULL; efsw::WatchID wid; FILE *build_out = NULL; bool build_done = false; string line = ""; std::future build_fut; std::future read_fut; std::mutex fsm_mutex; git_repository* repo = nullptr; public: Builder(GUI &g, GameEngine &engine); MatchResult parse_line(const string &line); string read_line(FILE *build_out, bool &done_out); FILE *start_command(string &build_cmd); void event(BuildEvent ev) { try { if(ev == QUIT) { EXIT(ev); } switch(_state) { FSM_STATE(BuildState, BUILDING, ev); FSM_STATE(BuildState, START, ev); FSM_STATE(BuildState, WAITING, ev); FSM_STATE(BuildState, DONE, ev); FSM_STATE(BuildState, FORKING, ev); FSM_STATE(BuildState, READING, ev); FSM_STATE(BuildState, EXIT, ev); FSM_STATE(BuildState, ERROR, ev); } } catch(...) { fmt::println("ERROR: unhandled state: {}", int(_state)); ERROR(ev); } } void BUILDING(BuildEvent ev); void START(BuildEvent ev); void WAITING(BuildEvent ev); void DONE(BuildEvent ev); void FORKING(BuildEvent ev); void READING(BuildEvent ev); void ERROR(BuildEvent ev); void EXIT(BuildEvent ev); };