Created
October 28, 2014 10:45
-
-
Save jseanj/8c2c9254b48c87c20ee7 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| protocol EventType { | |
| var name: String {get set} | |
| var code: String {get set} | |
| } | |
| struct Event: EventType { | |
| var name: String | |
| var code: String | |
| } | |
| //为什么struct不可以 | |
| class StateType { | |
| var name: String! | |
| var entry: (()->())? | |
| var exit: (()->())? | |
| var transitions: [String: Transition] = [:] | |
| init(name: String, entry: (()->())? = nil, exit: (()->())? = nil) { | |
| self.name = name | |
| self.entry = entry | |
| self.exit = exit | |
| } | |
| func hasTransition(eventCode: String) -> Bool { | |
| return transitions[eventCode] != nil ? true : false | |
| } | |
| func addTransition(event: Event, toState: StateType) { | |
| transitions[ event.code ] = Transition(from: self, to: toState, trigger: event) | |
| } | |
| func getAllToStates() -> [StateType] { | |
| var result = [StateType]() | |
| for transition in transitions.values { | |
| result.append(transition.to) | |
| } | |
| return result | |
| } | |
| // 根据事件获得下一个状态 | |
| func getToState(eventCode: String) -> StateType? { | |
| if transitions[eventCode] != nil { | |
| let transition = transitions[eventCode] as Transition? | |
| return transition!.to | |
| } | |
| return nil | |
| } | |
| func executeEntry() { | |
| if entry != nil { | |
| entry!() | |
| } | |
| } | |
| func executeExit() { | |
| if exit != nil { | |
| exit!() | |
| } | |
| } | |
| } | |
| struct Transition { | |
| var from: StateType | |
| var to: StateType | |
| var trigger: Event | |
| } | |
| class StateMachine { | |
| var initState: StateType | |
| var resetEvents = [Event]() | |
| init(initState: StateType) { | |
| self.initState = initState | |
| } | |
| func addResetEvents(events: Event...) { | |
| for event in events { | |
| resetEvents.append(event) | |
| } | |
| } | |
| func addResetEventByAddingTransitions(event: Event) { | |
| } | |
| func isResetEvent(eventCode: String) -> Bool { | |
| for resetEvent in resetEvents { | |
| if resetEvent.code == eventCode { | |
| return true | |
| } | |
| } | |
| return false | |
| } | |
| // func getAllStatesFromState(fromeState: StateType) -> [StateType] { | |
| // var result = [StateType]() | |
| // for state in fromeState.getAllToStates() { | |
| // result += getAllStatesFromState(state) | |
| // } | |
| // return result | |
| // } | |
| } | |
| class Controller { | |
| var currentState: StateType | |
| var machine: StateMachine | |
| init(currentState: StateType, machine: StateMachine) { | |
| self.currentState = currentState | |
| self.machine = machine | |
| } | |
| func handle(eventCode: String) { | |
| if currentState.hasTransition(eventCode) { | |
| // 如果当前状态可以转移,则转移到对应的状态 | |
| transitionToState(currentState.getToState(eventCode)!) | |
| } else if (machine.isResetEvent(eventCode)) { | |
| // 如果是重置事件,则转移到初始状态 | |
| transitionToState(machine.initState) | |
| } | |
| } | |
| // 转移状态 | |
| func transitionToState(toState: StateType) { | |
| currentState.executeExit() | |
| currentState = toState | |
| currentState.executeEntry() | |
| } | |
| } | |
| // Event | |
| //let doorClosed = Event(name: "doorClosed", code: "D1CL") | |
| //let drawerOpened = Event(name: "drawerOpened", code: "D2OP") | |
| //let lightOn = Event(name: "lightOn", code: "L1ON") | |
| //let doorOpened = Event(name: "doorOpened", code: "D1OP") | |
| //let panelColsed = Event(name: "panelClosed", code: "PNCL") | |
| // | |
| //let idle = StateType(name: "idle", entry: { | |
| // println("idle entry") | |
| // }, exit: { | |
| // println("idle exit") | |
| //}) | |
| //let activeState = StateType(name: "active", entry: { | |
| // println("active entry") | |
| // }, exit: { | |
| // println("active exit") | |
| //}) | |
| //let waitingForLightState = StateType(name: "waitingForLightState", entry: { | |
| // println("waitingForLightState entry") | |
| // }, exit: { | |
| // println("waitingForLightState exit") | |
| //}) | |
| //let waitingForDrawerState = StateType(name: "waitingForDrawerState", entry: { | |
| // println("waitingForDrawerState entry") | |
| // }, exit: { | |
| // println("waitingForDrawerState exit") | |
| //}) | |
| // | |
| //let unlockedPanelState = StateType(name: "unlockedPanelState", entry: { | |
| // println("unlockedPanelState entry") | |
| // }, exit: { | |
| // println("unlockedPanelState exit") | |
| //}) | |
| // | |
| // | |
| //var machine = StateMachine(initState: idle) | |
| // | |
| //idle.addTransition(doorClosed, toState: activeState) | |
| //activeState.addTransition(lightOn, toState: waitingForDrawerState) | |
| //activeState.addTransition(drawerOpened, toState: waitingForLightState) | |
| //waitingForLightState.addTransition(lightOn, toState: unlockedPanelState) | |
| //waitingForDrawerState.addTransition(drawerOpened, toState: unlockedPanelState) | |
| //unlockedPanelState.addTransition(panelColsed, toState: idle) | |
| // | |
| //machine.addResetEvents(doorOpened) | |
| // | |
| //let controller = Controller(currentState: idle, machine: machine) | |
| //controller.handle("D1CL") | |
| //controller.handle("D2OP") | |
| //controller.currentState.name | |
| //controller.handle("D1OP") | |
| //controller.currentState.name |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment