Traffic Intersection
A canvas-rendered traffic intersection demonstrating hierarchical FSMs in machina v6. The parent FSM manages the intersection’s phase sequencing; two child FSMs independently control the signal progression for each active phase.
What it demonstrates
Section titled “What it demonstrates”Five machina v6 features working together in a realistic scenario:
_childdelegation — parent states forward inputs to an active child FSM automatically; the parent never manually routes them- Input bubbling —
phaseCompletehas no handler in the child’sredstate, so it bubbles up to the parent compositeState()— returns"northSouthPhase.green"as a single readable string, combining parent and child state- Child auto-reset — when the parent re-enters a phase state, machina calls
reset()on the child automatically, returning it togreen defer()— a pedestrian button press during non-interruptible green is queued and replayed automatically wheninterruptibleGreenis entered
State hierarchy
Section titled “State hierarchy”The two child instances (nsPhaseCtrl and ewPhaseCtrl) are created by the same factory but have independent context objects and timers. They never share state.
Signal state mapping
Section titled “Signal state mapping”compositeState() drives everything the renderer shows. The lookup table in config.ts maps every composite state string to visual signal states for all four directions:
| Composite State | N/S Vehicle | N/S Ped | E/W Vehicle | E/W Ped |
|---|---|---|---|---|
ready | red | don’t walk | red | don’t walk |
northSouthPhase.green | green | walk | red | don’t walk |
northSouthPhase.interruptibleGreen | green | flashing | red | don’t walk |
northSouthPhase.yellow | yellow | don’t walk | red | don’t walk |
northSouthPhase.red | red | don’t walk | red | don’t walk |
clearanceNS | red | don’t walk | red | don’t walk |
eastWestPhase.green | red | don’t walk | green | walk |
eastWestPhase.interruptibleGreen | red | don’t walk | green | flashing |
eastWestPhase.yellow | red | don’t walk | yellow | don’t walk |
eastWestPhase.red | red | don’t walk | red | don’t walk |
clearanceEW | red | don’t walk | red | don’t walk |
The pedestrian button
Section titled “The pedestrian button”Pressing the button during the non-interruptible green state calls defer({ until: "interruptibleGreen" }). Machina queues the input and replays it automatically when interruptibleGreen is entered — the press “works”, it just takes effect at the earliest safe moment.
Whether the pedestrianRequest input arrives as a live press or a deferred replay, it lands in interruptibleGreen and immediately transitions to yellow, shortening the phase. Pressing the button during yellow, clearance, or ready is unhandled and fires a nohandler event.