设为首页 加入收藏

TOP

Akka(7): FSM:通过状态变化来转换运算行为(三)
2017-10-09 14:06:32 】 浏览:4158
Tags:Akka FSM 通过 状态 变化 转换 运算 行为
makeTransition(currentState)
else throw new IllegalStateException("You must call `startWith` before calling `initialize`")

完整的FSM FeelingSeasons定义如下: 

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 } }

首先注意StateFunction中SeasonInfo的各种意思同等的表达方式及nextStateData。FSM状态数据用不可变对象(immutable object)最安全,所以在更新时必须用case class 的copy或直接构建新的SeasonInfo实例。

我们再来看看processEvent的作业流程:

 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) }

先运算用户定义的StateFunction处理事件Event获取新的状态State。然后调用applyState运算makeTransition处理状态转换(currentState = 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
首页 上一页 1 2 3 4 5 6 下一页 尾页 3/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Akka(6): become/unbecome:运.. 下一篇spark获取时间

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目