using System; using Microsoft.SPOT; namespace HSM { public class BASE_HSM { public static Event NullEvent = new Event(Signal.Null); public static Event InitEvent = new Event(Signal.Init); public static Event EntryEvent = new Event(Signal.Entry); public static Event DeepHistoryEvent = new Event(Signal.DeepHistory); public static Event ExitEvent = new Event(Signal.Exit); public static Event UserEvent = new Event(Signal.User); protected void Initialize(State topState) { // init top state this.topState = topState; // init deep history table StateHistory.Clear(); // transition to initial top state InitTransitionState(topState); } protected Boolean IsParent(State parentState, State childState) { do { childState = childState(NullEvent); if (childState == parentState) return true; } while (childState != null); return false; } protected void TransitionState(State newState, bool toDeepHist) { // retrive historical state if appropriate if (toDeepHist) { newState = StateHistory.Retrieve(newState); if (newState == null) { Debug.Print("TransitionState: ERROR - RetrieveDeephist failed!"); return; } } // exit signal to current state if (curState != null) { State parentState; // record the deep history state if appropriate parentState = curState(NullEvent); while (parentState != null) { // the top state cannot have a history sub state and returns stnone to all // unhandled signals anyhow if (parentState == topState) break; else if ((parentState(DeepHistoryEvent) == null) && (!IsParent(parentState, newState))) { StateHistory.Record(parentState, curState); break; } parentState = parentState(NullEvent); } // state exit chain curState(ExitEvent); parentState = curState(NullEvent); while (!IsParent(parentState, newState)) { parentState(ExitEvent); parentState = parentState(NullEvent); } // set current state to parent state curState = parentState; } else Debug.Print("TransitionState: ERROR - current state is invalid!"); // entry signal to new state while (curState != newState) { State parentState = newState; State lastChild = newState; while (true) { parentState = parentState(NullEvent); if (parentState == curState) { lastChild(EntryEvent); // set current state to last child state curState = lastChild; break; } lastChild = parentState; } } // init signal to new state newState(InitEvent); } protected void TransitionState(State newState) { TransitionState(newState, false); } protected void InitTransitionState(State newState) { // set new state curState = newState; if (curState != null) { // entry signal to current state curState(EntryEvent); // init signal to current state curState(InitEvent); } else Debug.Print("InitTransitionState: ERROR - current state is invalid!\n"); } public void SignalCurrentState(Event e) { if (curState != null) { State parentState = curState; do parentState = parentState(e); while (parentState != null); } else Debug.Print("SignalCurrentState: ERROR - current state is invalid!\n"); } protected Boolean IsInState(State state) { State parentState = curState; do { if (state == parentState) return true; parentState = parentState(NullEvent); } while (parentState != null); return false; } private History StateHistory = new History(); private State curState = null; private State topState = null; } }