using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
namespace Aitex.Core.RT.Routine
{
public class SeqenecRoutine2
{
//timer, 计算routine时间
protected DeviceTimer counter = new DeviceTimer();
protected DeviceTimer delayTimer = new DeviceTimer();
private enum STATE
{
IDLE,
WAIT,
}
public int TokenId
{
get { return _id; }
}
private int _id; //step index
private int _currentTokenId = -1;
///
/// already done steps
///
private Stack _steps = new Stack();
private STATE state; //step state //idel,wait,
//loop control
private int loop = 0;
private int loopCount = 0;
private int loopID = 0;
private DeviceTimer timer = new DeviceTimer();
public int LoopCounter { get { return loop; } }
public int LoopTotalTime { get { return loopCount; } }
// public int Timeout { get { return (int)(timer.GetTotalTime() / 1000); } }
//状态持续时间,单位为秒
public int Elapsed { get { return (int)(timer.GetElapseTime() / 1000); } }
protected RoutineResult RoutineToken = new RoutineResult() { Result = RoutineState.Running };
protected Tuple ExecuteResult;
public void Reset()
{
_id = 0;
_steps.Clear();
loop = 0;
loopCount = 0;
state = STATE.IDLE;
counter.Start(60*60*100); //默认1小时
RoutineToken.Result = RoutineState.Running;
_currentTokenId = -1;
ExecuteResult = Tuple.Create(false, Result.DONE);
}
protected void PerformRoutineStep(int id, Func execution, RoutineResult result)
{
if (!Acitve(id))
return;
result.Result = execution();
}
#region interface
public void StopLoop()
{
loop = loopCount;
}
public Tuple Loop(T id, Func func, int count)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (!func())
{
return Tuple.Create(bActive, Result.FAIL); //执行错误
}
loopID = idx;
loopCount = count;
next();
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
public Tuple EndLoop(T id, Func func)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (++loop >= loopCount) //Loop 结束
{
if (!func())
{
return Tuple.Create(bActive, Result.FAIL); //执行错误
}
loop = 0;
loopCount = 0; // Loop 结束时,当前loop和loop总数都清零
next();
return Tuple.Create(true, Result.RUN);
}
//继续下一LOOP
next(loopID);
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
public Tuple ExecuteAndWait(T id, IRoutine routine)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (state == STATE.IDLE)
{
Result startRet = routine.Start();
if (startRet == Result.FAIL)
{
return Tuple.Create(true, Result.FAIL); //执行错误
}else if (startRet == Result.DONE)
{
next();
return Tuple.Create(true, Result.DONE);
}
state = STATE.WAIT;
}
Result ret = routine.Monitor();
if (ret == Result.DONE)
{
next();
return Tuple.Create(true, Result.DONE);
}
else if (ret == Result.FAIL || ret == Result.TIMEOUT)
{
return Tuple.Create(true, Result.FAIL);
}
else
{
return Tuple.Create(true, Result.RUN);
}
}
return Tuple.Create(false, Result.RUN);
}
public Tuple ExecuteAndWait(T id, List routines)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (state == STATE.IDLE)
{
foreach (var item in routines)
{
if (item.Start() == Result.FAIL)
return Tuple.Create(true, Result.FAIL);
}
state = STATE.WAIT;
}
//wait all sub failed or completedboo
bool bFail = false;
bool bDone = true;
foreach (var item in routines)
{
Result ret = item.Monitor();
bDone &= (ret == Result.FAIL || ret == Result.DONE);
bFail |= ret == Result.FAIL;
}
if (bDone)
{
next();
if(bFail)
return Tuple.Create(true, Result.FAIL);
return Tuple.Create(true, Result.DONE);
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
public Tuple Check(T id, Func func) //顺序执行
{
return Check(Check(Convert.ToInt32(id), func));
}
public Tuple Execute(T id, Func func) //顺序执行
{
return Check(execute(Convert.ToInt32(id), func));
}
public Tuple Wait(T id, Func func, double timeout = int.MaxValue) //Wait condition
{
return Check(wait(Convert.ToInt32(id), func, timeout));
}
public Tuple Wait(T id, Func func, double timeout = int.MaxValue) //Wait condition
{
return Check(wait(Convert.ToInt32(id), func, timeout));
}
public Tuple ExecuteAndWait(T id, Func execute, Func check, double timeout = int.MaxValue)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
Result? bExecute = Result.RUN;
if (bActive)
{
//if (idx != _currentTokenId && ExecuteResult.Item1) return ExecuteResult;
if (state == STATE.IDLE)
{
if (!execute())
{
ExecuteResult = Tuple.Create(bActive, Result.FAIL);
return Tuple.Create(bActive, Result.FAIL); //执行错误
}
timer.Start(timeout);
state = STATE.WAIT;
_currentTokenId = idx;
}
bExecute = check();
if (bExecute == null)
{
ExecuteResult = Tuple.Create(bActive, Result.FAIL);
return Tuple.Create(bActive, Result.FAIL); //Termianate
}
else
{
if (bExecute == Result.DONE) //检查Success, next
{
next();
ExecuteResult = Tuple.Create(true, Result.RUN);
return Tuple.Create(true, Result.RUN);
}
if (bExecute == Result.Succeed) //检查Success, next
{
next();
ExecuteResult = Tuple.Create(true, Result.RUN);
return Tuple.Create(true, Result.RUN);
}
if (bExecute == Result.FAIL) //检查 Fail 直接返回Fail
{
ExecuteResult = Tuple.Create(true, Result.FAIL);
return Tuple.Create(true, Result.FAIL);
}
}
if (timer.IsTimeout())
{
ExecuteResult = Tuple.Create(true, Result.TIMEOUT);
return Tuple.Create(true, Result.TIMEOUT);
}
ExecuteResult = Tuple.Create(true, Result.RUN);
return Tuple.Create(true, Result.RUN);
}
ExecuteResult = Tuple.Create(false, Result.RUN);
return Tuple.Create(false, Result.RUN);
}
public Tuple Wait(T id, IRoutine rt)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (state == STATE.IDLE)
{
rt.Start();
state = STATE.WAIT;
}
Result ret = rt.Monitor();
return Tuple.Create(true, ret);
}
return Tuple.Create(false, Result.RUN);
}
//Monitor
public Tuple Monitor(T id, Func func, Func check, double time)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
bool bCheck = false;
if (bActive)
{
if (state == STATE.IDLE)
{
if ((func != null) && !func())
{
return Tuple.Create(true, Result.FAIL);
}
timer.Start(time);
state = STATE.WAIT;
}
bCheck = check();
if (!bCheck)
{
return Tuple.Create(true, Result.FAIL); //Termianate
}
if (timer.IsTimeout())
{
next();
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
//Delay
public Tuple Delay(T id, Func func, double time)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
//if (_currentTokenId != idx && !ExecuteResult.Item1) return ExecuteResult;
if (state == STATE.IDLE)
{
if ((func != null) && !func())
{
ExecuteResult = Tuple.Create(true, Result.FAIL);
return Tuple.Create(true, Result.FAIL);
}
_currentTokenId = idx;
timer.Start(time);
state = STATE.WAIT;
}
if (timer.IsTimeout())
{
next();
}
ExecuteResult = Tuple.Create(true, Result.RUN);
return Tuple.Create(true, Result.RUN);
}
ExecuteResult = Tuple.Create(false, Result.RUN);
return Tuple.Create(false, Result.RUN);
}
//先delay 再运行
public Tuple DelayCheck(T id, Func func, double time)
{
int idx = Convert.ToInt32(id);
bool bActive = Acitve(idx);
if (bActive)
{
if (state == STATE.IDLE)
{
timer.Start(time);
state = STATE.WAIT;
}
if (timer.IsTimeout())
{
if (func != null && !func())
{
return Tuple.Create(true, Result.FAIL);
}
next();
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
#endregion
private Tuple execute(int id, Func func) //顺序执行
{
bool bActive = Acitve(id);
bool bExecute = false;
if (bActive)
{
//if (ExecuteResult.Item1) return Tuple.Create(true, true);
bExecute = func();
if (bExecute)
{
next();
}
}
return Tuple.Create(bActive, bExecute);
}
private Tuple Check(int id, Func func) //check
{
bool bActive = Acitve(id);
bool bExecute = false;
if (bActive)
{
if (ExecuteResult.Item1) return Tuple.Create(true, true);
bExecute = func();
next();
}
return Tuple.Create(bActive, bExecute);
}
///
///
///
///
///
///
/// item1 Active
/// item2 execute
/// item3 Timeout
///
private Tuple wait(int id, Func func, double timeout = int.MaxValue) //Wait condition
{
bool bActive = Acitve(id);
bool bExecute = false;
bool bTimeout = false;
if (bActive)
{
if (state == STATE.IDLE)
{
timer.Start(timeout);
state = STATE.WAIT;
}
bExecute = func();
if (bExecute)
{
next();
}
bTimeout = timer.IsTimeout();
}
return Tuple.Create(bActive, bExecute, bTimeout);
}
private Tuple wait(int id, Func func, double timeout = int.MaxValue) //Wait condition && Check error
{
bool bActive = Acitve(id);
bool? bExecute = false;
bool bTimeout = false;
if (bActive)
{
if (state == STATE.IDLE)
{
timer.Start(timeout);
state = STATE.WAIT;
}
bExecute = func();
if (bExecute.HasValue && bExecute.Value)
{
next();
}
bTimeout = timer.IsTimeout();
}
return Tuple.Create(bActive, bExecute, bTimeout);
}
///
///
///
///
/// item1 true, return item2
///
private Tuple Check(Tuple value)
{
if (value.Item1)
{
if (!value.Item2)
{
ExecuteResult = Tuple.Create(true, Result.FAIL);
return Tuple.Create(true, Result.FAIL);
}
ExecuteResult = Tuple.Create(true, Result.RUN);
return Tuple.Create(true, Result.RUN);
}
ExecuteResult = Tuple.Create(false, Result.RUN);
return Tuple.Create(false, Result.RUN);
}
private Tuple Check(Tuple value)
{
if (value.Item1) // 当前执行
{
if (CheckTimeout(value)) //timeout
{
return Tuple.Create(true, Result.TIMEOUT);
}
return Tuple.Create(true, Result.RUN);
}
return Tuple.Create(false, Result.RUN);
}
private Tuple Check(Tuple value)
{
if (value.Item1) // 当前执行
{
if (value.Item2 == null)
{
return Tuple.Create(true, Result.FAIL);
}
else
{
if (value.Item2 == false && value.Item3 == true) //timeout
{
return Tuple.Create(true, Result.TIMEOUT);
}
return Tuple.Create(true, Result.RUN);
}
}
return Tuple.Create(false, Result.RUN);
}
private bool CheckTimeout(Tuple value)
{
return value.Item1 == true && value.Item2 == false && value.Item3 == true;
}
private bool Acitve(int id) //
{
if (_steps.Contains(id))
return false;
this._id = id;
return true;
}
private void next()
{
_steps.Push(this._id);
state = STATE.IDLE;
}
private void next(int step) //loop
{
while(_steps.Pop() != step);
state = STATE.IDLE;
}
public void Delay(int id, double delaySeconds)
{
Tuple ret = Delay(id, () =>
{
return true;
}, delaySeconds * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.RUN)
{
}
}
}
public bool IsActived(int id)
{
return _steps.Contains(id);
}
}
}