123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- using System;
- using XGame.Framework.Interfaces;
- namespace XGame.Framework.Time
- {
- public class Timer : ITimer, IReset
- {
- public enum TimerRunState : sbyte
- {
- None,
- Running,
- Paused,
- Stoped,
- Finished,
- Exception,
- }
- private int _delay;
- /// <summary>
- /// 间隔
- /// </summary>
- private int _interval;
- /// <summary>
- /// 时间轴
- /// </summary>
- private int _timeAxis;
- /// <summary>
- /// 循环次数上限
- /// </summary>
- private int _loopTimes;
- private Action _action;
- private Action<int> _actionLoop;
- public ITimeListener<ITimer> Listener { get; set; }
- public float TimeScale { get; set; } = 1;
- private int _passTimes;
- private TimerRunState _runState;
- public TimerRunState State
- {
- get => _runState;
- private set
- {
- _runState = value;
- if (value is TimerRunState.Stoped or TimerRunState.Finished or TimerRunState.Exception)
- {
- try
- {
- Listener?.OnCompleted(this);
- }
- catch (Exception ex)
- {
- Log.Exception($"定时器事件监听执行异常.", ex);
- }
- Listener = null;
- }
- }
- }
- internal Timer(int delay, int interval, int looptimes, Action action)
- {
- #if UNITY_EDITOR
- UnityEngine.Assertions.Assert.IsTrue(delay >= 0, "延迟不能<0");
- UnityEngine.Assertions.Assert.IsTrue(!(delay == 0 && looptimes == 1), "立即执行的延迟定时器次数不能小于2");
- UnityEngine.Assertions.Assert.IsTrue(interval > 0, "定时器间隔不能<=0");
- UnityEngine.Assertions.Assert.IsTrue(looptimes != 0, "定时器执行次数不能为0,如果要无限循环请设置为-1");
- UnityEngine.Assertions.Assert.IsNotNull(action, "定时器回调不能为null");
- #endif
- _action = action;
- InnerInit(delay, interval, looptimes);
- }
- internal Timer(int delay, int interval, int looptimes, Action<int> action)
- {
- #if UNITY_EDITOR
- UnityEngine.Assertions.Assert.IsTrue(delay >= 0, "延迟不能<0");
- UnityEngine.Assertions.Assert.IsTrue(!(delay == 0 && looptimes == 1), "立即执行的延迟定时器次数不能小于2");
- UnityEngine.Assertions.Assert.IsTrue(interval > 0, "定时器间隔不能<=0");
- UnityEngine.Assertions.Assert.IsTrue(looptimes != 0, "定时器执行次数不能为0,如果要无限循环请设置为-1");
- UnityEngine.Assertions.Assert.IsNotNull(action, "定时器回调不能为null");
- #endif
- _actionLoop = action;
- InnerInit(delay, interval, looptimes);
- }
- private void InnerInit(int delay, int interval, int looptimes)
- {
- _delay = delay;
- _interval = interval;
- _loopTimes = looptimes;
- _passTimes = 0;
- State = TimerRunState.Running;
- }
- //校准时间
- private float addingValue = 0;
- private int CorrectTime(int deltaTime)
- {
- float updateTime = (float)deltaTime * TimeScale;
- int elapse = (int)updateTime;
- float timeDecimals = updateTime - elapse;
- addingValue += timeDecimals;
- if (addingValue >= 1.0f)
- {
- elapse += 1;
- addingValue -= 1.0f;
- }
- return elapse;
- }
- internal bool Update(int deltaTime)
- {
- switch (State)
- {
- case TimerRunState.Stoped:
- case TimerRunState.Finished:
- case TimerRunState.Exception:
- return true;
- case TimerRunState.Paused:
- return false;
- }
- int correctedTime = CorrectTime(deltaTime);
- _timeAxis += correctedTime;
- var interval = _passTimes == 0 ? _delay : _interval;
- if (_timeAxis > interval)
- {
- _timeAxis -= interval;
- _passTimes += 1;
- try
- {
- _action?.Invoke();
- _actionLoop?.Invoke(_passTimes);
- }
- catch (Exception e)
- {
- State = TimerRunState.Exception;
- Log.Exception($"定时器回调执行发生异常({_passTimes}/{_loopTimes})", e);
- //throw new Exception($"定时器回调执行发生异常({_passTimes}/{_loopTimes}):{e}");
- }
- if (_passTimes == _loopTimes)
- {
- State = TimerRunState.Finished;
- return true;
- }
- }
- return false;
- }
- public void Cancel()
- {
- State = TimerRunState.Stoped;
- _action = null;
- _actionLoop = null;
- }
- public void Pause()
- {
- if (State == TimerRunState.Running)
- State = TimerRunState.Paused;
- }
- public void Resume()
- {
- if (State == TimerRunState.Paused)
- State = TimerRunState.Running;
- }
- public void Dispose()
- {
- _action = null;
- _actionLoop = null;
- Listener = null;
- }
- /// <summary>
- /// 只对Running状态的定时器有效
- /// </summary>
- void IReset.Reset()
- {
- if (State != TimerRunState.Running)
- {
- return;
- }
- _timeAxis = 0;
- _passTimes = 0;
- }
- public int TimeAxis => _timeAxis;
- /// <summary>
- /// 只对Running状态的定时器有效
- /// </summary>
- /// <param name="delay"></param>
- public void ResetForAxis(int timeAsis)
- {
- if (State != TimerRunState.Running)
- {
- return;
- }
- _timeAxis = timeAsis;
- _passTimes = 0;
- }
- }
- }
|