请努力看懂下面的例子:这个事件Event{id = "messageReceived", arguments =[ArrayList a = [...], Integer b = 1024]}下面的方法将和这个事件是等价的:
// All method arguments matches all event arguments directly@Transition(on = "messageReceived")public void messageReceived(ArrayList l, Integer i) { ... }// Matches since ((a instanceof List && b instanceof Number) == true)@Transition(on = "messageReceived")public void messageReceived(List l, Number n) { ... }// Matches since ((b instanceof Number) == true)@Transition(on = "messageReceived")public void messageReceived(Number n) { ... }// Methods with no arguments always matches@Transition(on = "messageReceived")public void messageReceived() { ... }// Methods only interested in the current Event or StateContext always matches@Transition(on = "messageReceived")public void messageReceived(StateContext context) { ... }// Matches since ((a instanceof Collection) == true)@Transition(on = "messageReceived")public void messageReceived(Event event, Collection c) { ... }
但是下面的方法不会和这个事件相匹配:
// Incorrect ordering@Transition(on = "messageReceived")public void messageReceived(Integer i, List l) { ... }// ((a instanceof LinkedList) == false)@Transition(on = "messageReceived")public void messageReceived(LinkedList l, Number n) { ... }// Event must be first argument@Transition(on = "messageReceived")public void messageReceived(ArrayList l, Event event) { ... }// StateContext must be second argument if Event is used@Transition(on = "messageReceived")public void messageReceived(Event event, ArrayList l, StateContext context) { ... }// Event must come before StateContext@Transition(on = "messageReceived")public void messageReceived(StateContext context, Event event) { ... }
状态继承:StateMachine.handle(Event)方法如果不能找到一个transaction和当前的事件在当前的状态中匹配的话就是去找他得父状态,依次类推,知道找到为止,所以我们有时候很需要状态的继承:
@State public static final String A = "A";@State(A) public static final String B = "A->B";@State(A) public static final String C = "A->C";@State(B) public static final String D = "A->B->D";@State(C) public static final String E = "A->C->E";运行:
public static void main(String[] args) {...deck.load("The Knife - Silent Shout");deck.play();deck.pause();deck.play();deck.stop();deck.eject();deck.play();}可能会保以下的错误,至少我第一次是报错的:
...Tape stoppedTape ejectedException in thread "main" o.a.m.sm.event.UnhandledEventException: Unhandled event: org.apache.mina.statemachine.event.Event@15eb0a9[id=play,...]at org.apache.mina.statemachine.StateMachine.handle(StateMachine.java:285)at org.apache.mina.statemachine.StateMachine.processEvents(StateMachine.java:142)这个异常我们无法处理,所以我们将添加一个指定的事务来处理所有不能匹配的事件:
@Transitions({@Transition(on = "*", in = EMPTY, weight = 100),@Transition(on = "*", in = LOADED, weight = 100),@Transition(on = "*", in = PLAYING, weight = 100),@Transition(on = "*", in = PAUSED, weight = 100)})public void error(Event event) {System.out.println("Cannot '" + event.getId() + "' at this time");}运行:
Tape stoppedTape ejectedCannot 'play' at this time.当然,定义所有状态的root更有效:
public static class TapeDeckHandler {@State public static final String ROOT = "Root";@State(ROOT) public static final String EMPTY = "Empty";@State(ROOT) public static final String LOADED = "Loaded";@State(ROOT) public static final String PLAYING = "Playing";@State(ROOT) public static final String PAUSED = "Paused";...@Transition(on = "*", in = ROOT)public void error(Event event) {System.out.println("Cannot '" + event.getId() + "' at this time");}}