At one point I built a type-based state machine core for Java. The idea was to use interfaces and classes as the basis for defining what transitions are allowed, and as a way to store the associated fields. It relied on Java's type-checking to guide you into using it correctly.
public interface TurnstileState {}
public interface LockedState extends TurnstileState {}
public class UnlockedState implements TurnstileState {
public final int credits;
public UnlockedState(int credits) {
this.credits = credits;
}
}
public static final LockedState LOCKED = new LockedState() {};
StateMachine<TurnstileState> turnstile = StateMachine.<TurnstileState>.newBuilder()
.addValidTransition(LockedState.class, UnlockedState.class)
.addValidTransition(UnlockedState.class, LockedState.class)
.addValidTransition(UnlockedState.class, UnlockedState.class)
.buildWithInitialState(LOCKED);
turnstile.transition(new UnlockedState(1));
I never got around to building out examples in Kotlin. I feel like the type checking there would streamline a ton of this even further.
https://github.com/Hounshell/st8 if anyone wants to see the gory bits.