Skip to content

A Swift package for creating elegant state machines.

License

Notifications You must be signed in to change notification settings

bpisano/StateMachine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

StateMachine

A Swift package for creating state machines.

Installation

Add the following dependency to your Package.swift file:

dependencies: [
    .package(url: "https://github.com/bpisano/StateMachine", .upToNextMajor(from: "1.0.0"))
]

Usage

You can start by defining your state by creating structs that conforms to the StateMachineState protocol. To transition between states, use the @StateTransition property wrapper.

Here is an example of states that toggles between an on and off:

import StateMachine

struct OnState: StateMachineState {
    @StateTransition private var transition

    func enter() async {
        print("ON")
        Task {
            try? await Task.sleep(for: .seconds(1))
            transition(to: OffState())
        }
    }
}

struct OffState: StateMachineState {
    @StateTransition private var transition

    func enter() async {
        print("OFF")
        Task {
            try? await Task.sleep(for: .seconds(1))
            transition(to: OnState())
        }
    }
}

You can then create and start your state machine by providing the initial state:

let stateMachine = StateMachine(initialState: OffState())
await stateMachine.start()

This should result with the following output:

OFF
ON
OFF
ON
...

Adding context

You can add context to your state machine by providing a type that conforms to the StateMachineContext protocol:

struct MyContext: StateMachineContext {
    static let defaultValue: MyContext = .init(delay: 1)

    let delay: TimeInterval
}

You need to provide a default value for your context by using the defaultValue property.

This context can be accessed from your states by using the @StateContext property wrapper:

struct OnState: StateMachineState {
    @StateTransition private var transition
    @StateContext(MyContext.Self) private var context

    func enter() async {
        print("ON")
        Task {
            try? await Task.sleep(for: .seconds(await context.delay))
            transition(to: OffState())
        }
    }
}

To create your state machine with a context, use the ContextualStateMachine type:

let stateMachine = ContextualStateMachine(
    initialState: OffState(),
    context: MyContext(delay: 1)
)
await stateMachine.start()

About

A Swift package for creating elegant state machines.

Topics

Resources

License

Stars

Watchers

Forks

Languages