enum State { a, b }
enum Event { e1, e2, e3 }
alias Stm = StateTransitor!(State, Event);
alias C = Stm.Cell;
string msg;
// STM
auto sm = Stm([
// Event StateA StateB
/* e1: */ [C(State.b, {msg = "a-1";}), C(State.b, forbiddenHandler)],
/* e2: */ [C(State.a, ignoreHandler), C(State.a, {msg = "b-2";})],
/* e3: */ [C(State.a, {msg = "a-3";}), C(State.a, forbiddenHandler)]
]);
static assert(isOutputRange!(typeof(sm), Event));
assert(sm.currentState == State.a);
std.range.put(sm, Event.e1);
assert(sm.currentState == State.b);
assert(msg == "a-1");
sm.put(Event.e2);
assert(sm.currentState == State.a);
assert(msg == "b-2");
sm.put(Event.e3);
assert(sm.currentState == State.a);
assert(msg == "a-3");
sm.put(Event.e2);
assert(sm.currentState == State.a);
assert(msg == "a-3");
sm.put(Event.e1);
assert(sm.currentState == State.b);
assert(msg == "a-1");
struct Policy
{
enum State { a, b }
enum Event { e1, e2, e3 }
enum consumeMode = ConsumeMode.separate;
}
alias Stm = StateTransitor!Policy;
alias State = Policy.State;
alias Event = Policy.Event;
alias C = Stm.Cell;
string[] msg;
State[] statesOnEvent;
// STM
auto sm = Stm([
// Event StateA StateB
/* e1: */ [C(State.b, {msg ~= "a-1";}), C(State.b, forbiddenHandler)],
/* e2: */ [C(State.a, ignoreHandler), C(State.a, {msg ~= "b-2";})],
/* e3: */ [C(State.a, {msg ~= "a-3";}), C(State.a, forbiddenHandler)]
]);
sm.addEventHandler((Event e)
{
statesOnEvent ~= sm.currentState;
});
static assert(isOutputRange!(typeof(sm), Event));
assert(sm.currentState == State.a);
put(sm, [Event.e1, Event.e2, Event.e3, Event.e2, Event.e1]);
assert(sm.currentState == State.a);
while (!sm.emptyEvents)
sm.consume();
with (State)
assert(statesOnEvent == [a, b, a, a, a]);
assert(sm.currentState == State.b);
assert(msg == ["a-1", "b-2", "a-3", "a-1"]);
StateTransitor