Consider providing some example code
Opened this issue · 4 comments
This library looks really interesting but it isn't immediately clear how to use it correctly. Perhaps by adding a couple of simple examples that highlight some of the usage patterns it could help make it more approachable.
I was thinking something along the lines of the following (but obviously using the correct API)
enum TrafficLightState {
green,
yellow,
red,
}
enum TrafficLightEvent {
timerExpired,
}
class TrafficLightStateMachine {
final Machine<TrafficLightState, TrafficLightEvent> _stateMachine;
TrafficLightStateMachine()
: _stateMachine = Machine<TrafficLightState, TrafficLightEvent>(
initialState: TrafficLightState.green,
states: {
TrafficLightState.green: State(
onEnter: () => print('Green light'),
transitions: {
TrafficLightEvent.timerExpired: TrafficLightState.yellow,
},
),
TrafficLightState.yellow: State(
onEnter: () => print('Yellow light'),
transitions: {
TrafficLightEvent.timerExpired: TrafficLightState.red,
},
),
TrafficLightState.red: State(
onEnter: () => print('Red light'),
transitions: {
TrafficLightEvent.timerExpired: TrafficLightState.green,
},
),
},
);
void start() {
while (true) {
_stateMachine.transition(TrafficLightEvent.timerExpired);
sleep(Duration(seconds: 1));
}
}
}
void main() {
final trafficLight = TrafficLightStateMachine();
trafficLight.start();
}
Ah, I thought I had the keyboard state machine in the tests section of code. That's not a bad example (though we'd have to restart the timer on every enter) and could be expanded with say a pedestrian wanting to cross.
Hi, I am also trying to implement a hierarchical state machine and I thought this repo looked promising. It would be nice to declare as per the example above, but that doesn't seem to be possible. There are no docs or examples, its 2 years old so would you suggest I look elsewhere, or is this still a viable option?
So here is my effort so far, but i cannot see a way to add a state to a machine, or machines to a state?
The only state in the machine is the root.
How do I add the states to the machine?
How do I make nested machines?
import 'package:hierarchical_state_machine/hierarchical_state_machine.dart';
enum TrafficLightState {
red,
amber,
green,
}
enum TrafficLightEvent {
stop,
readyToGo,
readyToStop,
go
}
enum TrafficLightTransition {
red2amber,
amber2green,
green2amber,
amber2red
}
void init() {
//states
var red = State(TrafficLightState.red);
var amber = State(TrafficLightState.amber);
var green = State(TrafficLightState.green);
//events
var stop = EventHandler(
target: red,
guard: null,
action: (event, data) {
print('stop action, light is red');
},
isLocalTransition: true
);
var readyToGo = EventHandler(
target: amber,
guard: null,
action: (event, data) {
print('readyTogo action, light is amber');
},
isLocalTransition: true
);
var readyToStop = EventHandler(
target: amber,
guard: null,
action: (event, data) {
print('readyToStop action, light is amber');
},
isLocalTransition: true
);
var go = EventHandler(
target: green,
guard: null,
action: (event, data) {
print('go action, light is green');
},
isLocalTransition: true
);
red.addHandler(readyToGo);
amber.addHandler(stop);
amber.addHandler(go);
green.addHandler(readyToStop);
//machine
TrafficLightState root = TrafficLightState.red;
final Machine<TrafficLightState, TrafficLightEvent> trafficlight =
Machine<TrafficLightState, TrafficLightEvent>(
name: 'traffic_light',
rootId: root,
);
//transitions
// runs twice
var loop = 2;
while (loop > 0) {
trafficlight.start();
trafficlight.handle(TrafficLightEvent.stop);
trafficlight.handle(TrafficLightEvent.readyToGo);
trafficlight.handle(TrafficLightEvent.go);
trafficlight.handle(TrafficLightEvent.readyToStop);
trafficlight.handle(TrafficLightEvent.stop);
loop--;
}
}
void main() {
init();
}
@macasas maybe this can help for now (documentation can always be improved):
final root = hsm.root;
final red = root.newChild(TrafficLightState.red);
final yellow = root.newChild(TrafficLightState.yellow);
final green = root.newChild(TrafficLightState.green);
as a bonus; its easier to add event handlers without allocating:
red.addHandler(
target: amber,
action: (event, data) {
print('readyTogo action, light is amber');
},
);
I use this library for personal projects, so it's not dead, it's just "stable".
Thanks, I'm having a play :-)