通常のアクターの場合は、構成できます。しかし、FSMでそれを行うことについて何も見つけられないようです。また、 += を使用して追加する受信ブロックはありません。FSM を一般化しようとした経験のある人はいますか?
FSM を構成できるかどうかわからないため、まだコードを持っていないため、コード例を提供することはできません。
アクターの部分関数を構成するのと同じ方法で、部分関数を使用して状態の動作を構成できます。関数にはタイプのwhen()
部分関数が必要ですscala.PartialFunction[FSM.this.Event, FSM.this.State]
)。Jibber
以下の例では、トレイトで宣言された部分関数 (たとえば、いくつかの一般的な動作) で状態を拡張します。として宣言された PF を使用して、まったく同じ手法をonTermination
使用して、トレイトから動作を拡張できますscala.PartialFunction[StopEvent, Unit]
。
この手法を使用して、いくつかの複雑な FSM から重要な一般的な動作を取り出しました。
package monster
import akka.actor._
import monster.FlyingSpaghetti._
// State and data objects
object FlyingSpaghetti {
trait State
object Jibber extends State
object Jabber extends State
object Ping
object Done
}
// Trait with common behaviour behaviour
trait FlyingSpaghetti extends Actor with FSM[State,String]{
val layer: StateFunction = {
case Event(Done,s) ⇒
println("Done behaviour layered")
stop()
}
}
class Monster() extends FlyingSpaghetti {
startWith(Jibber,"jabber")
self ! Ping
println("Starting")
// First, do the common behaviour PF then do specialised behaviour
when(Jibber) (layer orElse {
case Event(Ping,"jabber") ⇒
println("jabber")
goto(Jabber) using "jibber"
case Event(Done,s) ⇒
println("Done jabbering")
stop()
})
when(Jabber) {
case Event(Ping,"jibber") ⇒
println("jibber")
goto(Jibber) using "jabber"
case Event(Done,s) ⇒
println("Done jibbering")
stop()
}
}
object Run extends App {
val system = ActorSystem("mySystem")
val rattle = system.actorOf(Props[Monster])
rattle ! Ping
rattle ! Ping
rattle ! Done
Thread.sleep(100)
system.shutdown()
}