From 2af5fda73edcc8b52fbbba53cb33b32bdf4942a8 Mon Sep 17 00:00:00 2001 From: momania Date: Mon, 19 Jul 2010 16:28:35 +0200 Subject: [PATCH] refactor fsm --- akka-core/src/main/scala/actor/Actor.scala | 34 ------------------ akka-core/src/main/scala/actor/Fsm.scala | 38 +++++++++++++++++++++ akka-core/src/test/scala/FsmActorSpec.scala | 8 ++--- 3 files changed, 42 insertions(+), 38 deletions(-) create mode 100644 akka-core/src/main/scala/actor/Fsm.scala diff --git a/akka-core/src/main/scala/actor/Actor.scala b/akka-core/src/main/scala/actor/Actor.scala index 5630fe3a24..76adf9c729 100644 --- a/akka-core/src/main/scala/actor/Actor.scala +++ b/akka-core/src/main/scala/actor/Actor.scala @@ -25,40 +25,6 @@ trait Transactor extends Actor { self.makeTransactionRequired } -trait FsmActor[S] extends Actor { - - type State = scala.PartialFunction[Event, NextState] - - @volatile var currentState: NextState = initialState - @volatile var timeoutActor: Option[ActorRef] = None - - def initialState: NextState - - def handleEvent: State = { - case event@Event(value,stateData) => - log.warning("No state for event with value %s - keeping current state %s", value, stateData) - NextState(currentState.state, stateData, currentState.timeout) - } - - protected def receive = { - case value => { - timeoutActor.foreach{ref => Scheduler.unschedule(ref); timeoutActor = None } - - val event = Event(value, currentState.stateData) - currentState = (currentState.state orElse handleEvent).apply(event) - - currentState.timeout.foreach{timeout => - timeoutActor = Some(Scheduler.scheduleOnce(self, StateTimeout, timeout, TimeUnit.MILLISECONDS)) - } - } - } - - case class NextState(state: State, stateData: S, timeout: Option[Int] = None) - case class Event(event: Any, stateData: S) - object StateTimeout -} - - /** * Extend this abstract class to create a remote actor. *

diff --git a/akka-core/src/main/scala/actor/Fsm.scala b/akka-core/src/main/scala/actor/Fsm.scala new file mode 100644 index 0000000000..b7cc457c53 --- /dev/null +++ b/akka-core/src/main/scala/actor/Fsm.scala @@ -0,0 +1,38 @@ +package actor + +import java.util.concurrent.TimeUnit +import se.scalablesolutions.akka.actor.{ActorRef, Scheduler, Actor} + +trait Fsm[S] { self: Actor => + + type State = scala.PartialFunction[Event, NextState] + + @volatile var currentState: NextState = initialState + @volatile var timeoutActor: Option[ActorRef] = None + + def initialState: NextState + + def handleEvent: State = { + case event@Event(value,stateData) => + log.warning("No state for event with value %s - keeping current state %s", value, stateData) + NextState(currentState.state, stateData, currentState.timeout) + } + + + override protected def receive: Receive = { + case value => { + timeoutActor.foreach{ref => Scheduler.unschedule(ref); timeoutActor = None } + + val event = Event(value, currentState.stateData) + currentState = (currentState.state orElse handleEvent).apply(event) + + currentState.timeout.foreach{timeout => + timeoutActor = Some(Scheduler.scheduleOnce(this.self, StateTimeout, timeout, TimeUnit.MILLISECONDS)) + } + } + } + + case class NextState(state: State, stateData: S, timeout: Option[Int] = None) + case class Event(event: Any, stateData: S) +} +object StateTimeout diff --git a/akka-core/src/test/scala/FsmActorSpec.scala b/akka-core/src/test/scala/FsmActorSpec.scala index 3a3a60162e..06bf4d301b 100644 --- a/akka-core/src/test/scala/FsmActorSpec.scala +++ b/akka-core/src/test/scala/FsmActorSpec.scala @@ -7,7 +7,7 @@ package se.scalablesolutions.akka.actor import org.scalatest.junit.JUnitSuite import org.junit.Test import org.multiverse.api.latches.StandardLatch -import Actor._ +import actor.{StateTimeout, Fsm} import java.util.concurrent.TimeUnit object FsmActorSpec { @@ -15,7 +15,7 @@ object FsmActorSpec { class Lock(code: String, timeout: Int, unlockedLatch: StandardLatch, - lockedLatch: StandardLatch) extends FsmActor[CodeState] { + lockedLatch: StandardLatch) extends Actor with Fsm[CodeState] { def initialState = NextState(locked, CodeState("", "33221")) @@ -26,7 +26,7 @@ object FsmActorSpec { NextState(locked, CodeState(incomplete, code)) case codeTry if (codeTry == code) => { doUnlock - NextState(open, CodeState("", code), Some(timeout)) + new NextState(open, CodeState("", code), Some(timeout)) } case wrong => { log.error("Wrong code %s", wrong) @@ -66,7 +66,7 @@ class FsmActorSpec extends JUnitSuite { val lockedLatch = new StandardLatch // lock that locked after being open for 1 sec - val lock = actorOf(new Lock("33221", 1000, unlockedLatch, lockedLatch)).start + val lock = Actor.actorOf(new Lock("33221", 1000, unlockedLatch, lockedLatch)).start lock ! '3' lock ! '3'