Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import Foundation
import Actor
import MessageRouter
public final class Core<State, Event, Command> {
public typealias CommandProcessor = (Core<State, Event, Command>, Command) -> Void
public typealias EventHandler = (State, Event) -> CoreUpdate<State, Command>
public let stateChanged = MessageRouter<State>()
public var currentState: State {
return stateMachine.currentState
}
private let stateMachine: PureStateMachine<State, Event, CoreUpdate<State, Command>>
private let commandProcessors: [CommandProcessor]
public init(initialState: State, commandProcessors: [CommandProcessor] = [], handler: @escaping EventHandler) {
self.stateMachine = PureStateMachine<State, Event, CoreUpdate<State, Command>>(initialState: initialState, label: "pro.tricksofthetrade.Core") { state, event in
let update = handler(state, event)
return (update.state ?? state, update)
}
self.commandProcessors = commandProcessors
}
public func fire(event: Event) {
DispatchQueue.global(qos: .default).async {
let update = self.stateMachine.handleEvent(event)
if let state = update.state {
self.stateChanged.send(state)
}
for command in update.commands {
for processor in self.commandProcessors {
processor(self, command)
}
}
}
}
public func perform(command: Command) {
DispatchQueue.global(qos: .default).async {
self.commandProcessors.forEach { $0(self, command) }
}
}
}
public enum CoreUpdate<State, Command> {
case NoUpdate
case State(State)
case Commands([Command])
case StateAndCommands(State, [Command])
public var state: State? {
switch self {
case .NoUpdate, .Commands: return nil
case .State(let state): return state
case .StateAndCommands(let state, _): return state
}
}
public var commands: [Command] {
switch self {
case .NoUpdate, .State: return []
case .Commands(let commands): return commands
case .StateAndCommands(_, let commands): return commands
}
}
public func mapState<T>(_ closure: (State) -> T) -> CoreUpdate<T, Command> {
switch self {
case .NoUpdate:
return .NoUpdate
case .Commands(let commands):
return .Commands(commands)
case .State(let state):
return .State(closure(state))
case .StateAndCommands(let state, let commands):
return .StateAndCommands(closure(state), commands)
}
}
public func mapCommand<T>(_ closure: (Command) -> T) -> CoreUpdate<State, T> {
switch self {
case .NoUpdate:
return .NoUpdate
case .Commands(let commands):
return .Commands(commands.map(closure))
case .State(let state):
return .State(state)
case .StateAndCommands(let state, let commands):
return .StateAndCommands(state, commands.map(closure))
}
}
}
@rob-brown

This comment has been minimized.

Copy link
Owner Author

commented Jan 29, 2018

Dependencies

Actor
MessageRouter

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.