Minimal finite state machine with explicit transitions between states.
FSM keeps track of one current state and only allows transitions that are
explicitly registered on that state. This keeps state flow easy to reason
about: if there is no transition, goto simply does nothing.
Typical usage:
var idle = new State();
var walking = new State();
idle[walking] = () -> trace("start walking");
walking[idle] = () -> trace("stop walking");
var fsm = new FSM(idle);
fsm.goto(walking);