StateCommand
enum Event {
case .none
case .filter
case .clearFilter
}
struct StateCommand {
let event: Event
let action: () -> ()
}
I’m using a struct with immutable properties. The StateCommand object is used to model an event along with an action to execute. If I wanted to use a different type of event I would need to make StateCommand generic by the type of event:
struct StateCommand<E> {
let event: E
let action: () -> ()
}
Now I can create a new enum for another set of events related to promoting/demoting Item
objects:
enum ItemEvent {
case .none
case .promote
case .demote
}
And create a new StateCommand
object for each type of event:
let event = Event()
let itemEvent = ItemEvent()
let command = StateCommand(event: event) { print("StateCommand<Event>") }
let itemCommand = StateCommand(event: itemEvent) { print("StateCommand<ItemEvent>") }
Note that I’ve used trailing closure syntax for the StateCommand action parameter
We also need state enumerations
enum State {
case .filtered
case .unfiltered
}
enum ItemState {
case .initial
case .promoted
}
Each view model dictates what type of state machine to create based on the state and event enumerations that the view model cares about.
class ViewModel {
let state: State = .initial
let event: Event = .none
let stateMachine: StateMachine<State, Event> = StateMachine<State, Event>(state: state, event: event)
}
class ItemViewModel {
let state: ItemState = .initial
let event: ItemEvent = .none
let stateMachine: StateMachine<ItemState, ItemEvent> =
StateMachine<ItemState, ItemEvent>(state: state, event: event)
}
You may not need to specify the generic types when calling the init method. I’ve included them for completeness