add documentation and compat implicit to FSM
This commit is contained in:
parent
3d04acf314
commit
42b72f0c4b
2 changed files with 57 additions and 2 deletions
|
|
@ -98,6 +98,23 @@ object FSM {
|
|||
* Each of the above also supports the method <code>replying(AnyRef)</code> for
|
||||
* sending a reply before changing state.
|
||||
*
|
||||
* While changing state, custom handlers may be invoked which are registered
|
||||
* using <code>onTransition</code>. This is meant to enable concentrating
|
||||
* different concerns in different places; you may choose to use
|
||||
* <code>when</code> for describing the properties of a state, including of
|
||||
* course initiating transitions, but you can describe the transitions using
|
||||
* <code>onTransision</code> to avoid having to duplicate that code among
|
||||
* multiple paths which lead to a transition:
|
||||
*
|
||||
* <pre>
|
||||
* onTransition {
|
||||
* case Active -> _ => cancelTimer("activeTimer")
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Multiple such blocks are supported and all of them will be called, not only
|
||||
* the first matching one.
|
||||
*
|
||||
* Another feature is that other actors may subscribe for transition events by
|
||||
* sending a <code>SubscribeTransitionCallback</code> message to this actor;
|
||||
* use <code>UnsubscribeTransitionCallback</code> before stopping the other
|
||||
|
|
@ -247,12 +264,43 @@ trait FSM[S, D] {
|
|||
|
||||
/**
|
||||
* Set handler which is called upon each state transition, i.e. not when
|
||||
* staying in the same state.
|
||||
* staying in the same state. This may use the pair extractor defined in the
|
||||
* FSM companion object like so:
|
||||
*
|
||||
* <pre>
|
||||
* onTransition {
|
||||
* case Old -> New => doSomething
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* It is also possible to supply a 2-ary function object:
|
||||
*
|
||||
* <pre>
|
||||
* onTransition(handler _)
|
||||
*
|
||||
* private def handler(from: S, to: S) { ... }
|
||||
* </pre>
|
||||
*
|
||||
* The underscore is unfortunately necessary to enable the nicer syntax shown
|
||||
* above (it uses the implicit conversion total2pf under the hood).
|
||||
*
|
||||
* <b>Multiple handlers may be installed, and every one of them will be
|
||||
* called, not only the first one matching.</b>
|
||||
*/
|
||||
protected final def onTransition(transitionHandler: TransitionHandler) = {
|
||||
protected final def onTransition(transitionHandler: TransitionHandler) {
|
||||
transitionEvent :+= transitionHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper for using a total function instead of a partial
|
||||
* function literal. To be used with onTransition.
|
||||
*/
|
||||
implicit protected final def total2pf(transitionHandler: (S, S) => Unit) =
|
||||
new PartialFunction[(S, S), Unit] {
|
||||
def isDefinedAt(in : (S, S)) = true
|
||||
def apply(in : (S, S)) { transitionHandler(in._1, in._2) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Set handler which is called upon termination of this FSM actor.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -68,6 +68,13 @@ object FSMActorSpec {
|
|||
case Locked -> Open => transitionLatch.open
|
||||
}
|
||||
|
||||
// verify that old-style does still compile
|
||||
onTransition (transitionHandler _)
|
||||
|
||||
def transitionHandler(from: LockState, to: LockState) = {
|
||||
// dummy
|
||||
}
|
||||
|
||||
onTermination {
|
||||
case StopEvent(Shutdown, Locked, _) =>
|
||||
// stop is called from lockstate with shutdown as reason...
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue