Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
import Foundation
protocol StateType: Hashable {}
protocol EventType: Hashable {}
struct Transition<S: StateType, E: EventType> {
let event: E
let fromState: S
let toState: S
init(event: E, fromState: S, toState: S) {
self.event = event
self.fromState = fromState
self.toState = toState
class StateMachine<S: StateType, E: EventType> {
private struct Operation<S: StateType, E: EventType> {
let transition: Transition<S, E>
let triggerCallback: (Transition<S, E>) -> Void
private var routes = [S: [E: Operation<S, E>]]()
private(set) var currentState: S
private(set) var lastState: S?
init(_ currentState: S) {
self.currentState = currentState
func listen(_ event: E, transit fromStates:[S], to toState: S, callback: @escaping (Transition<S, E>) -> Void) {
for fromState in fromStates {
listen(event, transit: fromState, to: toState, callback: callback)
func listen(_ event: E, transit fromState: S, to toState: S, callback: @escaping (Transition<S, E>) -> Void) {
var route = routes[fromState] ?? [:]
let transition = Transition(event: event, fromState: fromState, toState: toState)
let operation = Operation(transition: transition, triggerCallback: callback)
route[event] = operation
routes[fromState] = route
func trigger(_ event: E) {
guard let route = routes[currentState]?[event] else { return }
lastState = currentState
currentState = route.transition.toState
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.