private def processMsg(value: Any, source: AnyRef): Unit = { val event = Event(value, currentState.stateData) processEvent(event, source) } private[akka] def processEvent(event: Event, source: AnyRef): Unit = { val stateFunc = stateFunctions(currentState.stateName) val nextState = if (stateFunc isDefinedAt event) { stateFunc(event) } else { // handleEventDefault ensures that this is always defined
handleEvent(event) } applyState(nextState) }
/* * State definitions */
private val stateFunctions = mutable.Map[S, StateFunction]()
type StateFunction = scala.PartialFunction[Event, State]
/** * Insert a new StateFunction at the end of the processing chain for the * given state. If the stateTimeout parameter is set, entering this state * without a differing explicit timeout setting will trigger a StateTimeout * event; the same is true when using #stay. * * @param stateName designator for the state * @param stateTimeout default state timeout for this state * @param stateFunction partial function describing response to input */ final def when(stateName: S, stateTimeout: FiniteDuration = null)(stateFunction: StateFunction): Unit = register(stateName, stateFunction, Option(stateTimeout)) private def register(name: S, function: StateFunction, timeout: Timeout): Unit = { if (stateFunctions contains name) { stateFunctions(name) = stateFunctions(name) orElse function stateTimeouts(name) = timeout orElse stateTimeouts(name) } else { stateFunctions(name) = function stateTimeouts(name) = timeout } }
class FillSeasons extends FSM[Seasons,SeasonInfo] with ActorLogging { import FillSeasons._ startWith(Spring,SeasonInfo(0,1)) //起始状态
when(Spring) { //状态在春季
case Event(HowYouFeel,seasonInfo) => ... } when(Summer) { //夏季状态
case Event(HowYouFeel,_) => } when(Fall) { //秋季状态
case Event(HowYouFeel,SeasonInfo(tks,mnth)) => } when(Winter) { //冬季状态
case Event(HowYouFeel,si@ SeasonInfo(tks,_)) => } whenUnhandled { //所有状态未处理的Event
case Event(NextMonth,seasonInfo) => } onTransition { case Spring -> Summer => log.info("Season changed from Spring to Summer month 1") case Summer -> Fall => log.info("Season changed from Summer to Fall month 1") case Fall -> Winter => log.info("Season changed from Fall to Winter month 1") case Winter -> Spring => log.info("Season changed from Winter to Spring month 1") } initialize() //设定起始状态
}
type TransitionHandler = PartialFunction[(S, S), Unit]
/** * Verify existence of initial state and setup timers. This should be the * last call within the constructor, or [[akka.actor.Actor#preStart]] and * [[akka.actor.Actor#postRestart]] * * An initial `currentState -> currentState` notification will be triggered by calling this method. * * @see [[#startWith]] */ final def initialize(): Unit =
if (currentState != null)