Skip to content

Instantly share code, notes, and snippets.

@oliverbarreto
Created December 31, 2016 15:29
Show Gist options
  • Save oliverbarreto/e4d839cdb8b98a7f4893fff2cf5c017d to your computer and use it in GitHub Desktop.
Save oliverbarreto/e4d839cdb8b98a7f4893fff2cf5c017d to your computer and use it in GitHub Desktop.
Simple State Machine v1 (Swift 3)
import Foundation
//: Simple State Machine Delegate Protocol
protocol SimpleStateMachineDelegateProtocol: class {
// Defines the future States of the Machine
associatedtype StateMachineState
// Used to confirm that a state change can occur, and its notification to the delegate to perform somthing upon change
func shouldTransition(fromState: StateMachineState, toState: StateMachineState) -> Bool
func didTransition(fromState: StateMachineState, toState: StateMachineState)
}
//: Simple -GENERIC- State Machine
class SimpleStateMachine<P: SimpleStateMachineDelegateProtocol> {
// Delegate
private unowned let delegate: P
// Current Valid State
private var internalState: P.StateMachineState {
didSet {
delegate.didTransition(fromState: oldValue, toState: internalState)
}
}
// Facade of Internal State
var state: P.StateMachineState {
get {
return internalState
}
set {
if delegate.shouldTransition(fromState: internalState, toState: newValue) {
internalState = newValue
}
}
}
// Full Init
init(initialState: P.StateMachineState, withDelegate delegate: P) {
self.internalState = initialState
self.delegate = delegate
}
}
//: A class that implements the SimpleStateMachineDelegateProtocol
class PomodoroWorkflow:SimpleStateMachineDelegateProtocol {
enum PomodoroPhases {
case Ready, Pomodoro(Int), ShortBreak, LongBreak, Paused
}
typealias StateMachineState = PomodoroPhases
//: Determine Valid Transitions for valid States
func shouldTransition(fromState: PomodoroWorkflow.PomodoroPhases, toState: PomodoroWorkflow.PomodoroPhases) -> Bool {
// Define Transition Logic here:
switch (fromState, toState) {
case (.Ready,.Pomodoro):
return true
case (.Pomodoro,.Paused), (.Pomodoro,.ShortBreak), (.Pomodoro,.LongBreak):
return true
case (.ShortBreak,.Paused), (.ShortBreak,.Pomodoro):
return true
case (.LongBreak,.Paused), (.LongBreak,.Pomodoro):
return true
default:
return false
}
}
func didTransition(fromState: PomodoroWorkflow.PomodoroPhases, toState: PomodoroWorkflow.PomodoroPhases) {
// Define Work to do when transition occrus here:
switch (fromState, toState) {
case (.Ready, .Pomodoro):
// Call API Pomodoro DidStart
break
case (.Pomodoro, .Paused):
// Call API Pomodoro DidPause
break
case (.Pomodoro(let currentPomodoro), .ShortBreak):
// Call API ShortBreak DidEnd
break
case (.Pomodoro(let currentPomodoro), .LongBreak):
// Call API LongBreak DidEnd
break
default:
break
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment