using System.Collections.Generic;
|
using System.Threading;
|
using Bro.Common.FSM;
|
using System.Diagnostics;
|
|
namespace Bro.Common.Procedure
|
{
|
/// <summary>
|
/// 流程状态
|
/// </summary>
|
public enum ProcStat
|
{
|
PSInit = 0, // 初始化
|
PSOpen, // 打开
|
PSRunning, // 运行
|
PSReset, // 重置,
|
PSReseting, // 重置中
|
PSPause, // 暂停
|
PSClose, // 关闭
|
PSFnit // 销毁
|
}
|
|
/// <summary>
|
/// 处理流程基类
|
///
|
/// 说明:
|
/// 工站,工位类都可继承此类
|
/// 定义如下动作
|
/// 1. 初始化/销毁
|
/// 2. 打开/关闭
|
/// 3. 读写
|
/// 4. 设置选项
|
/// 5. 事件订阅/取消
|
/// </summary>
|
public abstract class ProcedureBase
|
{
|
#region 代理定义
|
// 状态变化事件
|
public delegate void StatChange(ProcedureBase procedure, ProcStat srcStat, ProcStat dstStat);
|
|
#endregion
|
|
#region 常量
|
|
// 线程默认等待时间(单位:毫秒)
|
protected const int DFT_WAIT_INTERVAL = 200;
|
|
#endregion
|
|
#region 事件代理
|
|
// 流程状态变化
|
public StatChange StatChangeEvent;
|
|
#endregion
|
|
#region 属性
|
// 流程描述
|
public string Desp { get; set; }
|
// 流程状态
|
public ProcStat Stat{ get { return curStat; } }
|
|
#endregion
|
|
#region 成员变量
|
|
// 流程状态机
|
protected SimpleFSM procFSM = new SimpleFSM();
|
// 流程状态
|
protected ProcStat curStat = ProcStat.PSInit;
|
// 生产工序同步事件
|
protected AutoResetEvent waitEvent = new AutoResetEvent(false);
|
// 输入队列
|
private Queue<IODataBase> requestQueue = new Queue<IODataBase>();
|
// 输入处理者
|
private List<object> requestHandlers = new List<object>();
|
|
#endregion
|
|
#region 结构体
|
|
public ProcedureBase()
|
{
|
this.Desp = this.GetType().Name;
|
|
// 设置默认的状态处理者
|
AddRequestHandler(this);
|
|
RegistProcFSM();
|
}
|
|
public ProcedureBase(SimpleFSM fsm)
|
{
|
this.Desp = this.GetType().Name;
|
this.procFSM = fsm;
|
|
// 设置默认的状态处理者
|
AddRequestHandler(this);
|
|
RegistProcFSM();
|
}
|
|
#endregion
|
|
#region 外部接口
|
|
/// <summary>
|
/// 暂停流程
|
/// </summary>
|
public virtual void Pause()
|
{
|
Trace.TraceInformation("{0} Pause", Desp);
|
|
var req = new ProcStatChangeReq();
|
req.TargetStat = ProcStat.PSPause;
|
|
AddRequest(req);
|
|
}
|
|
/// <summary>
|
/// 重置流程
|
/// </summary>
|
public virtual void Reset()
|
{
|
Trace.TraceInformation("{0} Reset", Desp);
|
|
var req = new ProcStatChangeReq();
|
req.TargetStat = ProcStat.PSReset;
|
|
AddRequest(req);
|
}
|
|
/// <summary>
|
/// 请求处理
|
/// </summary>
|
/// <param name="input"></param>
|
public void AddRequest(IODataBase req)
|
{
|
if (null == req)
|
{
|
return;
|
}
|
|
lock (requestQueue)
|
{
|
// 设置输入处理者
|
req.Handlers = this.requestHandlers;
|
|
requestQueue.Enqueue(req);
|
}
|
}
|
|
#endregion
|
|
#region 基础流程状态机
|
|
/// <summary>
|
/// 注册基本状态处理
|
/// </summary>
|
protected virtual bool RegistProcFSM()
|
{
|
int iRet = 0;
|
|
if ( null == procFSM )
|
{
|
return false;
|
}
|
|
iRet += procFSM.Regist((int)ProcStat.PSInit, DoInit) ? 0 : 1;
|
iRet += procFSM.Regist((int)ProcStat.PSOpen, DoOpen) ? 0 : 1;
|
iRet += procFSM.Regist((int)ProcStat.PSClose, DoClose) ? 0 : 1;
|
iRet += procFSM.Regist((int)ProcStat.PSRunning, DoRunning) ? 0 : 1;
|
iRet += procFSM.Regist((int)ProcStat.PSReset, DoReset) ? 0 : 1;
|
iRet += procFSM.Regist((int)ProcStat.PSReseting, DoReseting) ? 0 : 1;
|
iRet += procFSM.Regist((int)ProcStat.PSPause, DoPause) ? 0 : 1;
|
iRet += procFSM.Regist((int)ProcStat.PSFnit, DoFnit) ? 0 : 1;
|
|
// 设置初始状态
|
SetState(ProcStat.PSInit);
|
|
return (iRet == 0);
|
}
|
|
/// <summary>
|
/// 初始化
|
/// </summary>
|
public virtual void DoInit()
|
{
|
Trace.TraceInformation("{0} DoInit", Desp);
|
|
ClearIOData();
|
|
SetState(ProcStat.PSOpen);
|
}
|
|
/// <summary>
|
/// 销毁
|
/// </summary>
|
public virtual void DoFnit()
|
{
|
Trace.TraceInformation("{0} DoFnit", Desp);
|
}
|
|
/// <summary>
|
/// 开始
|
/// </summary>
|
public virtual void DoOpen()
|
{
|
Trace.TraceInformation("{0} DoOpen", Desp);
|
|
SetState(ProcStat.PSRunning);
|
}
|
|
/// <summary>
|
/// 停止
|
/// </summary>
|
public virtual void DoClose()
|
{
|
Trace.TraceInformation("{0} DoClose", this.GetType().Name);
|
|
SetState(ProcStat.PSFnit);
|
}
|
|
/// <summary>
|
/// 重置
|
/// </summary>
|
public virtual void DoReset()
|
{
|
Trace.TraceInformation("{0} DoReset", this.GetType().Name);
|
|
SetState(ProcStat.PSReseting);
|
}
|
|
/// <summary>
|
/// 重置中
|
/// </summary>
|
public virtual void DoReseting()
|
{
|
Trace.TraceInformation("{0} DoReseting", this.GetType().Name);
|
|
SetState(ProcStat.PSRunning);
|
}
|
|
/// <summary>
|
/// 暂停
|
/// </summary>
|
public virtual void DoPause()
|
{
|
// 等待
|
waitEvent.WaitOne(DFT_WAIT_INTERVAL);
|
}
|
|
/// <summary>
|
/// 就绪
|
/// </summary>
|
public virtual void DoRunning()
|
{
|
// TODO:流程就绪,主处理
|
|
}
|
|
#endregion
|
|
#region 请求处理
|
|
/// <summary>
|
/// 状态转变请求
|
/// </summary>
|
/// <param name="req"></param>
|
/// <returns></returns>
|
protected bool HandleRequest(ProcStatChangeReq req)
|
{
|
Trace.TraceInformation("{0} HandleRequest cur stat:{1} target:{2}",
|
Desp, GetStatDesp(Stat), GetStatDesp(req.TargetStat));
|
|
if ( req.TargetStat == Stat )
|
{
|
Trace.TraceWarning("{0} HandleRequest fail, already in {1}", Desp, GetStatDesp(req.TargetStat));
|
return true;
|
}
|
|
if ( ProcStat.PSRunning != this.Stat )
|
{
|
Trace.TraceWarning("{0} not running, can't turn to {1}", Desp, GetStatDesp(req.TargetStat));
|
return true;
|
}
|
|
SetState(req.TargetStat);
|
|
return true;
|
}
|
|
#endregion
|
|
#region 其他方法
|
|
/// <summary>
|
/// 运行
|
/// </summary>
|
public virtual void Run()
|
{
|
procFSM.Run();
|
|
Routine();
|
}
|
|
/// <summary>
|
/// 流程每次运行的例程
|
/// </summary>
|
protected virtual void Routine()
|
{
|
// 处理请求
|
HandleRequests();
|
}
|
|
/// <summary>
|
/// 设置状态
|
/// </summary>
|
/// <param name="stat"></param>
|
protected internal void SetState(ProcStat stat)
|
{
|
var srcStat = GetStatDesp(curStat);
|
var dstStat = GetStatDesp(stat);
|
var tempStat = curStat;
|
|
curStat = stat;
|
|
if (null == procFSM)
|
{
|
return;
|
}
|
|
Trace.TraceInformation("{0} stat [{1}]-->[{2}]", Desp, srcStat, dstStat);
|
|
procFSM.SetStat((int)stat);
|
|
// 通知流程状态变化
|
if (null != StatChangeEvent)
|
{
|
StatChangeEvent(this, tempStat, stat);
|
}
|
}
|
|
/// <summary>
|
/// 设置输入处理者
|
/// </summary>
|
/// <param name="handler"></param>
|
public void AddRequestHandler(object handler)
|
{
|
requestHandlers.Add(handler);
|
}
|
|
/// <summary>
|
/// 处理输入
|
/// </summary>
|
protected void HandleRequests()
|
{
|
var req = NextReq();
|
if ( null == req )
|
{
|
return;
|
}
|
|
Trace.TraceInformation("[{0}] HandleRequest {1} ", Desp, req.GetType().Name);
|
|
// 输入处理派遣
|
req.Dispatch();
|
}
|
|
/// <summary>
|
/// 获取下个输入
|
/// </summary>
|
/// <returns></returns>
|
protected IODataBase NextReq()
|
{
|
return NextData(requestQueue);
|
}
|
|
/// <summary>
|
/// 添加数据
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="dataQueue"></param>
|
protected void AddQueue(IODataBase data, Queue<IODataBase> dataQueue)
|
{
|
if ( null == data || null == dataQueue )
|
{
|
return;
|
}
|
|
lock(dataQueue)
|
{
|
dataQueue.Enqueue(data);
|
}
|
}
|
|
/// <summary>
|
/// 获取下个数据
|
/// </summary>
|
/// <param name="dataQueue"></param>
|
/// <returns></returns>
|
protected IODataBase NextData(Queue<IODataBase> dataQueue)
|
{
|
IODataBase ioData = null;
|
|
lock(dataQueue)
|
{
|
if ( dataQueue.Count > 0 )
|
{
|
ioData = dataQueue.Dequeue();
|
}
|
}
|
|
return ioData;
|
}
|
|
/// <summary>
|
/// 情空输入数据
|
/// </summary>
|
protected void ClearIOData()
|
{
|
lock(requestQueue)
|
{
|
requestQueue.Clear();
|
}
|
}
|
|
/// <summary>
|
/// 获取状态描述
|
/// </summary>
|
/// <param name="procStat"></param>
|
/// <returns></returns>
|
private string GetStatDesp(ProcStat procStat)
|
{
|
var desp = "";
|
|
switch (procStat)
|
{
|
case ProcStat.PSInit:
|
desp = "PSInit";
|
break;
|
case ProcStat.PSFnit:
|
desp = "PSFnit";
|
break;
|
case ProcStat.PSOpen:
|
desp = "PSOpen";
|
break;
|
case ProcStat.PSClose:
|
desp = "PSClose";
|
break;
|
case ProcStat.PSRunning:
|
desp = "PSRunning";
|
break;
|
case ProcStat.PSPause:
|
desp = "PSPause";
|
break;
|
case ProcStat.PSReset:
|
desp = "PSReset";
|
break;
|
case ProcStat.PSReseting:
|
desp = "PSReseting";
|
break;
|
default:
|
desp = "Unknow";
|
break;
|
}
|
|
return desp;
|
}
|
|
#endregion
|
}
|
|
}
|