?? state.java
字號(hào):
/***************************************************************************** * net.openai.fsm.State ***************************************************************************** * @author JC on E * @date 9/18/2000 * 2001 OpenAI Labs *****************************************************************************/package net.openai.util.fsm;import java.util.Vector;import java.io.Serializable;import net.openai.util.fsm.event.StateEvent;import net.openai.util.fsm.event.StateListener;/** * State abstract class */public abstract class State implements Serializable { /** The current "number" for the state name. */ private static int stateNumber = 0; /** A Vector of Conditions to check. */ private Vector conditions = new Vector(); /** The name of this state. */ private String name = getDefaultName(); /** A flag to indicate that we are a start state. This can only be set by the Machine itself. If you wish to set a State as a start state you must call <code>setStartState()</code> on the machine itself. */ private boolean startState = false; /** A flag to indicate that this is an end state. Unlike the start state flag, a state's end state flag can freely be changed on the state itself. */ private boolean endState = false; /** A list of listeners for this state. */ private Vector listeners = new Vector(); /** * Constructs a new state name that is given by default. */ private static synchronized String getDefaultName() { return "<Unnamed State " + (stateNumber++) + ">"; } /** * Sets the name for this state. If the name passed in is null, then a * <code>NullPointerException</code> will be generated. * * @param name The new name for this state. */ public final void setName(String name) { if(name == null) throw new NullPointerException("The state name cannot be null!"); this.name = new String(name); } /** * Returns the name of this state. * * @return A String that represents the name of this state. */ public final String getName() { return new String(name); } /** * This method will only be called by the machine itself. It sets the * start state flag for this state. * * @param startState The new start state flag. */ final void setStartStateFlag(boolean startState) { if(startState == this.startState) return; this.startState = startState; fireStateEvent(StateEvent.START_FLAG_CHANGE); } /** * Returns true if this state is a start state, false otherwise. * * @return The value of this state's start state flag. */ public final boolean getStartStateFlag() { return startState; } /** * Sets the value of this state's end state flag. * * @param endState The new value of this state's end state flag. */ public final void setEndStateFlag(boolean endState) { if(endState == this.endState) return; this.endState = endState; fireStateEvent(StateEvent.END_FLAG_CHANGE); } /** * Returns true if this state is an end state, false otherwise. * * @return The value of this state's end state flag. */ public final boolean getEndStateFlag() { return endState; } /** * Adds a StateListener to this State that we will deliver events to. * * @param listener The StateListener to add. */ public final void addStateListener(StateListener listener) { if(listener == null) throw new NullPointerException("Cannot add null listener."); synchronized(listeners) { if(!listeners.contains(listener)) listeners.addElement(listener); } } /** * Removes a StateListener from this State. * * @param listener The StateListener to remove. */ public final void removeStateListener(StateListener listener) { if(listener == null) return; synchronized(listeners) { listeners.removeElement(listener); } } /** * Sends a StateEvent to all of the listeners on this State. * * @param type The type of event to fire. */ private void fireStateEvent(int type) { Vector toFireTo = null; synchronized(listeners) { toFireTo = (Vector)listeners.clone(); } int numListeners = toFireTo.size(); for(int i = 0; i < numListeners; i++) ((StateListener)toFireTo.elementAt(i)). handleStateEvent(new StateEvent(this, type)); } /** * Adds a Condition to this State. If this is the current state in the * machine when the machine is receiving input, then this state will * iterate down the list of conditions to find the first one that is * met by the input to the machine. Once the first condition that * satisfies the input is found, then the condition's target state * will be returned to the machine as the new curren state. * <br><br> * NOTE: Subsequent calls to this method with the same condition will * put the condition at the end of the list of conditions to be * checked. * * @param condition The new Condition to add. */ public final void addTransition(Condition condition) { // Both condition and state must be non-null if(condition == null) throw new NullPointerException("Cannot add null Condition"); synchronized(conditions) { if(conditions.contains(condition)) conditions.removeElement(condition); conditions.addElement(condition); } condition.addSourceState(this); } /** * Convenience method for adding a transition from this state to the next. * This method simply calls addTransition() on this state and then calls * setTargetState() the condition. * * @param condition The new Condition to add. * @param targetState The target state for this transition. */ public final void addTransition(Condition condition, State targetState) { addTransition(condition); condition.setTargetState(targetState); } /** * Removes a Condition as a Transition from this State. * * @param condition The Condition/Transition to remove. */ public final void removeTransition(Condition condition) { if(condition == null) return; condition.removeSourceState(this); synchronized(conditions) { conditions.removeElement(condition); } } /** * Returns a Vector of the current Conditions/Transitions for this State. * * @return The current list of Conditions for this State or null if there * aren't any. */ public final Vector getTransitions() { Vector returnValue = null; synchronized(conditions) { if(!conditions.isEmpty()) returnValue = (Vector)conditions.clone(); } return returnValue; } /** * Iterates through the Condition list and finds the first Condition * that meets <code>condition</code> and returns the associated State. * If no conditions match, then null is returned. * * @param condition The condition to check. For example, if the set of * Conditions check for a particular Integer, then the * first Condition that matches the Integer passed into * this method will be "met" and the associated State * will be returned. * @return The State that maps to the matching Condition or null if no * Conditions meet the criteria. */ final State input(Object condition) { // condition must be non-null if(condition == null) throw new NullPointerException("Null input condition"); Vector toCheck = getTransitions(); if(toCheck == null) return null; // Iterate through the list of Conditions and find the first match int numConditions = toCheck.size(); for(int i = 0; i < numConditions; i++) { Condition cond = (Condition)toCheck.elementAt(i); if(cond.satisfiedBy(condition)) return cond.getTargetState(); } // No conditions matched, so return null return null; } /** * Called directly by the machine when this state is entered. * * @param input The input to feed into this state. */ void enterState(Object input) { fireStateEvent(StateEvent.ENTER_START); enter(input); fireStateEvent(StateEvent.ENTER_END); } /** * Called directly by the machine when this state is exited. * * @return Any output object that is to be fed into the next state. */ Object exitState() { fireStateEvent(StateEvent.EXIT_START); Object returnValue = exit(); fireStateEvent(StateEvent.EXIT_END); return returnValue; } /** * This method is called when the state is entered. * * @param input Any output from a previous state will become the input * for this state. If this is a start state, then * <code>input</code> will be <code>null</code>. */ public abstract void enter(Object input); /** * This method is called when the state is exited via a transition to * another state. * * @return Any output object that is to be fed into the next state. */ public abstract Object exit();}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -