/// <summary> /// Remove FSM from processor. /// </summary> /// <param name="fsm">FSM to remove</param> private void RemoveFsm( Fsm fsm ) { PopFsm(fsm); System.Threading.Monitor.Exit(this); try { fsm.OnFsmExit(); fsm.Done(); } finally { System.Threading.Monitor.Enter(this); } }
/// <summary> /// Terminate the FSM. /// </summary> /// <param name="fsm">The FSM, which sould be terminated</param> // Terminate a specific fsm. this call is asynchronous. To wait on completion, // call the FSMs "Wait" method. public void TerminateFsm( Fsm fsm ) { if (Thread.CurrentThread.GetHashCode() == thread.GetHashCode()) { RemoveFsm(fsm); } else { TerminateFsmEvent ev = new TerminateFsmEvent(); PushEvent( ev, fsm ); } }
/// <summary> /// Push an fsm to the processor. The processor will put it in its list /// and call OnFsmEntry of the FSM in the context of its thread. /// </summary> public void PushFsm(Fsm fsm) { fsm.FsmProcessor = this; lock(this) { jobQueue.Enqueue(fsm); Monitor.Pulse(this); } }
/// <summary> /// Push timer event on an FSM using this processor /// </summary> /// <param name="fsmTimerEvent">timer event to push</param> /// <param name="fsm">target FSM</param> public void PushEvent( FsmTimerEvent fsmTimerEvent, Fsm fsm ) { lock(this) { fsmTimerEvent.Fsm = fsm; bool inserted = false; for (int i = 0; i < timerList.Count; i++) { if (((FsmTimerEvent)timerList[i]).ExpiryTime >= fsmTimerEvent.ExpiryTime) { timerList.Insert(i,fsmTimerEvent); inserted = true; break; } } if (!inserted) { timerList.Add(fsmTimerEvent); } timerListChanged = true; Monitor.Pulse(this); } }
/// <summary> /// Push event on an FSM using this processor /// </summary> /// <param name="fsmEvent">event to push</param> /// <param name="fsm">target FSM</param> public void PushEvent( FsmEvent fsmEvent, Fsm fsm ) { lock(this) { fsmEvent.Fsm = fsm; jobQueue.Enqueue(fsmEvent); Monitor.Pulse(this); } }
/// <summary> /// Used internally by the processor itself and the FSM to remove the FSM from the active FSM list. /// Do NOT call this method directly! Use TerminateFsm instead /// </summary> /// <param name="fsm">The Fsm to remove</param> public void PopFsm(Fsm fsm) { // Call PopFsm only from processor thread. Debug.Assert(Thread.CurrentThread.GetHashCode() == thread.GetHashCode()); fsmList.Remove(fsm.GetHashCode()); // remove timers for fsm // runs on fsm processor thread for (int i = 0; i < timerList.Count; i++) { if (((FsmTimerEvent)timerList[i]).Fsm.GetHashCode() == fsm.GetHashCode()) { ((FsmTimerEvent)timerList[i]).Enable = false; } } }