public Boolean Deactive(params SafeID[] tIDs) { if (!this.Available) { return(false); } else if (!this.IsActive) { return(false); } else if (null == tIDs) { return(false); } else if (0 == tIDs.Length) { return(false); } lock (m_Locker) { foreach (SafeID tID in tIDs) { State tTarget = m_ActiveFSMSet.Find(tID); if (null != tTarget) { m_ActiveFSMSet.Remove(tID); IFSM tFSM = tTarget as IFSM; if (null != tFSM) { do { tFSM.RequestStop(); }while (tFSM.IsActive); tFSM.Reset(); } m_FreeStateSet.Add(tTarget); } tTarget = m_ActiveStateSet.Find(tID); if (null != tTarget) { tTarget.StopSignal.Set(); m_ActiveStateSet.Remove(tID); m_FreeStateSet.Add(tTarget); } } } RefreshState(); return(true); }
public override Status Task(params object[] tArgs) { if (!this.Available) { return(m_Status); } do { switch (m_Status) { case Status.FSM_STARTING: m_Status = Status.FSM_WORKING; break; case Status.FSM_CLOSING: case Status.FSM_PENDING: case Status.FSM_WORKING: break; case Status.FSM_ERROR: case Status.FSM_INVALID: case Status.FSM_CANCELLED: case Status.FSM_CLOSED: case Status.FSM_IDLE: default: return(m_Status); } //! stop event if (m_Event.WaitOne(0)) { lock (m_Locker) { foreach (State tItem in m_ActiveStateSet) { if (null == tItem) { continue; } else if (!tItem.Available) { continue; } if ((tItem.IsActive) || (tItem.Status == Status.FSM_IDLE)) { tItem.StopSignal.Set(); } } foreach (State tItem in m_ActiveFSMSet) { if (null == tItem) { continue; } else if (!tItem.Available) { continue; } IFSM tFSM = tItem as IFSM; if (null == tFSM) { continue; } if ((tFSM.IsActive) || (tFSM.Status == Status.FSM_IDLE)) { tFSM.RequestStop(); } } m_Event.Reset(); } } m_StateChanged = false; //!< reset state change flag lock (m_Locker) { State[] tActiveStates = m_ActiveStateSet.ToArray(); foreach (State tItem in tActiveStates) { if (null == tItem) { continue; } else if (!tItem.Available) { continue; } switch (tItem.Task(m_Args)) { case Status.FSM_PENDING: case Status.FSM_CLOSING: case Status.FSM_STARTING: case Status.FSM_WORKING: break; case Status.FSM_ERROR: //! encountered an unhandled error if (ErrorHandler(m_Args)) { continue; } m_Status = Status.FSM_ERROR; return(m_Status); case Status.FSM_INVALID: case Status.FSM_CANCELLED: case Status.FSM_CLOSED: case Status.FSM_IDLE: default: m_FreeStateSet.Add(tItem); m_ActiveStateSet.Remove(tItem.ID); m_StateChanged = true; break; } } tActiveStates = m_ActiveFSMSet.ToArray(); foreach (State tItem in tActiveStates) { if (null == tItem) { continue; } else if (!tItem.Available) { continue; } switch (tItem.Task(m_Args)) { case Status.FSM_ERROR: m_Status = Status.FSM_ERROR; return(m_Status); case Status.FSM_CLOSING: case Status.FSM_PENDING: case Status.FSM_STARTING: case Status.FSM_WORKING: break; case Status.FSM_INVALID: case Status.FSM_CANCELLED: case Status.FSM_CLOSED: case Status.FSM_IDLE: default: m_FreeStateSet.Add(tItem); m_ActiveFSMSet.Remove(tItem.ID); m_StateChanged = true; IFSM tFSM = tItem as IFSM; if (null != tFSM) { tFSM.Reset(); } do { miniFSM tminiFSM = tItem as miniFSM; if (null == tminiFSM) { break; } else if (null == tminiFSM.ReturnStateID) { break; } this.TriggerFSM(tminiFSM.ReturnStateID, m_Args); }while (false); break; } } } RefreshState(); }while (m_StateChanged); return(m_Status); }
public Status RequestStop(int tMilionsecond) { lock (m_Event) { switch (m_Status) { case Status.FSM_CLOSING: lock (m_Locker) { if ((m_ActiveFSMSet.Count == 0) && (m_ActiveStateSet.Count == 0)) { if (0 == m_FreeStateSet.Count) { m_Status = Status.FSM_INVALID; } else { m_Status = Status.FSM_CLOSED; } break; } } //! force to stop if (m_StopWatch.ElapsedMilliseconds >= tMilionsecond) { lock (m_Locker) { if (m_ActiveStateSet.Count > 0) { foreach (State tItem in m_ActiveStateSet) { if (null == tItem) { continue; } else if (!tItem.Available) { continue; } m_FreeStateSet.Add(tItem); } } m_ActiveStateSet.Clear(); if (m_ActiveFSMSet.Count > 0) { foreach (State tItem in m_ActiveFSMSet) { if (null == tItem) { continue; } else if (!tItem.Available) { continue; } IFSM tFSMItem = tItem as IFSM; if (null == tFSMItem) { continue; } do { tFSMItem.RequestStop(tMilionsecond); }while (tFSMItem.IsActive); tFSMItem.Reset(); m_FreeStateSet.Add(tItem); } } m_ActiveFSMSet.Clear(); m_StopWatch.Stop(); m_Status = Status.FSM_CLOSED; } } break; case Status.FSM_CANCELLED: case Status.FSM_CLOSED: case Status.FSM_IDLE: case Status.FSM_INVALID: break; case Status.FSM_ERROR: case Status.FSM_PENDING: case Status.FSM_STARTING: case Status.FSM_WORKING: m_Status = Status.FSM_CLOSING; m_Event.Set(); m_StopWatch.Reset(); m_StopWatch.Start(); //! raising closing event if (null != FSMClosing) { try { FSMClosing.Invoke(this, m_Args); } catch (Exception) { } } break; default: break; } } return(m_Status); }