Swift StateMachine源码分析

Swift StateMachine源码分析,第1张

概述Swift StateMachine源码分析 状态机的描述如下图: 3@2x.png swift的StateMachine的源码是Transporter。比较简单,只有3个文件。 Event指事件,State指状态,StateMachine是状态机控制中心。 1@2x.png State public class State <T:Hashable> { /// Value of state pu Swift StateMachine源码分析

状态机的描述如下图:


3@2x.png

swift的StateMachine的源码是Transporter。比较简单,只有3个文件。
Event指事件,State指状态,StateMachine是状态机控制中心。


1@2x.png State
public class State <T:Hashable> { /// Value of state public let value : T /// Closure,that will be executed,before state machine enters this state public var willEnterState: ( (enteringState : State<T> ) -> VoID)? /// Closure,after state machine enters this state public var dIDEnterState: ( (enteringState : State<T> ) -> VoID)? /// Closure,that will be executed before state machine will switch from current state to another state. public var willExitState: ( (exitingState : State<T> ) -> VoID)? /// Closure,that will be executed after state machine switched from current state to another state. public var dIDExitState: ( (exitingState : State<T> ) -> VoID)? /// Create state with value /// - Parameter value: value of state public init(_ value: T) { self.value = value } }

value:用来标识状态。

willEnterState:即将进入状态state

dIDEnterState:已经进入状态state

willExitState:即将脱离状态state

dIDExitState:已经脱离状态state

Event
public class Event<T:Hashable> { /// name of event public let name : String /// Array of source values,in which event can be fired public let sourceValues: [T] /// Destination value for state,to which state machine will switch after firing event. public let destinationValue: T /// If this closure return value is false,event will not be fired public var shouldFireEvent: ( (event : Event) -> Bool )? /// This closure will be executed before event is fired. public var willFireEvent: ( (event : Event) -> VoID )? /// This closure will be executed after event was fired. public var dIDFireEvent: ( (event : Event) -> VoID )? }

name定义了事件的名称

sourceValues:事件的起始状态,为什么要用一个数组呢?猜想是因为到另外一个状态的转换,可以是由不同的状态转换而来。如下图C可由A,B转换而来。

destinationValue:事件的目的状态

shouldFireEvent:是否允许事件触发

willFireEvent:即将触发事件

dIDFireEvent:已经触发事件


2@2x.png StateMachine
public class StateMachine<T:Hashable> { /// Initial state of state machine. var initialState: State<T> /// Current state of state machine public private(set) var currentState : State<T> /// Available states in state machine private lazy var availableStates : [State<T>] = [] /// Available events in state machine private lazy var events : [Event<T>] = [] }

initialState:初始状态

currentState:当前状态

availableStates:所有转换状态

events:所有转换事件

addState
public func addState(state: State<T>) { availableStates.append(state) } /// Add array of states /// - Parameter states: states array. public func addStates(states: [State<T>]) { availableStates.appendContentsOf(states) }

主要往状态机里添加状态,提供了批量添加addStates。

addEvent
public func addEvent(event: Event<T>) throws { if event.sourceValues.isEmpty { throw EventError.NoSourceValue } for state in event.sourceValues { if (self.stateWithValue(state) == nil) { throw EventError.NoSourceValue } } if (self.stateWithValue(event.destinationValue) == nil) { throw EventError.NoDestinationValue } self.events.append(event) } /// Add events to `StateMachine`. This method checks,whether source states and destination state of event are present in `StateMachine`. If not - event will not be added. /// - Parameter events: events to add to `StateMachine`. public func addEvents(events: [Event<T>]) { for event in events { guard let _ = try? self.addEvent(event) else { print("Failed adding event with name: %@",event.name) continue } } }

主要是添加事件。在添加的时候需要做一系列判断,条件成立之后才会添加到eventList中。

event.sourceValues是否为空

event.sourceValues包含的state是否在availableStates中

event.destinationValue是否在availableStates中

fireEvent
 public func fireEvent(event: Event<T>) -> Transition<T> { return _fireEventnamed(event.name) }

fireEvent内部调用_fireEventnamed方法,返回了Transition,是enum类型,返回转换的结果。

public enum Transition<T:Hashable> { /** Returns whether Transition was successful */ public var successful: Bool { switch self { case .Success(_,_): return true case .Error(_): return false } } /** Success case with source state,from which Transition happened,and destination state,to which state machine switched */ case Success(sourceState: State<T>,destinationState: State<T>) /** Error case,containing error. Error domain and status codes are described in Errors struct. */ case Error(TransitionError) }

_fireEventnamed

func _fireEventnamed(eventname: String) -> Transition<T> { if let event = eventWithname(eventname) { let possibleTransition = possibleTransitionForEvent(event) switch possibleTransition { case .Success(let sourceState,let destinationState): if let shouldBlock = event.shouldFireEvent { if shouldBlock(event: event) { event.willFireEvent?(event: event) activateState(event.destinationValue) event.dIDFireEvent?(event: event) return .Success(sourceState: sourceState,destinationState: destinationState) } else { return .Error(.TransitionDeclined) } } else { let sourceState = self.currentState event.willFireEvent?(event: event) activateState(event.destinationValue) event.dIDFireEvent?(event: event) return .Success(sourceState: sourceState,destinationState: destinationState) } default : return possibleTransition } } else { return .Error(.UnkNownEvent) } }

首先判断eventname是否在eventList中存在

possibleTransitionForEvent,判断event的sourceValues是否是包含当前的currentState,若是就返回.Success(srcState,desstate)。

判断event.shouldFireEvent,是否可以触发事件。如果设置了shouldFireEvent,则判断可以执行,就如顺序执行willFireEvent-->activateState-->dIDFireEvent。如果没有设置,还是按willFireEvent-->activateState-->dIDFireEvent执行。

activiateState

 public func activateState(stateValue: T) { if (isstateAvailable(stateValue)) { let oldState = currentState let newState = stateWithValue(stateValue)! newState.willEnterState?(enteringState: newState) oldState.willExitState?(exitingState: oldState) currentState = newState oldState.dIDExitState?(exitingState: oldState) newState.dIDEnterState?(enteringState: currentState) } }

stateWithValue:在availableStates中筛选value=stateValue的state。
依次调用:willEnterState--->willExitState--->dIDExitState--->dIDEnterState



文/summer_liu(简书作者) 原文链接:http://www.jianshu.com/p/85c8c3cc4917 著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。 总结

以上是内存溢出为你收集整理的Swift StateMachine源码分析全部内容,希望文章能够帮你解决Swift StateMachine源码分析所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1077733.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-27
下一篇2022-05-27

发表评论

登录后才能评论

评论列表(0条)

    保存