public Boolean CallFSM(SafeID tID, String tReturnID, params Object[] tArgs) { if (!this.Available) { return(false); } else if (!this.IsActive) { return(false); } lock (m_Locker) { State tTarget = m_FreeStateSet.Find(tID); if (null != tTarget) { if (!tTarget.Available) { return(false); } if (tTarget.IsFSM) { IFSM tFSM = tTarget as IFSM; if (null == tFSM) { return(false); } m_FreeStateSet.Remove(tID); m_ActiveFSMSet.Add(tTarget); tFSM.Reset(); do { miniFSM tminiFSM = tFSM as miniFSM; if (null == tminiFSM) { break; } tminiFSM.m_ReturnStateID = tReturnID; }while (false); tFSM.Start(tArgs); } else { m_FreeStateSet.Remove(tID); m_ActiveStateSet.Add(tTarget); } } } m_StateChanged = true; RefreshState(); return(true); }
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 Boolean Start(params Object[] tArgs) { if ((m_Status != Status.FSM_IDLE) || (0 == m_FreeStateSet.Count)) { return(false); } lock (m_Locker) { State tFirstState = m_FreeStateSet.Items[0]; if (!tFirstState.Available) { return(false); } if (tFirstState.IsFSM) { IFSM tFSM = tFirstState as IFSM; if (null == tFSM) { return(false); } else if (tFSM.Reset()) { return(false); } else if (!tFSM.Start(tArgs)) { return(false); } m_ActiveFSMSet.Add(tFirstState); } else { m_ActiveStateSet.Add(tFirstState); } m_Args = tArgs; m_Status = Status.FSM_STARTING; if (null != FSMStarted) { try { FSMStarted.Invoke(this, m_Args); } catch (Exception) { } } } return(true); }
public Boolean TriggerFSM(SafeID tID, params Object[] tArgs) { if (!this.Available) { return(false); } else if (!this.IsActive) { return(false); } lock (m_Locker) { State tTarget = m_FreeStateSet.Find(tID); if (null != tTarget) { if (!tTarget.Available) { return(false); } if (tTarget.IsFSM) { IFSM tFSM = tTarget as IFSM; if (null == tFSM) { return(false); } m_FreeStateSet.Remove(tID); m_ActiveFSMSet.Add(tTarget); tFSM.Reset(); tFSM.Start(tArgs); } else { m_FreeStateSet.Remove(tID); m_ActiveStateSet.Add(tTarget); } } } m_StateChanged = true; 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); }