本文共 5990 字,大约阅读时间需要 19 分钟。
状态机简介
状态存储关于过去的信息,就是说:它反映从系统开始到现在时刻的输入变化。转移指示状态变更,并且用必须满足来确使转移发生的条件来描述它。动作是在给定时刻要进行的活动的描述。有多种类型的动作:
FSM(有限状态机)可以使用上面图 1 那样的(或状态转移图)来表示。此外可以使用多种类型的。下面展示最常见的表示:当前状态(B)和条件(Y)的组合指示出下一个状态(C)。完整的动作信息可以只使用脚注来增加。包括完整动作信息的 FSM 定义可以使用。
创建状态机模型文件:stopwatch.xmlcommons-scxml commons-scxml 0.9 commons-jexl commons-jexl 1.1 xalan xalan 2.6.0
创建状态机:StopWatch.java
import org.apache.commons.scxml.SCXMLListener; import org.apache.commons.scxml.env.AbstractStateMachine; import org.apache.commons.scxml.model.ModelException; import org.apache.commons.scxml.model.State; import org.apache.commons.scxml.model.Transition; import org.apache.commons.scxml.model.TransitionTarget; import java.util.Timer; import java.util.TimerTask; public class StopWatch extends AbstractStateMachine { /** * The events for the stop watch. */ public static final String EVENT_START = "watch.start", EVENT_STOP = "watch.stop", EVENT_SPLIT = "watch.split", EVENT_UNSPLIT = "watch.unsplit", EVENT_RESET = "watch.reset"; /** * The fragments of the elapsed time. */ private int hr, min, sec, fract; /** * The fragments of the display time. */ private int dhr, dmin, dsec, dfract; /** * The stopwatch "split" (display freeze). */ private boolean split; /** * The Timer to keep time. */ private Timer timer; /** * The display decorations. */ private static final String DELIM = ":", DOT = ".", EMPTY = "", ZERO = "0"; public StopWatch() throws ModelException { super(StopWatch.class.getClassLoader().getResource("stopwatch.xml")); getEngine().addListener(getEngine().getStateMachine(), new EntryListener()); System.out.println(StopWatch.class.getClassLoader().getResource("stopwatch.xml")); } public void reset() { hr = min = sec = fract = dhr = dmin = dsec = dfract = 0; split = false; } public void running() { split = false; if (timer == null) { timer = new Timer(true); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { increment(); } }, 100, 100); } } public void paused() { split = true; } public void stopped() { timer.cancel(); timer = null; } public String getDisplay() { String padhr = dhr > 9 ? EMPTY : ZERO; String padmin = dmin > 9 ? EMPTY : ZERO; String padsec = dsec > 9 ? EMPTY : ZERO; return new StringBuffer().append(padhr).append(dhr).append(DELIM). append(padmin).append(dmin).append(DELIM).append(padsec). append(dsec).append(DOT).append(dfract).toString(); } public String getCurrentState() { return ((State)getEngine().getCurrentStatus().getStates().iterator().next()).getId(); } private void increment() { if (fract < 9) { fract++; } else { fract = 0; if (sec < 59) { sec++; } else { sec = 0; if (min < 59) { min++; } else { min = 0; if (hr < 99) { hr++; } else { hr = 0; //wrap } } } } if (!split) { dhr = hr; dmin = min; dsec = sec; dfract = fract; } } /** * A SCXMLListener that is only concerned about "onentry" * notifications. */ protected class EntryListener implements SCXMLListener { public void onEntry(final TransitionTarget entered) { System.out.println("Current State:"+entered.getId()); } public void onTransition(final TransitionTarget from, final TransitionTarget to, final Transition transition) { // nothing to do } public void onExit(final TransitionTarget exited) { // nothing to do } } }
public static void main(String[] args) throws ModelException { StopWatch stopWatch = new StopWatch(); Scanner input=new Scanner(System.in); System.out.println("event: watch.start watch.stop watch.reset watch.split watch.unsplit"); while(true){ String event=input.nextLine(); if(event.trim()!=null&&!event.trim().equals("")){ if(event.equals("exit")) break; else{ stopWatch.fireEvent(event); System.out.println(stopWatch.getCurrentState()); System.out.print(stopWatch.getDisplay()); } } } }
转载地址:http://ajxax.baihongyu.com/