diff --git a/Assets/GameScripts/HotFix/GameLogic/UI/Common/UIExtension.cs b/Assets/GameScripts/HotFix/GameLogic/UI/Common/UIExtension.cs
index 18065b6b..d5cd9960 100644
--- a/Assets/GameScripts/HotFix/GameLogic/UI/Common/UIExtension.cs
+++ b/Assets/GameScripts/HotFix/GameLogic/UI/Common/UIExtension.cs
@@ -4,15 +4,6 @@ using UnityEngine;
using UnityEngine.UI;
using TEngine;
-public enum EUIGroup
-{
- Root,
- UI,
- Dialog,
- Tips,
- System
-}
-
public static class UIExtension
{
#region SetActive
diff --git a/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs b/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs
index 7833c06a..ddad7a37 100644
--- a/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs
+++ b/Assets/TEngine/Runtime/GameFramework/GameFrameworkEntry.cs
@@ -47,22 +47,18 @@ namespace TEngine
/// 如果要获取的游戏框架模块不存在,则自动创建该游戏框架模块。
public static T GetModule() where T : class
{
- Type interfaceType = typeof(T);
- if (!interfaceType.IsInterface)
+ Type module = typeof(T);
+
+ if (module.FullName != null && !module.FullName.StartsWith("TEngine.", StringComparison.Ordinal))
{
- throw new GameFrameworkException(Utility.Text.Format("You must get module by interface, but '{0}' is not.", interfaceType.FullName));
+ throw new GameFrameworkException(Utility.Text.Format("You must get a Game Framework module, but '{0}' is not.", module.FullName));
}
- if (!interfaceType.FullName.StartsWith("TEngine.", StringComparison.Ordinal))
- {
- throw new GameFrameworkException(Utility.Text.Format("You must get a Game Framework module, but '{0}' is not.", interfaceType.FullName));
- }
-
- string moduleName = Utility.Text.Format("{0}.{1}", interfaceType.Namespace, interfaceType.Name.Substring(1));
+ string moduleName = Utility.Text.Format("{0}.{1}", module.Namespace, module.Name.Substring(1));
Type moduleType = Type.GetType(moduleName);
if (moduleType == null)
{
- moduleName = Utility.Text.Format("{0}.{1}", interfaceType.Namespace, interfaceType.Name);
+ moduleName = Utility.Text.Format("{0}.{1}", module.Namespace, module.Name);
moduleType = Type.GetType(moduleName);
if (moduleType == null)
{
diff --git a/Assets/TEngine/Runtime/GameFramework/Timer.meta b/Assets/TEngine/Runtime/GameFramework/Timer.meta
new file mode 100644
index 00000000..82a8c33e
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Timer.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 555d657d6bb444a983750fb61876af89
+timeCreated: 1681822247
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Timer/Timer.meta b/Assets/TEngine/Runtime/GameFramework/Timer/Timer.meta
new file mode 100644
index 00000000..1ec86396
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Timer/Timer.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 9d644fbcf0a6413da6f4d0c54724266a
+timeCreated: 1681822257
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Timer/Timer/TimerManager.cs b/Assets/TEngine/Runtime/GameFramework/Timer/Timer/TimerManager.cs
new file mode 100644
index 00000000..083c7318
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Timer/Timer/TimerManager.cs
@@ -0,0 +1,465 @@
+using System;
+using System.Collections.Generic;
+
+namespace TEngine
+{
+ public delegate void TimerHandler(object[] args);
+
+ internal class TimerManager : GameFrameworkModule
+ {
+ [Serializable]
+ 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 readonly List _timerList = new List();
+ private readonly List _unscaledTimerList = new List();
+ private readonly List _cacheRemoveTimers = new List();
+ private readonly List _cacheRemoveUnscaledTimers = new List();
+
+ ///
+ /// 添加计时器
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public int AddTimer(TimerHandler callback, float time, bool isLoop = false, bool isUnscaled = false, params object[] args)
+ {
+ Timer timer = new Timer
+ {
+ timerId = ++_curTimerId,
+ curTime = time,
+ time = time,
+ Handler = callback,
+ isLoop = isLoop,
+ isUnscaled = isUnscaled,
+ Args = args,
+ isNeedRemove = false,
+ 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 is { isRunning: true };
+ }
+
+ ///
+ /// 获得计时器剩余时间
+ ///
+ 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(float elapseSeconds)
+ {
+ 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 -= elapseSeconds;
+ 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(float realElapseSeconds)
+ {
+ 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 -= realElapseSeconds;
+ 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();
+ }
+ }
+
+ private readonly List _ticker = new List();
+
+ public System.Timers.Timer AddSystemTimer(Action