using zth::operator""_s;
namespace fsm {
static void init_()
{
printf("\x1b[0m ________ \n");
printf("/ \\\n");
printf("| .. |\n");
printf("| .. |\n");
printf("| |\n");
printf("| .. |\n");
printf("| .. |\n");
printf("| |\n");
printf("| .. |\n");
printf("| .. |\n");
printf("\\________/\n");
printf(" || \n");
printf(" || \n");
printf(" || \n");
printf(" || \n");
printf("\nPress enter to generate traffic.\n");
printf("\x1b[17A\x1b[s");
}
static void off_()
{
printf("\n\x1b[u");
printf(" ________ \n");
printf("/ \\\n");
printf("| .. |\n");
printf("| .. |\n");
printf("| |\n");
printf("| .. |\n");
printf("| .. |\n");
printf("| |\n");
printf("| .. |\n");
printf("| .. |\n");
printf("\\________/\n");
printf("\n\x1b[11A");
fflush(nullptr);
}
static void red_()
{
printf("\n\x1b[u");
printf(" ________ \n");
printf("/ \\\n");
printf("| \x1b[31;1m00\x1b[0m |\n");
printf("| \x1b[31;1m00\x1b[0m |\n");
printf("| |\n");
printf("| .. |\n");
printf("| .. |\n");
printf("| |\n");
printf("| .. |\n");
printf("| .. |\n");
printf("\\________/\n");
printf("\n\x1b[11A");
fflush(nullptr);
}
static void amber_()
{
printf("\n\x1b[u");
printf(" ________ \n");
printf("/ \\\n");
printf("| .. |\n");
printf("| .. |\n");
printf("| |\n");
printf("| \x1b[33m00\x1b[0m |\n");
printf("| \x1b[33m00\x1b[0m |\n");
printf("| |\n");
printf("| .. |\n");
printf("| .. |\n");
printf("\\________/\n");
printf("\n\x1b[11A");
fflush(nullptr);
}
static void green_()
{
printf("\n\x1b[u");
printf(" ________ \n");
printf("/ \\\n");
printf("| .. |\n");
printf("| .. |\n");
printf("| |\n");
printf("| .. |\n");
printf("| .. |\n");
printf("| |\n");
printf("| \x1b[32;1m00\x1b[0m |\n");
printf("| \x1b[32;1m00\x1b[0m |\n");
printf("\\________/\n");
printf("\n\x1b[11A");
fflush(nullptr);
}
constexpr
auto init =
action(init_,
"init");
constexpr
auto off =
action(off_,
"off");
constexpr
auto red =
action(red_,
"red");
constexpr
auto amber =
action(amber_,
"amber");
#if __cplusplus < 201703L
constexpr
auto green =
action(green_,
"green");
#else
constexpr
auto green =
action([]() { green_(); },
"green");
#endif
class TrafficLight : public Fsm {
public:
void justGotGreen()
{
m_green = t();
}
auto tooLongGreen() const
{
}
private:
};
constexpr
auto justGotGreen =
action(&TrafficLight::justGotGreen,
"justGotGreen");
constexpr
auto tooLongGreen =
guard(&TrafficLight::tooLongGreen,
"tooLongGreen");
constexpr
auto transitions =
compile(
"init" / init >>= "blink on",
"blink on" +
entry / amber ,
+ timeout_s<1> >>= "blink off",
"blink off" +
entry / off ,
+ timeout_s<1> >>= "peek",
"peek" +
input(
"traffic") >>=
"amber",
"red (wait)" +
entry / red ,
+ timeout_s<2> >>= "red",
+ timeout_s<10> >>= "blink off",
"green (first)" / justGotGreen >>= "green",
"green" +
entry / green ,
+ tooLongGreen >>= "amber",
+ timeout_s<3> >>= "amber",
"amber" +
entry / amber ,
+ timeout_s<2> >>= "red (wait)"
);
}
static void trafficDetect(fsm::TrafficLight& fsm)
{
char buf = 0;
fsm.input("traffic");
}
{
fsm::transitions.dump();
fflush(stdout);
fsm::transitions.uml(stderr);
fflush(stderr);
fsm::TrafficLight fsm;
fsm::transitions.init(fsm);
async trafficDetect(fsm);
fsm.run();
return 0;
}
Convenient wrapper around struct timespec that contains an absolute timestamp.
int main_fiber(int argc, char **argv)
#define zth_config(name)
Checks if the given zth::Config field is enabled.
#define zth_fiber(...)
Prepare every given function to become a fiber by async.
#define async
Run a function as a new fiber.
constexpr auto consume
Action consume the current input symbol.
constexpr auto guard(T &&g, char const *name=nullptr)
Create a guard from a function.
constexpr auto entry
Guard that is only enabled upon entry of a state.
constexpr auto action(T &&a, char const *name=nullptr)
Create an action from a function.
constexpr auto always
Trivial guard that is always enabled.
constexpr auto compile(T &&... t)
Compile a transition description.
TimeInterval input(Fsm &fsm)
A guard that is true when the given input has been set.
ssize_t read(int fd, void *buf, size_t count)
Like normal read(), but forwards the poll() to the zth::Waiter in case it would block.