diff --git a/Assets/TEngine/Scripts/Runtime/Core/Base/GameTickWatcher.meta b/Assets/TEngine/Scripts/Runtime/Core/Base/Time.meta similarity index 100% rename from Assets/TEngine/Scripts/Runtime/Core/Base/GameTickWatcher.meta rename to Assets/TEngine/Scripts/Runtime/Core/Base/Time.meta diff --git a/Assets/TEngine/Scripts/Runtime/Core/Base/GameTickWatcher/GameTickWatcher.cs b/Assets/TEngine/Scripts/Runtime/Core/Base/Time/GameTickWatcher.cs similarity index 100% rename from Assets/TEngine/Scripts/Runtime/Core/Base/GameTickWatcher/GameTickWatcher.cs rename to Assets/TEngine/Scripts/Runtime/Core/Base/Time/GameTickWatcher.cs diff --git a/Assets/TEngine/Scripts/Runtime/Core/Base/GameTickWatcher/GameTickWatcher.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/Base/Time/GameTickWatcher.cs.meta similarity index 100% rename from Assets/TEngine/Scripts/Runtime/Core/Base/GameTickWatcher/GameTickWatcher.cs.meta rename to Assets/TEngine/Scripts/Runtime/Core/Base/Time/GameTickWatcher.cs.meta diff --git a/Assets/TEngine/Scripts/Runtime/Core/Base/Time/TickMgr.cs b/Assets/TEngine/Scripts/Runtime/Core/Base/Time/TickMgr.cs new file mode 100644 index 00000000..fc7b00a1 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/Base/Time/TickMgr.cs @@ -0,0 +1,466 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace TEngine.Runtime +{ + public class TimerMgr : BehaviourSingleton + { + public delegate void TimerHandler(object[] args); + + public class Timer + { + public int timerId = 0; + public float curTime = 0; + public float time = 0; + public TimerHandler handler; + public bool isLoop = false; + public bool isNeedRemove = false; + public bool isRunning = false; + public bool isUnscaled = false; //是否使用非缩放的时间 + public object[] args = null; //回调参数 + } + + private int _curTimerId = 0; + private List _timerList = new List(); + private List _unscaledTimerList = new List(); + private List _cacheRemoveTimers = new List(); + private List _cacheRemoveUnscaledTimers = new List(); + + /// + /// 添加计时器 + /// + /// + /// + /// + /// + /// + /// + public int AddTimer(TimerHandler callback, float time, bool isLoop = false, bool isUnscaled = false, + params object[] args) + { + Timer timer = new Timer(); + timer.timerId = ++_curTimerId; + timer.curTime = time; + timer.time = time; + timer.handler = callback; + timer.isLoop = isLoop; + timer.isUnscaled = isUnscaled; + timer.args = args; + timer.isNeedRemove = false; + timer.isRunning = true; + + InsertTimer(timer); + return timer.timerId; + } + + private void InsertTimer(Timer timer) + { + bool isInsert = false; + if (timer.isUnscaled) + { + for (int i = 0, len = _unscaledTimerList.Count; i < len; i++) + { + if (_unscaledTimerList[i].curTime > timer.curTime) + { + _unscaledTimerList.Insert(i, timer); + isInsert = true; + break; + } + } + + if (!isInsert) + { + _unscaledTimerList.Add(timer); + } + } + else + { + for (int i = 0, len = _timerList.Count; i < len; i++) + { + if (_timerList[i].curTime > timer.curTime) + { + _timerList.Insert(i, timer); + isInsert = true; + break; + } + } + + if (!isInsert) + { + _timerList.Add(timer); + } + } + } + + /// + /// 暂停计时 + /// + public void Stop(int timerId) + { + Timer timer = GetTimer(timerId); + if (timer != null) timer.isRunning = false; + } + + /// + /// 恢复计时 + /// + public void Resume(int timerId) + { + Timer timer = GetTimer(timerId); + if (timer != null) timer.isRunning = true; + } + + /// + /// 计时器是否在运行中 + /// + public bool IsRunning(int timerId) + { + Timer timer = GetTimer(timerId); + return timer != null && timer.isRunning; + } + + /// + /// 获得计时器剩余时间 + /// + public float GetLeftTime(int timerId) + { + Timer timer = GetTimer(timerId); + if (timer == null) return 0; + return timer.curTime; + } + + /// + /// 重置计时器,恢复到开始状态 + /// + public void Restart(int timerId) + { + Timer timer = GetTimer(timerId); + if (timer != null) + { + timer.curTime = timer.time; + timer.isRunning = true; + } + } + + /// + /// 重置计时器 + /// + public void Reset(int timerId, TimerHandler callback, float time, bool isLoop = false, bool isUnscaled = false) + { + Timer timer = GetTimer(timerId); + if (timer != null) + { + timer.curTime = time; + timer.time = time; + timer.handler = callback; + timer.isLoop = isLoop; + timer.isNeedRemove = false; + if (timer.isUnscaled != isUnscaled) + { + RemoveTimerImmediate(timerId); + + timer.isUnscaled = isUnscaled; + InsertTimer(timer); + } + } + } + + /// + /// 重置计时器 + /// + public void Reset(int timerId, float time, bool isLoop, bool isUnscaled) + { + Timer timer = GetTimer(timerId); + if (timer != null) + { + timer.curTime = time; + timer.time = time; + timer.isLoop = isLoop; + timer.isNeedRemove = false; + if (timer.isUnscaled != isUnscaled) + { + RemoveTimerImmediate(timerId); + + timer.isUnscaled = isUnscaled; + InsertTimer(timer); + } + } + } + + /// + /// 立即移除 + /// + /// + private void RemoveTimerImmediate(int timerId) + { + for (int i = 0, len = _timerList.Count; i < len; i++) + { + if (_timerList[i].timerId == timerId) + { + _timerList.RemoveAt(i); + return; + } + } + + for (int i = 0, len = _unscaledTimerList.Count; i < len; i++) + { + if (_unscaledTimerList[i].timerId == timerId) + { + _unscaledTimerList.RemoveAt(i); + return; + } + } + } + + /// + /// 移除计时器 + /// + /// + public void RemoveTimer(int timerId) + { + for (int i = 0, len = _timerList.Count; i < len; i++) + { + if (_timerList[i].timerId == timerId) + { + _timerList[i].isNeedRemove = true; + return; + } + } + + for (int i = 0, len = _unscaledTimerList.Count; i < len; i++) + { + if (_unscaledTimerList[i].timerId == timerId) + { + _unscaledTimerList[i].isNeedRemove = true; + return; + } + } + } + + /// + /// 移除所有计时器 + /// + public void RemoveAllTimer() + { + _timerList.Clear(); + _unscaledTimerList.Clear(); + } + + /// + /// 根据TimerId获取计时器 + /// + /// + /// + private Timer GetTimer(int timerId) + { + for (int i = 0, len = _timerList.Count; i < len; i++) + { + if (_timerList[i].timerId == timerId) + { + return _timerList[i]; + } + } + + for (int i = 0, len = _unscaledTimerList.Count; i < len; i++) + { + if (_unscaledTimerList[i].timerId == timerId) + { + return _unscaledTimerList[i]; + } + } + + return null; + } + + private void LoopCallInBadFrame() + { + bool isLoopCall = false; + for (int i = 0, len = _timerList.Count; i < len; i++) + { + Timer timer = _timerList[i]; + if (timer.isLoop && timer.curTime <= 0) + { + if (timer.handler != null) + { + timer.handler(timer.args); + } + + timer.curTime += timer.time; + if (timer.curTime <= 0) + { + isLoopCall = true; + } + } + } + + if (isLoopCall) + { + LoopCallInBadFrame(); + } + } + + private void LoopCallUnscaledInBadFrame() + { + bool isLoopCall = false; + for (int i = 0, len = _unscaledTimerList.Count; i < len; i++) + { + Timer timer = _unscaledTimerList[i]; + if (timer.isLoop && timer.curTime <= 0) + { + if (timer.handler != null) + { + timer.handler(timer.args); + } + + timer.curTime += timer.time; + if (timer.curTime <= 0) + { + isLoopCall = true; + } + } + } + + if (isLoopCall) + { + LoopCallUnscaledInBadFrame(); + } + } + + private void UpdateTimer() + { + bool isLoopCall = false; + for (int i = 0, len = _timerList.Count; i < len; i++) + { + Timer timer = _timerList[i]; + if (timer.isNeedRemove) + { + _cacheRemoveTimers.Add(i); + continue; + } + + if (!timer.isRunning) continue; + timer.curTime -= Time.deltaTime; + if (timer.curTime <= 0) + { + if (timer.handler != null) + { + timer.handler(timer.args); + } + + if (timer.isLoop) + { + timer.curTime += timer.time; + if (timer.curTime <= 0) + { + isLoopCall = true; + } + } + else + { + _cacheRemoveTimers.Add(i); + } + } + } + + for (int i = _cacheRemoveTimers.Count - 1; i >= 0; i--) + { + _timerList.RemoveAt(_cacheRemoveTimers[i]); + _cacheRemoveTimers.RemoveAt(i); + } + + if (isLoopCall) + { + LoopCallInBadFrame(); + } + } + + + private void UpdateUnscaledTimer() + { + bool isLoopCall = false; + for (int i = 0, len = _unscaledTimerList.Count; i < len; i++) + { + Timer timer = _unscaledTimerList[i]; + if (timer.isNeedRemove) + { + _cacheRemoveUnscaledTimers.Add(i); + continue; + } + + if (!timer.isRunning) continue; + timer.curTime -= Time.unscaledDeltaTime; + if (timer.curTime <= 0) + { + if (timer.handler != null) + { + timer.handler(timer.args); + } + + if (timer.isLoop) + { + timer.curTime += timer.time; + if (timer.curTime <= 0) + { + isLoopCall = true; + } + } + else + { + _cacheRemoveUnscaledTimers.Add(i); + } + } + } + + for (int i = _cacheRemoveUnscaledTimers.Count - 1; i >= 0; i--) + { + _unscaledTimerList.RemoveAt(_cacheRemoveUnscaledTimers[i]); + _cacheRemoveUnscaledTimers.RemoveAt(i); + } + + if (isLoopCall) + { + LoopCallUnscaledInBadFrame(); + } + } + + public override void Update() + { + UpdateTimer(); + UpdateUnscaledTimer(); + } + + private List _ticker = new List(); + + public System.Timers.Timer AddSystemTimer(Action callBack) + { + var timerTick = new System.Timers.Timer(); + int interval = 1000; + timerTick = new System.Timers.Timer(interval); + timerTick.AutoReset = true; + timerTick.Enabled = true; + timerTick.Elapsed += new System.Timers.ElapsedEventHandler(callBack); + + _ticker.Add(timerTick); + + return timerTick; + } + + public override void Destroy() + { + DestroySystemTimer(); + base.Destroy(); + } + + private void DestroySystemTimer() + { + for (int i = 0; i < _ticker.Count; i++) + { + if (_ticker[i] != null) + { + _ticker[i].Stop(); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/Base/Time/TickMgr.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/Base/Time/TickMgr.cs.meta new file mode 100644 index 00000000..6f937e1c --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/Base/Time/TickMgr.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3dcdeab46de84504f9aa9448c67fec82 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: