FSM is now even cleaner, as long as you don't look at that CPP macro.

master
Zed A. Shaw 10 months ago
parent c9425aebf9
commit f632f2d5af
  1. 16
      builder.cpp
  2. 36
      builder.hpp
  3. 4
      fsm.hpp
  4. 16
      game_engine.cpp
  5. 26
      game_engine.hpp
  6. 6
      tests/fsm.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);

@ -56,31 +56,31 @@ class Builder : DeadSimpleFSM<BuildState, BuildEvent> {
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);
};

@ -3,9 +3,9 @@
#include <fmt/core.h>
#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<typename S, typename E>

@ -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()

@ -50,23 +50,21 @@ class GameEngine : DeadSimpleFSM<GameState, GameEvent> {
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);

@ -18,9 +18,9 @@ class MyFSM : public DeadSimpleFSM<MyState, MyEvent> {
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);
}
}

Loading…
Cancel
Save