public class DeviceTimer
{
private enum DeviceTimerState
{
TM_ST_IDLE,
TM_ST_BUSY,
TM_ST_TIMEOUT
}
private DeviceTimerState _state;
private long _startTime;
private long _timeOut;
private double _freq;
private double _duration;
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);
public DeviceTimer()
{
if (!QueryPerformanceFrequency(out var lpFrequency))
{
throw new Exception("本计算机不支持高性能计数器");
}
_freq = (double)lpFrequency / 1000.0;
SetState(DeviceTimerState.TM_ST_IDLE);
QueryPerformanceCounter(out _startTime);
_timeOut = _startTime;
_duration = 0.0;
}
private void SetState(DeviceTimerState state)
{
_state = state;
}
private DeviceTimerState GetState()
{
return _state;
}
public double GetElapseTime()
{
QueryPerformanceCounter(out var lpPerformanceCount);
return (double)(lpPerformanceCount - _startTime) / _freq;
}
public double GetTotalTime()
{
return _duration;
}
public void Stop()
{
SetState(DeviceTimerState.TM_ST_IDLE);
QueryPerformanceCounter(out _startTime);
_timeOut = _startTime;
_duration = 0.0;
}
public void Start(double delay_ms)
{
QueryPerformanceCounter(out _startTime);
_timeOut = Convert.ToInt64((double)_startTime + delay_ms * _freq);
SetState(DeviceTimerState.TM_ST_BUSY);
_duration = delay_ms;
}
public void Restart(double delay_ms)
{
_timeOut = Convert.ToInt64((double)_startTime + delay_ms * _freq);
SetState(DeviceTimerState.TM_ST_BUSY);
_duration = delay_ms;
}
public bool IsTimeout()
{
_ = _state;
QueryPerformanceCounter(out var lpPerformanceCount);
if (_state == DeviceTimerState.TM_ST_BUSY && lpPerformanceCount >= _timeOut)
{
SetState(DeviceTimerState.TM_ST_TIMEOUT);
return true;
}
if (_state == DeviceTimerState.TM_ST_TIMEOUT)
{
return true;
}
return false;
}
public bool IsIdle()
{
return _state == DeviceTimerState.TM_ST_IDLE;
}
}
}
public class SeqenecRoutine
{
private enum STATE
{
IDLE,
WAIT
}
protected DeviceTimer counter = new DeviceTimer();
protected DeviceTimer delayTimer = new DeviceTimer();
private int _id;
private Stack<int> _steps = new Stack<int>();
private STATE state;
private int loop;
private int loopCount;
private int loopID;
private DeviceTimer timer = new DeviceTimer();
protected RoutineResult RoutineToken = new RoutineResult
{
Result = RoutineState.Running
};
public int TokenId => _id;
public int LoopCounter => loop;
public int LoopTotalTime => loopCount;
public int Elapsed => (int)(timer.GetElapseTime() / 1000.0);
public void Reset()
{
_id = 0;
_steps.Clear();
loop = 0;
loopCount = 0;
state = STATE.IDLE;
counter.Start(360000.0);
RoutineToken.Result = RoutineState.Running;
}
protected void PerformRoutineStep(int id, Func<RoutineState> execution, RoutineResult result)
{
if (Acitve(id))
{
result.Result = execution();
}
}
public void StopLoop()
{
loop = loopCount;
}
public Tuple<bool, Result> Loop<T>(T id, Func<bool> func, int count)
{
int id2 = Convert.ToInt32(id);
bool flag = Acitve(id2);
if (flag)
{
if (!func())
{
return Tuple.Create(flag, Result.FAIL);
}
loopID = id2;
loopCount = count;
next();
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
public Tuple<bool, Result> EndLoop<T>(T id, Func<bool> func)
{
int id2 = Convert.ToInt32(id);
bool flag = Acitve(id2);
if (flag)
{
if (++loop >= loopCount)
{
if (!func())
{
return Tuple.Create(flag, Result.FAIL);
}
loop = 0;
loopCount = 0;
next();
return Tuple.Create(item1: true, Result.RUN);
}
next(loopID);
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
public Tuple<bool, Result> ExecuteAndWait<T>(T id, IRoutine routine)
{
int id2 = Convert.ToInt32(id);
if (Acitve(id2))
{
if (state == STATE.IDLE)
{
switch (routine.Start())
{
case Result.FAIL:
return Tuple.Create(item1: true, Result.FAIL);
case Result.DONE:
next();
return Tuple.Create(item1: true, Result.DONE);
}
state = STATE.WAIT;
}
switch (routine.Monitor())
{
case Result.DONE:
next();
return Tuple.Create(item1: true, Result.DONE);
case Result.FAIL:
case Result.TIMEOUT:
return Tuple.Create(item1: true, Result.FAIL);
default:
return Tuple.Create(item1: true, Result.RUN);
}
}
return Tuple.Create(item1: false, Result.RUN);
}
public Tuple<bool, Result> ExecuteAndWait<T>(T id, List<IRoutine> routines)
{
int id2 = Convert.ToInt32(id);
if (Acitve(id2))
{
if (state == STATE.IDLE)
{
foreach (IRoutine routine in routines)
{
if (routine.Start() == Result.FAIL)
{
return Tuple.Create(item1: true, Result.FAIL);
}
}
state = STATE.WAIT;
}
bool flag = false;
bool flag2 = true;
foreach (IRoutine routine2 in routines)
{
Result result = routine2.Monitor();
flag2 = flag2 && (result == Result.FAIL || result == Result.DONE);
flag = flag || result == Result.FAIL;
}
if (flag2)
{
next();
if (flag)
{
return Tuple.Create(item1: true, Result.FAIL);
}
return Tuple.Create(item1: true, Result.DONE);
}
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
public Tuple<bool, Result> Check<T>(T id, Func<bool> func)
{
return Check(Check(Convert.ToInt32(id), func));
}
public Tuple<bool, Result> Execute<T>(T id, Func<bool> func)
{
return Check(execute(Convert.ToInt32(id), func));
}
public Tuple<bool, Result> Wait<T>(T id, Func<bool> func, double timeout = 2147483647.0)
{
return Check(wait(Convert.ToInt32(id), func, timeout));
}
public Tuple<bool, Result> Wait<T>(T id, Func<bool?> func, double timeout = 2147483647.0)
{
return Check(wait(Convert.ToInt32(id), func, timeout));
}
public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, double timeout = 2147483647.0)
{
int id2 = Convert.ToInt32(id);
bool flag = Acitve(id2);
bool? flag2 = false;
if (flag)
{
if (state == STATE.IDLE)
{
if (!execute())
{
return Tuple.Create(flag, Result.FAIL);
}
timer.Start(timeout);
state = STATE.WAIT;
}
flag2 = check();
if (!flag2.HasValue)
{
return Tuple.Create(flag, Result.FAIL);
}
if (flag2.Value)
{
next();
return Tuple.Create(item1: true, Result.RUN);
}
if (timer.IsTimeout())
{
return Tuple.Create(item1: true, Result.TIMEOUT);
}
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, Func<double> time)
{
int id2 = Convert.ToInt32(id);
bool num = Acitve(id2);
bool? flag = false;
double num2 = 0.0;
if (num)
{
if (state == STATE.IDLE)
{
num2 = time();
if (!execute())
{
return Tuple.Create(item1: true, Result.FAIL);
}
timer.Start(num2);
state = STATE.WAIT;
}
flag = check();
if (!flag.HasValue)
{
return Tuple.Create(item1: true, Result.FAIL);
}
if (flag.Value)
{
next();
return Tuple.Create(item1: true, Result.RUN);
}
if (timer.IsTimeout())
{
return Tuple.Create(item1: true, Result.TIMEOUT);
}
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
public Tuple<bool, Result> Wait<T>(T id, IRoutine rt)
{
int id2 = Convert.ToInt32(id);
if (Acitve(id2))
{
if (state == STATE.IDLE)
{
rt.Start();
state = STATE.WAIT;
}
Result item = rt.Monitor();
return Tuple.Create(item1: true, item);
}
return Tuple.Create(item1: false, Result.RUN);
}
public Tuple<bool, Result> Monitor<T>(T id, Func<bool> func, Func<bool> check, double time)
{
int id2 = Convert.ToInt32(id);
if (Acitve(id2))
{
if (state == STATE.IDLE)
{
if (func != null && !func())
{
return Tuple.Create(item1: true, Result.FAIL);
}
timer.Start(time);
state = STATE.WAIT;
}
if (!check())
{
return Tuple.Create(item1: true, Result.FAIL);
}
if (timer.IsTimeout())
{
next();
}
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
public Tuple<bool, Result> Delay<T>(T id, Func<bool> func, double time)
{
int id2 = Convert.ToInt32(id);
if (Acitve(id2))
{
if (state == STATE.IDLE)
{
if (func != null && !func())
{
return Tuple.Create(item1: true, Result.FAIL);
}
timer.Start(time);
state = STATE.WAIT;
}
if (timer.IsTimeout())
{
next();
}
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
public Tuple<bool, Result> DelayCheck<T>(T id, Func<bool> func, double time)
{
int id2 = Convert.ToInt32(id);
if (Acitve(id2))
{
if (state == STATE.IDLE)
{
timer.Start(time);
state = STATE.WAIT;
}
if (timer.IsTimeout())
{
if (func != null && !func())
{
return Tuple.Create(item1: true, Result.FAIL);
}
next();
}
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
private Tuple<bool, bool> execute(int id, Func<bool> func)
{
bool num = Acitve(id);
bool flag = false;
if (num)
{
flag = func();
if (flag)
{
next();
}
}
return Tuple.Create(num, flag);
}
private Tuple<bool, bool> Check(int id, Func<bool> func)
{
bool num = Acitve(id);
bool item = false;
if (num)
{
item = func();
next();
}
return Tuple.Create(num, item);
}
private Tuple<bool, bool, bool> wait(int id, Func<bool> func, double timeout = 2147483647.0)
{
bool num = Acitve(id);
bool flag = false;
bool item = false;
if (num)
{
if (state == STATE.IDLE)
{
timer.Start(timeout);
state = STATE.WAIT;
}
flag = func();
if (flag)
{
next();
}
item = timer.IsTimeout();
}
return Tuple.Create(num, flag, item);
}
private Tuple<bool, bool?, bool> wait(int id, Func<bool?> func, double timeout = 2147483647.0)
{
bool num = Acitve(id);
bool? item = false;
bool item2 = false;
if (num)
{
if (state == STATE.IDLE)
{
timer.Start(timeout);
state = STATE.WAIT;
}
item = func();
if (item.HasValue && item.Value)
{
next();
}
item2 = timer.IsTimeout();
}
return Tuple.Create(num, item, item2);
}
private Tuple<bool, Result> Check(Tuple<bool, bool> value)
{
if (value.Item1)
{
if (!value.Item2)
{
return Tuple.Create(item1: true, Result.FAIL);
}
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
private Tuple<bool, Result> Check(Tuple<bool, bool, bool> value)
{
if (value.Item1)
{
if (CheckTimeout(value))
{
return Tuple.Create(item1: true, Result.TIMEOUT);
}
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
private Tuple<bool, Result> Check(Tuple<bool, bool?, bool> value)
{
if (value.Item1)
{
if (!value.Item2.HasValue)
{
return Tuple.Create(item1: true, Result.FAIL);
}
if (value.Item2 == false && value.Item3)
{
return Tuple.Create(item1: true, Result.TIMEOUT);
}
return Tuple.Create(item1: true, Result.RUN);
}
return Tuple.Create(item1: false, Result.RUN);
}
private bool CheckTimeout(Tuple<bool, bool, bool> value)
{
if (value.Item1 && !value.Item2)
{
return value.Item3;
}
return false;
}
private bool Acitve(int id)
{
if (_steps.Contains(id))
{
return false;
}
_id = id;
return true;
}
private void next()
{
_steps.Push(_id);
state = STATE.IDLE;
}
private void next(int step)
{
while (_steps.Pop() != step)
{
}
state = STATE.IDLE;
}
public void Delay(int id, double delaySeconds)
{
Tuple<bool, Result> tuple = Delay(id, () => true, delaySeconds * 1000.0);
if (tuple.Item1 && tuple.Item2 == Result.RUN)
{
throw new RoutineBreakException();
}
}
public bool IsActived(int id)
{
return _steps.Contains(id);
}
}
比较难理解的代码 我要记录下 每天想想。