Created
December 31, 2016 15:29
-
-
Save oliverbarreto/e4d839cdb8b98a7f4893fff2cf5c017d to your computer and use it in GitHub Desktop.
Simple State Machine v1 (Swift 3)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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