class FillSeasons extends FSM[Seasons,SeasonInfo] with ActorLogging { import FillSeasons._ startWith(Spring,SeasonInfo(0,1)) //起始状态
when(Spring) { //状态在春季
case Event(HowYouFeel,seasonInfo) => val numtalks = seasonInfo.talks + 1 log.info(s"It's ${stateName.toString}, feel so gooood! You've asked me ${numtalks}times.") stay using seasonInfo.copy(talks = numtalks) } when(Summer) { //夏季状态
case Event(HowYouFeel,_) => val numtalks = stateData.talks + 1 log.info(s"It's ${stateName.toString}, it's so hot! You've asked me ${numtalks}times") stay().using(stateData.copy(talks = numtalks)) } when(Fall) { //秋季状态
case Event(HowYouFeel,SeasonInfo(tks,mnth)) => val numtalks = tks + 1 log.info(s"It's ${stateName.toString}, it's no so bad. You've asked me ${numtalks}times.") stay using SeasonInfo(numtalks,mnth) } when(Winter) { //冬季状态
case Event(HowYouFeel,si@ SeasonInfo(tks,_)) => val numtalks = tks + 1 log.info(s"It's ${stateName.toString}, it's freezing cold! You've asked me ${numtalks}times.") stay using si.copy(talks = numtalks) } whenUnhandled { //所有状态未处理的Event
case Event(NextMonth,seasonInfo) => val mth = seasonInfo.month if (mth <= 3) { log.info(s"It's month ${mth+1} of ${stateName.toString}") stay using seasonInfo.copy(month = mth + 1) } else { goto(nextSeason(stateName)) using SeasonInfo(0,1) } } onTransition { case Spring -> Summer => log.info(s"Season changed from Spring to Summer month ${nextStateData.month}") case Summer -> Fall => log.info(s"Season changed from Summer to Fall month ${nextStateData.month}") case Fall -> Winter => log.info(s"Season changed from Fall to Winter month ${nextStateData.month}") case Winter -> Spring => log.info(s"Season changed from Winter to Spring month ${nextStateData.month}") } initialize() //设定起始状态
log.info(s"It's month 1 of ${stateName.toString}") //季节转换顺序
def nextSeason(season: Seasons): Seasons = season match { case Spring => Summer case Summer => Fall case Fall => Winter case Winter => Spring } }
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) }
private[akka] def applyState(nextState: State): Unit = { nextState.stopReason match { case None ? makeTransition(nextState) case _ ? nextState.replies.reverse foreach { r ? sender() ! r } terminate(nextState) context.stop(self) } } private[akka] def makeTransition(nextState: State): Unit = { if (!stateFunctions.contains(nextState.stateName)) { terminate(stay withStopReason Failure("Next state %s does not exist".format(nextState.stateName))) } else { nextStat