StateTransitor

StateTransitor

Examples

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"]);

Meta