Building & Driving a Machine
Building a machine
Hydra.create(…) takes a builder lambda. Inside it:
| Builder call | Purpose |
|---|---|
|
The state the machine starts in (required). |
|
Declare a state matched by value equality. |
|
Declare a state matched by type. |
|
A machine-wide listener fired on every transition. |
Inside a state builder (sb):
| Builder call | Purpose |
|---|---|
|
A transition triggered by an event matched by value. |
|
A transition triggered by an event matched by type. |
|
Move to |
|
Stay in the current state (a self-loop), optionally emitting an action. |
|
Fire side effects when the state is entered / exited. |
Driving a machine
| Method | Behaviour |
|---|---|
|
Match-and-move. Mutates the current state (thread-safe), fires listeners, returns the |
|
Computes the move and fires listeners without mutating in-memory state — derives the class from the instance (a 3-arg |
|
The current state. |
|
A new machine derived from this one (e.g. a different initial state); the original is untouched. |
Thread safety
The current state lives in a single AtomicReference, and each transition does a synchronized match-and-move. Safe to drive from many concurrent worker threads; the state never tears.
// Push an event. The machine moves AND tells you what to do next.
var checkout = orderMachine.transition(new Checkout(4999, "1 Market St"));
orderMachine.getState(); // Placed[amountCents=4999, address=1 Market St]
Each valid push moves the state and hands you an action to carry out. An illegal push is rejected; the state is left untouched and there is no action to run — the outcome is one of three sealed Transition cases.