using System; using System.Collections.Generic; using System.Linq; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; namespace MECF.Framework.Common.Fsm { /// /// 应用于构建模组(Module)状态机的对象。 /// /// /// 模组(Module)在系统中为一类控制单元,对应硬件系统的控制单元。 ///
/// 通常一个模组包含一组设备(Device),并通过Routine提供具有原子性的各种操作。 /// 设备整机有不同的模组构成,并通过调用模组下的Routine完成各个功能动作。 /// 关于Routine的细节,请参考对象。 ///
/// 模组基于有限状态机(FSM)进行工作,模组实例化时构建了状态转换表;各个动作基于状态转化完成; /// 状态机模型有效的控制模组的工作状态,有助于构建健壮的、稳定的系统架构。 ///
public class ModuleFsmDevice : FsmDevice { #region Variables /// /// 当模组发生异常时触发此事件。 /// /// /// 通常情况下,当该事件引发时,会向状态机发送Error或Alarm消息,以使状态机转换到Error或Alarm状态。 /// public event EventHandler OnEnterError; private readonly Queue _qRoutines; #endregion #region Constructors /// /// 创建模组的对象实例。 /// public ModuleFsmDevice() { _qRoutines = new Queue(); } #endregion #region Properties /// /// 返回当前模组是否在系统配置中启用。 /// public bool IsInstalled { get { if (!SC.ContainsItem("System.SetUp.Is" + base.Module + "Installed")) { return true; } return SC.GetValue("System.SetUp.Is" + base.Module + "Installed"); } } /// /// 设置或返回当前模组是否上线。 /// public bool IsOnline { get; set; } /// /// 返回当前设备正在执行的Routine的列队。 /// protected Queue QueueRoutine => _qRoutines; #endregion #region Methods /// /// 初始化模组。 /// /// public override bool Initialize() { return base.Initialize(); } /// /// 使用指定的参数启动Routine。 /// /// Routine对象的实例。 /// /// Routine的启动参数。 /// /// 该参数表会传递给Routine的Start()方法。 /// /// /// /// ///
/// Routine的执行状态。
public Result StartRoutine(IRoutine routine, params object[] args) { QueueRoutine.Clear(); QueueRoutine.Enqueue(routine); return QueueRoutine.Peek().Start(args); } /// /// 启动指定的Routine。 /// /// Routine对象的实例。 /// /// ///
/// Routine的执行状态。
public Result StartRoutine(IRoutine routine) { QueueRoutine.Clear(); QueueRoutine.Enqueue(routine); return QueueRoutine.Peek().Start(); } /// /// 启动列队中的Routine。 /// /// /// 需要将待执行的Routine添加到队列中。 /// /// /// ///
/// Routine的执行状态。 ///
public Result StartRoutine() { if (_qRoutines.Count == 0) { return Result.DONE; } var result = Result.DONE; var list = _qRoutines.ToList(); for (int i = 0; i < list.Count; _qRoutines.Dequeue(), i++) { switch (list[i].Start()) { case Result.DONE: continue; case Result.FAIL: return Result.FAIL; } break; } return Result.RUN; } /// /// 周期性扫描正在执行的Routine。 /// /// /// ///
/// Routine的执行状态。 ///
public Result MonitorRoutine() { if (_qRoutines.Count == 0) { return Result.DONE; } var routine = _qRoutines.Peek(); var result = routine.Monitor(); if (result == Result.DONE) { _qRoutines.Dequeue(); var list = _qRoutines.ToList(); for (var i = 0; i < list.Count; _qRoutines.Dequeue(), i++) { result = list[i].Start(); switch (result) { case Result.DONE: continue; case Result.FAIL: return Result.FAIL; } break; } } return result; } /// /// 终止当前模组的所有正在执行的Routine。 /// public void AbortRoutine() { if (_qRoutines != null) { if( _qRoutines.Count > 0) _qRoutines.Peek().Abort(); _qRoutines.Clear(); } } /// /// 产生模组异常事件。 /// /// protected virtual void InvokeOnEnterError(string module) { OnEnterError?.Invoke(this, module); } #endregion } }