#pragma once #include "gui.hpp" #include "game_engine.hpp" #include <stdio.h> #include "fsm.hpp" #include <efsw/efsw.hpp> #include <future> #include <stdio.h> #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<BuildState, BuildEvent> { 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<FILE *> build_fut; std::future<string> read_fut; std::mutex fsm_mutex; git_repository* repo = nullptr; std::unordered_map<string, int> $hit_line_stats; 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); };