From 75c8ac33b48775e80f832b0cf34f42c4bf60f4ca Mon Sep 17 00:00:00 2001 From: Roland Date: Tue, 29 Nov 2011 16:37:48 +0100 Subject: [PATCH] =?UTF-8?q?make=20next=20state=E2=80=99s=20data=20availabl?= =?UTF-8?q?e=20in=20onTransition=20blocks,=20fixes=20#1422?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cherry-picked from release-1.3 --- .../scala/akka/actor/FSMTransitionSpec.scala | 25 +++++++++++++++++++ .../src/main/scala/akka/actor/FSM.scala | 7 ++++++ 2 files changed, 32 insertions(+) diff --git a/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala index afdf9da5eb..7c67d8e1e1 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala @@ -29,6 +29,19 @@ object FSMTransitionSpec { override def preRestart(reason: Throwable, msg: Option[Any]) { target ! "restarted" } } + class OtherFSM(target: ActorRef) extends Actor with FSM[Int, Int] { + startWith(0, 0) + when(0) { + case Ev("tick") ⇒ goto(1) using (1) + } + when(1) { + case Ev(_) ⇒ stay + } + onTransition { + case 0 -> 1 ⇒ target ! ((stateData, nextStateData)) + } + } + class Forwarder(target: ActorRef) extends Actor { def receive = { case x ⇒ target ! x } } @@ -72,4 +85,16 @@ class FSMTransitionSpec extends AkkaSpec with ImplicitSender { } } + "A FSM" must { + + "make previous and next state data available in onTransition" in { + val fsm = system.actorOf(new OtherFSM(testActor)) + within(300 millis) { + fsm ! "tick" + expectMsg((0, 1)) + } + } + + } + } diff --git a/akka-actor/src/main/scala/akka/actor/FSM.scala b/akka-actor/src/main/scala/akka/actor/FSM.scala index e4ca89770a..9419fccc60 100644 --- a/akka-actor/src/main/scala/akka/actor/FSM.scala +++ b/akka-actor/src/main/scala/akka/actor/FSM.scala @@ -382,6 +382,11 @@ trait FSM[S, D] extends ListenerManagement { */ protected[akka] def stateData: D = currentState.stateData + /** + * Return next state data (available in onTransition handlers) + */ + protected[akka] def nextStateData = nextState.stateData + /* * **************************************************************** * PRIVATE IMPLEMENTATION DETAILS @@ -393,6 +398,7 @@ trait FSM[S, D] extends ListenerManagement { */ private var currentState: State = _ private var timeoutFuture: Option[Cancellable] = None + private var nextState: State = _ private var generation: Long = 0L /* @@ -515,6 +521,7 @@ trait FSM[S, D] extends ListenerManagement { } else { nextState.replies.reverse foreach { r ⇒ sender ! r } if (currentState.stateName != nextState.stateName) { + this.nextState = nextState handleTransition(currentState.stateName, nextState.stateName) notifyListeners(Transition(self, currentState.stateName, nextState.stateName)) }