1 enum State { a, b }
2 enum Event { e1, e2, e3 }
3
4 alias Stm = StateTransitor!(State, Event);
5
6 alias C = Stm.Cell;
7 string msg;
8 // STM
9 auto sm = Stm([
10 // Event StateA StateB
11 /* e1: */ [C(State.b, {msg = "a-1";}), C(State.b, forbiddenHandler)],
12 /* e2: */ [C(State.a, ignoreHandler), C(State.a, {msg = "b-2";})],
13 /* e3: */ [C(State.a, {msg = "a-3";}), C(State.a, forbiddenHandler)]
14 ]);
15 static assert(isOutputRange!(typeof(sm), Event));
16
17 assert(sm.currentState == State.a);
18 std.range.put(sm, Event.e1);
19 assert(sm.currentState == State.b);
20 assert(msg == "a-1");
21 sm.put(Event.e2);
22 assert(sm.currentState == State.a);
23 assert(msg == "b-2");
24 sm.put(Event.e3);
25 assert(sm.currentState == State.a);
26 assert(msg == "a-3");
27 sm.put(Event.e2);
28 assert(sm.currentState == State.a);
29 assert(msg == "a-3");
30 sm.put(Event.e1);
31 assert(sm.currentState == State.b);
32 assert(msg == "a-1");
1 struct Policy
2 {
3 enum State { a, b }
4 enum Event { e1, e2, e3 }
5 enum consumeMode = ConsumeMode.separate;
6 }
7 alias Stm = StateTransitor!Policy;
8 alias State = Policy.State;
9 alias Event = Policy.Event;
10 alias C = Stm.Cell;
11 string[] msg;
12 State[] statesOnEvent;
13 // STM
14 auto sm = Stm([
15 // Event StateA StateB
16 /* e1: */ [C(State.b, {msg ~= "a-1";}), C(State.b, forbiddenHandler)],
17 /* e2: */ [C(State.a, ignoreHandler), C(State.a, {msg ~= "b-2";})],
18 /* e3: */ [C(State.a, {msg ~= "a-3";}), C(State.a, forbiddenHandler)]
19 ]);
20 sm.addEventHandler((Event e)
21 {
22 statesOnEvent ~= sm.currentState;
23 });
24 static assert(isOutputRange!(typeof(sm), Event));
25
26 assert(sm.currentState == State.a);
27 put(sm, [Event.e1, Event.e2, Event.e3, Event.e2, Event.e1]);
28 assert(sm.currentState == State.a);
29
30 while (!sm.emptyEvents)
31 sm.consume();
32 with (State)
33 assert(statesOnEvent == [a, b, a, a, a]);
34 assert(sm.currentState == State.b);
35 assert(msg == ["a-1", "b-2", "a-3", "a-1"]);
StateTransitor