DeviceTimer

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);
        }
    }

  

 public enum RoutineState
    {
        Running,
        Failed,
        Timeout,
        Finished
    }

  

public class RoutineResult
    {
        public RoutineState Result;

        public string ErrorMessage;
    }

  

public class RoutineBreakException : ApplicationException
    {
        public RoutineBreakException()
        {
        }

        public RoutineBreakException(string message)
            : base(message)
        {
        }
    }

  

 public interface IRoutine
    {
        Result Start(params object[] objs);

        Result Monitor();

        void Abort();
    }

  

 public enum Result
    {
        RUN,
        DONE,
        FAIL,
        TIMEOUT,
        VERIFYFAIL,
        PAUSE,
        SUCCEED
    }

  

 

比较难理解的代码  我要记录下  每天想想。

posted on 2023-03-30 14:17  tom_xsb  阅读(17)  评论(0编辑  收藏  举报

导航