-
Notifications
You must be signed in to change notification settings - Fork 4
Transitions
In order to transition between states, you'll need to dispatch events. Very often you'll need some metadata to go along with your events so that you can guard some transitions or apply some side effects.
To create an Automata event, all you'll have to do is to extend the abstract Event
class, and you're free to add any data that you want.
class Search extends Event {
final String query;
const Search(this.query);
}
On the following example, both the transition defined in the Off
and On
states are simple transitions.
final machine = StateMachine.create(
(g) => g
..initial<Off>()
..state<Off>(builder: (g) => g..on<OnToggle, On>())
..state<On>(builder: (g) => g..on<OnToggle, Off>())
);
On the following example we have a simple transition for the OnAwardPoints
event, this transition will move the state to itself which will then trigger the Eventless transitions created with the always
function. These transitions are executed every time regardless of the event that triggered it, they require a condition and will transition to the given target if it evaluates to true.
final machine = StateMachine.create(
(g) => g
..initial<Playing>()
..state<Playing>(
builder: (b) => b
// Eventless transition
// Will transition to either 'win' or 'lose' immediately upon
// entering 'playing' state or receiving OnAwardPoints event
// if the condition is met.
..always<Win>(condition: (_) => scoreboard.points > 99)
..always<Lose>(condition: (_) => scoreboard.points < 0)
..on<OnAwardPoints, Playing>(
actions: [
(OnAwardPoints e) {
scoreboard.points += e.points;
},
],
),
)
..state<Win>(type: StateNodeType.terminal)
..state<Lose>(type: StateNodeType.terminal),
);
TBA (talk about how a transition is picked)
Guards are the conditions defined in each transition. A transition is only applied if it's guard evaluates to true.
In the following example the first transition will match for the first 18 calls, afterwards that transition will evaluate to false and the applied transition will be the one that has MiddleAged
as it's target.
final machine = StateMachine.create(
(g) => g
..initial<Alive>()
..state<Alive>(
builder: (b) => b
..initial<Young>()
// Transitions
..on<OnBirthday, Young>(
condition: (e) => human.age < 18,
actions: [(e) { human.age++; }],
)
..on<OnBirthday, MiddleAged>(
condition: (e) => human.age < 50,
actions: [(e) { human.age++;}],
)
..on<OnBirthday, Old>(
condition: (e) => human.age < 80,
actions: [(e) { human.age++; }],
)
..on<OnDeath, Purgatory>()
// States
..state<Young>()
..state<MiddleAged>()
..state<Old>(),
)
..state<Dead>(),
);
TBA
TBA
TBA