From f632f2d5af54728c060226650953d04a0eecd739 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Mon, 16 Sep 2024 08:05:43 -0400 Subject: [PATCH] FSM is now even cleaner, as long as you don't look at that CPP macro. --- builder.cpp | 16 ++++++++-------- builder.hpp | 36 ++++++++++++++++++------------------ fsm.hpp | 4 ++-- game_engine.cpp | 16 ++++++++-------- game_engine.hpp | 26 ++++++++++++-------------- tests/fsm.cpp | 6 +++--- 6 files changed, 51 insertions(+), 53 deletions(-) diff --git a/builder.cpp b/builder.cpp index 75041b5..660029a 100644 --- a/builder.cpp +++ b/builder.cpp @@ -73,7 +73,7 @@ MatchResult Builder::parse_line(const string &line) { } } -void Builder::building(BuildEvent ev) { +void Builder::BUILDING(BuildEvent ev) { // check if there's output if(build_done) { int rc = pclose(build_out); @@ -100,7 +100,7 @@ void Builder::building(BuildEvent ev) { } } -void Builder::start(BuildEvent ev) { +void Builder::START(BuildEvent ev) { gui.output(format("Using build command: {}", build_cmd)); fileWatcher = new efsw::FileWatcher(); dbc::check(fileWatcher != nullptr, "Failed to create filewatcher."); @@ -120,7 +120,7 @@ void Builder::start(BuildEvent ev) { state(BuildState::WAITING); } -void Builder::waiting(BuildEvent ev) { +void Builder::WAITING(BuildEvent ev) { if(listener->changes) { game.event(GameEvent::BUILD_START); gui.building(); @@ -129,7 +129,7 @@ void Builder::waiting(BuildEvent ev) { } } -void Builder::forking(BuildEvent ev) { +void Builder::FORKING(BuildEvent ev) { if(build_fut.valid()) { std::future_status status = build_fut.wait_for(0ms); @@ -148,7 +148,7 @@ void Builder::forking(BuildEvent ev) { } } -void Builder::reading(BuildEvent ev) { +void Builder::READING(BuildEvent ev) { // BUG: too much copy-pasta so turn this into a class? if(read_fut.valid()) { std::future_status status = read_fut.wait_for(0ms); @@ -166,7 +166,7 @@ void Builder::reading(BuildEvent ev) { } } -void Builder::done(BuildEvent ev) { +void Builder::DONE(BuildEvent ev) { if(game.is_dead()) { gui.you_died(); } @@ -176,7 +176,7 @@ void Builder::done(BuildEvent ev) { state(BuildState::WAITING); } -void Builder::exit(BuildEvent ev) { +void Builder::EXIT(BuildEvent ev) { if(ev == QUIT) { fileWatcher->removeWatch(wid); git_libgit2_shutdown(); @@ -184,7 +184,7 @@ void Builder::exit(BuildEvent ev) { } } -void Builder::error(BuildEvent ev) { +void Builder::ERROR(BuildEvent ev) { // how to avoid doing this more than once? if(ev == CRASH) { if(repo != nullptr) git_repository_free(repo); diff --git a/builder.hpp b/builder.hpp index 6b0e050..6c53bc7 100644 --- a/builder.hpp +++ b/builder.hpp @@ -56,31 +56,31 @@ class Builder : DeadSimpleFSM { void event(BuildEvent ev) { try { if(ev == QUIT) { - exit(ev); + EXIT(ev); } switch(_state) { - FSM_STATE(BuildState, BUILDING, building, ev); - FSM_STATE(BuildState, START, start, ev); - FSM_STATE(BuildState, WAITING, waiting, ev); - FSM_STATE(BuildState, DONE, done, ev); - FSM_STATE(BuildState, FORKING, forking, ev); - FSM_STATE(BuildState, READING, reading, ev); - FSM_STATE(BuildState, EXIT, exit, ev); - FSM_STATE(BuildState, ERROR, exit, ev); + 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); + 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); + 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); }; diff --git a/fsm.hpp b/fsm.hpp index d0fe917..5898ea4 100644 --- a/fsm.hpp +++ b/fsm.hpp @@ -3,9 +3,9 @@ #include #ifndef FSM_DEBUG -#define FSM_STATE(C, S, F, E, ...) case C::S: F(E, ##__VA_ARGS__); break +#define FSM_STATE(C, S, E, ...) case C::S: S(E, ##__VA_ARGS__); break #else -#define FSM_STATE(C, S, F, E, ...) case C::S: fmt::println(">> " #C " " #S ":" #F " event={}, state={}", int(E), int(_state)); F(E, ##__VA_ARGS__); fmt::println("<< " #C " state={}", int(_state)); break +#define FSM_STATE(C, S, E, ...) case C::S: fmt::println(">> " #C " " #S " event={}, state={}", int(E), int(_state)); S(E, ##__VA_ARGS__); fmt::println("<< " #C " state={}", int(_state)); break #endif template diff --git a/game_engine.cpp b/game_engine.cpp index d5faec4..7589cd8 100644 --- a/game_engine.cpp +++ b/game_engine.cpp @@ -54,12 +54,12 @@ bool GameEngine::is_dead() { return free_death ? false : hit_points <= 0; } -void GameEngine::start(GameEvent ev) { +void GameEngine::START(GameEvent ev) { state(GameState::IDLE); - idle(ev); + IDLE(ev); } -void GameEngine::idle(GameEvent ev) { +void GameEngine::IDLE(GameEvent ev) { if(ev == GameEvent::BUILD_START) { hits_taken = 0; state(GameState::IN_ROUND); @@ -68,7 +68,7 @@ void GameEngine::idle(GameEvent ev) { } } -void GameEngine::in_round(GameEvent ev, string &hit_type) { +void GameEngine::IN_ROUND(GameEvent ev, string &hit_type) { switch(ev) { case GameEvent::HIT: hit(hit_type); @@ -91,11 +91,11 @@ void GameEngine::in_round(GameEvent ev, string &hit_type) { } } -void GameEngine::dead(GameEvent ev) { +void GameEngine::DEAD(GameEvent ev) { if(ev == GameEvent::BUILD_DONE) { reset(); state(GameState::FAILURE); - failure(ev); + FAILURE(ev); } else if(ev == GameEvent::HIT) { ++hits_taken; } else { @@ -103,7 +103,7 @@ void GameEngine::dead(GameEvent ev) { } } -void GameEngine::success(GameEvent ev) { +void GameEngine::SUCCESS(GameEvent ev) { assert(ev == GameEvent::BUILD_DONE && "success state expected BUILD_DONE"); ++rounds; ++streak; @@ -111,7 +111,7 @@ void GameEngine::success(GameEvent ev) { state(GameState::IDLE); } -void GameEngine::failure(GameEvent ev) { +void GameEngine::FAILURE(GameEvent ev) { assert(ev == GameEvent::BUILD_DONE && "failure state expected BUILD_DONE"); ++rounds; // streak is handled by reset() diff --git a/game_engine.hpp b/game_engine.hpp index 3b517f5..834ccab 100644 --- a/game_engine.hpp +++ b/game_engine.hpp @@ -50,23 +50,21 @@ class GameEngine : DeadSimpleFSM { void event(GameEvent ev, string hit_type="") { switch(_state) { - FSM_STATE(GameState, START, start, ev); - FSM_STATE(GameState, IDLE, idle, ev); - FSM_STATE(GameState, DEAD, dead, ev); - FSM_STATE(GameState, SUCCESS, success, ev); - FSM_STATE(GameState, FAILURE, failure, ev); - case GameState::IN_ROUND: - in_round(ev, hit_type); - break; + FSM_STATE(GameState, START, ev); + FSM_STATE(GameState, IDLE, ev); + FSM_STATE(GameState, DEAD, ev); + FSM_STATE(GameState, SUCCESS, ev); + FSM_STATE(GameState, FAILURE, ev); + FSM_STATE(GameState, IN_ROUND, ev, hit_type); } } - void start(GameEvent ev); - void idle(GameEvent ev); - void in_round(GameEvent ev, string &hit_type); - void dead(GameEvent ev); - void success(GameEvent ev); - void failure(GameEvent ev); + void START(GameEvent ev); + void IDLE(GameEvent ev); + void IN_ROUND(GameEvent ev, string &hit_type); + void DEAD(GameEvent ev); + void SUCCESS(GameEvent ev); + void FAILURE(GameEvent ev); void heal(); bool hit(string &type); diff --git a/tests/fsm.cpp b/tests/fsm.cpp index 0440098..bd43bf6 100644 --- a/tests/fsm.cpp +++ b/tests/fsm.cpp @@ -18,9 +18,9 @@ class MyFSM : public DeadSimpleFSM { public: void event(MyEvent ev, string data="") { switch(_state) { - FSM_STATE(MyState, START, START, ev); - FSM_STATE(MyState, RUNNING, RUNNING, ev, data); - FSM_STATE(MyState, END, END, ev); + FSM_STATE(MyState, START, ev); + FSM_STATE(MyState, RUNNING, ev, data); + FSM_STATE(MyState, END, ev); } }