修复bug
This commit is contained in:
parent
998a2eac0b
commit
0d80bcfa5b
@ -9,8 +9,6 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
int AddTimer(TimerHandler callback, float time, bool isLoop = false, bool isUnscaled = false, params object[] args);
|
int AddTimer(TimerHandler callback, float time, bool isLoop = false, bool isUnscaled = false, params object[] args);
|
||||||
int AddTimer(TimerHandlerNoArgs callback, float time, bool isLoop = false, bool isUnscaled = false);
|
int AddTimer(TimerHandlerNoArgs callback, float time, bool isLoop = false, bool isUnscaled = false);
|
||||||
|
|
||||||
// 优化1: 使用值类型泛型参数,完全零GC
|
|
||||||
int AddTimer<T>(Action<T> callback, T arg, float time, bool isLoop = false, bool isUnscaled = false);
|
int AddTimer<T>(Action<T> callback, T arg, float time, bool isLoop = false, bool isUnscaled = false);
|
||||||
void Stop(int timerId);
|
void Stop(int timerId);
|
||||||
void Resume(int timerId);
|
void Resume(int timerId);
|
||||||
|
|||||||
@ -7,11 +7,8 @@ using UnityEngine;
|
|||||||
namespace AlicizaX
|
namespace AlicizaX
|
||||||
{
|
{
|
||||||
public delegate void TimerHandler(params object[] args);
|
public delegate void TimerHandler(params object[] args);
|
||||||
|
|
||||||
public delegate void TimerHandlerNoArgs();
|
public delegate void TimerHandlerNoArgs();
|
||||||
|
|
||||||
|
|
||||||
// 优化2: 使用union结构存储不同类型的回调(零装箱)
|
|
||||||
[Il2CppSetOption(Option.NullChecks, false)]
|
[Il2CppSetOption(Option.NullChecks, false)]
|
||||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||||
@ -21,20 +18,21 @@ namespace AlicizaX
|
|||||||
public float TriggerTime;
|
public float TriggerTime;
|
||||||
public float Interval;
|
public float Interval;
|
||||||
|
|
||||||
// 优化3: 使用字段而非object存储,避免装箱
|
|
||||||
public TimerHandler Handler;
|
public TimerHandler Handler;
|
||||||
public TimerHandlerNoArgs HandlerNoArgs;
|
public TimerHandlerNoArgs HandlerNoArgs;
|
||||||
public Delegate HandlerGeneric; // 直接存储委托
|
public Delegate HandlerGeneric;
|
||||||
|
|
||||||
public bool IsLoop;
|
public bool IsLoop;
|
||||||
public bool IsRunning;
|
public bool IsRunning;
|
||||||
public bool IsUnscaled;
|
public bool IsUnscaled;
|
||||||
public bool IsActive;
|
public bool IsActive;
|
||||||
public byte HandlerType; // 0=Handler, 1=NoArgs, 2=Generic<struct>, 3=Generic<class>
|
public byte HandlerType; // 0=Handler, 1=NoArgs, 2=Generic
|
||||||
|
|
||||||
public object[] Args;
|
public object[] Args;
|
||||||
public object GenericArg; // 存储泛型参数
|
public object GenericArg;
|
||||||
|
|
||||||
|
// 优化1: 添加层级信息,用于精确定位
|
||||||
|
public int Level; // 当前所在的时间轮层级
|
||||||
public int SlotIndex;
|
public int SlotIndex;
|
||||||
public int NextTimerIndex;
|
public int NextTimerIndex;
|
||||||
public int PrevTimerIndex;
|
public int PrevTimerIndex;
|
||||||
@ -48,6 +46,8 @@ namespace AlicizaX
|
|||||||
Args = null;
|
Args = null;
|
||||||
GenericArg = null;
|
GenericArg = null;
|
||||||
IsActive = false;
|
IsActive = false;
|
||||||
|
Level = -1;
|
||||||
|
SlotIndex = -1;
|
||||||
NextTimerIndex = -1;
|
NextTimerIndex = -1;
|
||||||
PrevTimerIndex = -1;
|
PrevTimerIndex = -1;
|
||||||
}
|
}
|
||||||
@ -68,15 +68,9 @@ namespace AlicizaX
|
|||||||
private int[] _freeIndices;
|
private int[] _freeIndices;
|
||||||
private int _freeCount;
|
private int _freeCount;
|
||||||
|
|
||||||
// 优化4: 静态泛型缓存,避免每次调用时的类型检查
|
// 优化2: 延迟删除队列,避免在遍历时修改链表
|
||||||
private static class GenericInvoker<T>
|
private int[] _pendingRemoveTimers;
|
||||||
{
|
private int _pendingRemoveCount;
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void Invoke(Delegate callback, object arg)
|
|
||||||
{
|
|
||||||
((Action<T>)callback)((T)arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class HierarchicalTimeWheel
|
private class HierarchicalTimeWheel
|
||||||
{
|
{
|
||||||
@ -143,6 +137,8 @@ namespace AlicizaX
|
|||||||
slotIndex = (_levels[2].CurrentSlot + level2Slots) % SLOT_COUNT_LEVEL2;
|
slotIndex = (_levels[2].CurrentSlot + level2Slots) % SLOT_COUNT_LEVEL2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 优化3: 记录层级信息
|
||||||
|
timer.Level = level;
|
||||||
timer.SlotIndex = slotIndex;
|
timer.SlotIndex = slotIndex;
|
||||||
timer.NextTimerIndex = _levels[level].SlotHeads[slotIndex];
|
timer.NextTimerIndex = _levels[level].SlotHeads[slotIndex];
|
||||||
timer.PrevTimerIndex = -1;
|
timer.PrevTimerIndex = -1;
|
||||||
@ -187,21 +183,30 @@ namespace AlicizaX
|
|||||||
wheelLevel.CurrentSlot = (wheelLevel.CurrentSlot + 1) % wheelLevel.SlotCount;
|
wheelLevel.CurrentSlot = (wheelLevel.CurrentSlot + 1) % wheelLevel.SlotCount;
|
||||||
|
|
||||||
int currentHead = wheelLevel.SlotHeads[wheelLevel.CurrentSlot];
|
int currentHead = wheelLevel.SlotHeads[wheelLevel.CurrentSlot];
|
||||||
wheelLevel.SlotHeads[wheelLevel.CurrentSlot] = -1;
|
wheelLevel.SlotHeads[wheelLevel.CurrentSlot] = -1; // 清空槽
|
||||||
|
|
||||||
|
// 优化4: 遍历时先断开链表,避免在回调中修改导致问题
|
||||||
int currentIndex = currentHead;
|
int currentIndex = currentHead;
|
||||||
while (currentIndex != -1)
|
while (currentIndex != -1)
|
||||||
{
|
{
|
||||||
int nextIndex = pool[currentIndex].NextTimerIndex;
|
ref TimerInfo timer = ref pool[currentIndex];
|
||||||
|
int nextIndex = timer.NextTimerIndex;
|
||||||
|
|
||||||
if (pool[currentIndex].IsActive && pool[currentIndex].IsRunning)
|
// 断开链表连接
|
||||||
|
timer.NextTimerIndex = -1;
|
||||||
|
timer.PrevTimerIndex = -1;
|
||||||
|
timer.Level = -1; // 标记为不在时间轮中
|
||||||
|
|
||||||
|
if (timer.IsActive && timer.IsRunning)
|
||||||
{
|
{
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
{
|
{
|
||||||
|
// Level 0 直接触发
|
||||||
processTimer(currentIndex);
|
processTimer(currentIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// 高层级降级到低层级
|
||||||
AddTimer(currentIndex, pool, _currentTime);
|
AddTimer(currentIndex, pool, _currentTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,30 +215,53 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 优化5: 安全的移除方法,检查边界
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void RemoveTimer(int poolIndex, TimerInfo[] pool)
|
public void RemoveTimer(int poolIndex, TimerInfo[] pool)
|
||||||
{
|
{
|
||||||
|
if (poolIndex < 0 || poolIndex >= pool.Length)
|
||||||
|
return;
|
||||||
|
|
||||||
ref TimerInfo timer = ref pool[poolIndex];
|
ref TimerInfo timer = ref pool[poolIndex];
|
||||||
|
|
||||||
|
// 优化6: 如果已经不在时间轮中,直接返回
|
||||||
|
if (timer.Level < 0 || timer.Level >= _levels.Length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int level = timer.Level;
|
||||||
|
int slotIndex = timer.SlotIndex;
|
||||||
|
|
||||||
|
// 边界检查
|
||||||
|
if (slotIndex < 0 || slotIndex >= _levels[level].SlotCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 从链表中移除
|
||||||
if (timer.PrevTimerIndex != -1)
|
if (timer.PrevTimerIndex != -1)
|
||||||
{
|
{
|
||||||
pool[timer.PrevTimerIndex].NextTimerIndex = timer.NextTimerIndex;
|
if (timer.PrevTimerIndex < pool.Length)
|
||||||
|
{
|
||||||
|
pool[timer.PrevTimerIndex].NextTimerIndex = timer.NextTimerIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int level = 0; level < _levels.Length; level++)
|
// 是头节点
|
||||||
{
|
_levels[level].SlotHeads[slotIndex] = timer.NextTimerIndex;
|
||||||
if (_levels[level].SlotHeads[timer.SlotIndex] == poolIndex)
|
|
||||||
{
|
|
||||||
_levels[level].SlotHeads[timer.SlotIndex] = timer.NextTimerIndex;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer.NextTimerIndex != -1)
|
if (timer.NextTimerIndex != -1)
|
||||||
{
|
{
|
||||||
pool[timer.NextTimerIndex].PrevTimerIndex = timer.PrevTimerIndex;
|
if (timer.NextTimerIndex < pool.Length)
|
||||||
|
{
|
||||||
|
pool[timer.NextTimerIndex].PrevTimerIndex = timer.PrevTimerIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清除链表信息
|
||||||
|
timer.Level = -1;
|
||||||
|
timer.SlotIndex = -1;
|
||||||
|
timer.NextTimerIndex = -1;
|
||||||
|
timer.PrevTimerIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,12 +272,16 @@ namespace AlicizaX
|
|||||||
_timerIdToPoolIndex = new int[1024];
|
_timerIdToPoolIndex = new int[1024];
|
||||||
_freeIndices = new int[_timerPoolCapacity];
|
_freeIndices = new int[_timerPoolCapacity];
|
||||||
_freeCount = _timerPoolCapacity;
|
_freeCount = _timerPoolCapacity;
|
||||||
|
_pendingRemoveTimers = new int[64];
|
||||||
|
_pendingRemoveCount = 0;
|
||||||
|
|
||||||
for (int i = 0; i < _timerPoolCapacity; i++)
|
for (int i = 0; i < _timerPoolCapacity; i++)
|
||||||
{
|
{
|
||||||
_freeIndices[i] = i;
|
_freeIndices[i] = i;
|
||||||
_timerPool[i].NextTimerIndex = -1;
|
_timerPool[i].NextTimerIndex = -1;
|
||||||
_timerPool[i].PrevTimerIndex = -1;
|
_timerPool[i].PrevTimerIndex = -1;
|
||||||
|
_timerPool[i].Level = -1;
|
||||||
|
_timerPool[i].SlotIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_scaledTimeWheel = new HierarchicalTimeWheel(0.001f);
|
_scaledTimeWheel = new HierarchicalTimeWheel(0.001f);
|
||||||
@ -282,7 +314,6 @@ namespace AlicizaX
|
|||||||
return timer.TimerId;
|
return timer.TimerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int AddTimer<T>(Action<T> callback, T arg, float time, bool isLoop = false, bool isUnscaled = false)
|
public int AddTimer<T>(Action<T> callback, T arg, float time, bool isLoop = false, bool isUnscaled = false)
|
||||||
{
|
{
|
||||||
@ -292,8 +323,8 @@ namespace AlicizaX
|
|||||||
timer.TimerId = ++_curTimerId;
|
timer.TimerId = ++_curTimerId;
|
||||||
timer.TriggerTime = (isUnscaled ? Time.unscaledTime : Time.time) + time;
|
timer.TriggerTime = (isUnscaled ? Time.unscaledTime : Time.time) + time;
|
||||||
timer.Interval = isLoop ? time : 0f;
|
timer.Interval = isLoop ? time : 0f;
|
||||||
timer.HandlerGeneric = callback; // 直接存储委托,无需包装
|
timer.HandlerGeneric = callback;
|
||||||
timer.GenericArg = arg; // struct会装箱一次,但只在添加时
|
timer.GenericArg = arg;
|
||||||
timer.HandlerType = 2;
|
timer.HandlerType = 2;
|
||||||
timer.IsLoop = isLoop;
|
timer.IsLoop = isLoop;
|
||||||
timer.IsRunning = true;
|
timer.IsRunning = true;
|
||||||
@ -352,6 +383,8 @@ namespace AlicizaX
|
|||||||
_freeIndices[_freeCount++] = i;
|
_freeIndices[_freeCount++] = i;
|
||||||
_timerPool[i].NextTimerIndex = -1;
|
_timerPool[i].NextTimerIndex = -1;
|
||||||
_timerPool[i].PrevTimerIndex = -1;
|
_timerPool[i].PrevTimerIndex = -1;
|
||||||
|
_timerPool[i].Level = -1;
|
||||||
|
_timerPool[i].SlotIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _freeIndices[--_freeCount];
|
return _freeIndices[--_freeCount];
|
||||||
@ -371,33 +404,35 @@ namespace AlicizaX
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private int GetPoolIndex(int timerId)
|
private int GetPoolIndex(int timerId)
|
||||||
{
|
{
|
||||||
return timerId < _timerIdToPoolIndex.Length ? _timerIdToPoolIndex[timerId] : -1;
|
return timerId > 0 && timerId < _timerIdToPoolIndex.Length ? _timerIdToPoolIndex[timerId] : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop(int timerId)
|
public void Stop(int timerId)
|
||||||
{
|
{
|
||||||
int poolIndex = GetPoolIndex(timerId);
|
int poolIndex = GetPoolIndex(timerId);
|
||||||
if (poolIndex >= 0 && _timerPool[poolIndex].IsActive)
|
if (poolIndex >= 0 && poolIndex < _timerPool.Length && _timerPool[poolIndex].IsActive)
|
||||||
_timerPool[poolIndex].IsRunning = false;
|
_timerPool[poolIndex].IsRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Resume(int timerId)
|
public void Resume(int timerId)
|
||||||
{
|
{
|
||||||
int poolIndex = GetPoolIndex(timerId);
|
int poolIndex = GetPoolIndex(timerId);
|
||||||
if (poolIndex >= 0 && _timerPool[poolIndex].IsActive)
|
if (poolIndex >= 0 && poolIndex < _timerPool.Length && _timerPool[poolIndex].IsActive)
|
||||||
_timerPool[poolIndex].IsRunning = true;
|
_timerPool[poolIndex].IsRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsRunning(int timerId)
|
public bool IsRunning(int timerId)
|
||||||
{
|
{
|
||||||
int poolIndex = GetPoolIndex(timerId);
|
int poolIndex = GetPoolIndex(timerId);
|
||||||
return poolIndex >= 0 && _timerPool[poolIndex].IsActive && _timerPool[poolIndex].IsRunning;
|
return poolIndex >= 0 && poolIndex < _timerPool.Length &&
|
||||||
|
_timerPool[poolIndex].IsActive && _timerPool[poolIndex].IsRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetLeftTime(int timerId)
|
public float GetLeftTime(int timerId)
|
||||||
{
|
{
|
||||||
int poolIndex = GetPoolIndex(timerId);
|
int poolIndex = GetPoolIndex(timerId);
|
||||||
if (poolIndex < 0 || !_timerPool[poolIndex].IsActive) return 0;
|
if (poolIndex < 0 || poolIndex >= _timerPool.Length || !_timerPool[poolIndex].IsActive)
|
||||||
|
return 0;
|
||||||
|
|
||||||
ref TimerInfo timer = ref _timerPool[poolIndex];
|
ref TimerInfo timer = ref _timerPool[poolIndex];
|
||||||
return Mathf.Max(timer.TriggerTime - (timer.IsUnscaled ? Time.unscaledTime : Time.time), 0);
|
return Mathf.Max(timer.TriggerTime - (timer.IsUnscaled ? Time.unscaledTime : Time.time), 0);
|
||||||
@ -406,25 +441,35 @@ namespace AlicizaX
|
|||||||
public void Restart(int timerId)
|
public void Restart(int timerId)
|
||||||
{
|
{
|
||||||
int poolIndex = GetPoolIndex(timerId);
|
int poolIndex = GetPoolIndex(timerId);
|
||||||
if (poolIndex < 0 || !_timerPool[poolIndex].IsActive) return;
|
if (poolIndex < 0 || poolIndex >= _timerPool.Length || !_timerPool[poolIndex].IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
ref TimerInfo timer = ref _timerPool[poolIndex];
|
ref TimerInfo timer = ref _timerPool[poolIndex];
|
||||||
timer.TriggerTime = (timer.IsUnscaled ? Time.unscaledTime : Time.time) + timer.Interval;
|
|
||||||
|
|
||||||
|
// 先从时间轮中移除
|
||||||
HierarchicalTimeWheel targetWheel = timer.IsUnscaled ? _unscaledTimeWheel : _scaledTimeWheel;
|
HierarchicalTimeWheel targetWheel = timer.IsUnscaled ? _unscaledTimeWheel : _scaledTimeWheel;
|
||||||
|
targetWheel.RemoveTimer(poolIndex, _timerPool);
|
||||||
|
|
||||||
|
// 重新计算触发时间并添加
|
||||||
|
timer.TriggerTime = (timer.IsUnscaled ? Time.unscaledTime : Time.time) + timer.Interval;
|
||||||
targetWheel.AddTimer(poolIndex, _timerPool, timer.IsUnscaled ? Time.unscaledTime : Time.time);
|
targetWheel.AddTimer(poolIndex, _timerPool, timer.IsUnscaled ? Time.unscaledTime : Time.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveTimer(int timerId)
|
public void RemoveTimer(int timerId)
|
||||||
{
|
{
|
||||||
int poolIndex = GetPoolIndex(timerId);
|
int poolIndex = GetPoolIndex(timerId);
|
||||||
if (poolIndex < 0 || !_timerPool[poolIndex].IsActive) return;
|
if (poolIndex < 0 || poolIndex >= _timerPool.Length || !_timerPool[poolIndex].IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
ref TimerInfo timer = ref _timerPool[poolIndex];
|
ref TimerInfo timer = ref _timerPool[poolIndex];
|
||||||
timer.IsActive = false;
|
timer.IsActive = false;
|
||||||
|
|
||||||
HierarchicalTimeWheel targetWheel = timer.IsUnscaled ? _unscaledTimeWheel : _scaledTimeWheel;
|
// 优化7: 只有在时间轮中时才移除
|
||||||
targetWheel.RemoveTimer(poolIndex, _timerPool);
|
if (timer.Level >= 0)
|
||||||
|
{
|
||||||
|
HierarchicalTimeWheel targetWheel = timer.IsUnscaled ? _unscaledTimeWheel : _scaledTimeWheel;
|
||||||
|
targetWheel.RemoveTimer(poolIndex, _timerPool);
|
||||||
|
}
|
||||||
|
|
||||||
ReleaseTimerToPool(poolIndex);
|
ReleaseTimerToPool(poolIndex);
|
||||||
}
|
}
|
||||||
@ -444,22 +489,37 @@ namespace AlicizaX
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void ReleaseTimerToPool(int poolIndex)
|
private void ReleaseTimerToPool(int poolIndex)
|
||||||
{
|
{
|
||||||
_timerPool[poolIndex].Clear();
|
if (poolIndex >= 0 && poolIndex < _timerPool.Length)
|
||||||
_freeIndices[_freeCount++] = poolIndex;
|
{
|
||||||
|
_timerPool[poolIndex].Clear();
|
||||||
|
|
||||||
|
if (_freeCount >= _freeIndices.Length)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _freeIndices, _freeIndices.Length * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
_freeIndices[_freeCount++] = poolIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IModuleUpdate.Update(float elapseSeconds, float realElapseSeconds)
|
void IModuleUpdate.Update(float elapseSeconds, float realElapseSeconds)
|
||||||
{
|
{
|
||||||
_scaledTimeWheel.Advance(Time.time, _timerPool, ProcessTimer);
|
_scaledTimeWheel.Advance(Time.time, _timerPool, ProcessTimer);
|
||||||
_unscaledTimeWheel.Advance(Time.unscaledTime, _timerPool, ProcessTimer);
|
_unscaledTimeWheel.Advance(Time.unscaledTime, _timerPool, ProcessTimer);
|
||||||
|
|
||||||
|
// 优化8: 处理延迟删除队列
|
||||||
|
ProcessPendingRemovals();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优化7: 使用静态泛型分发,避免反射和类型检查
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void ProcessTimer(int poolIndex)
|
private void ProcessTimer(int poolIndex)
|
||||||
{
|
{
|
||||||
|
if (poolIndex < 0 || poolIndex >= _timerPool.Length)
|
||||||
|
return;
|
||||||
|
|
||||||
ref TimerInfo timer = ref _timerPool[poolIndex];
|
ref TimerInfo timer = ref _timerPool[poolIndex];
|
||||||
if (!timer.IsActive || !timer.IsRunning) return;
|
if (!timer.IsActive || !timer.IsRunning)
|
||||||
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -471,18 +531,20 @@ namespace AlicizaX
|
|||||||
case 1: // NoArgs
|
case 1: // NoArgs
|
||||||
timer.HandlerNoArgs?.Invoke();
|
timer.HandlerNoArgs?.Invoke();
|
||||||
break;
|
break;
|
||||||
case 2: // Generic<struct>
|
case 2: // Generic
|
||||||
case 3: // Generic<class>
|
|
||||||
// 直接调用,利用JIT优化
|
|
||||||
((dynamic)timer.HandlerGeneric)?.Invoke((dynamic)timer.GenericArg);
|
((dynamic)timer.HandlerGeneric)?.Invoke((dynamic)timer.GenericArg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.Error($"TimerInfo callback error: {e}");
|
Log.Error($"Timer callback error: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 优化9: 回调后检查是否仍然有效
|
||||||
|
if (!timer.IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
if (timer.IsLoop)
|
if (timer.IsLoop)
|
||||||
{
|
{
|
||||||
timer.TriggerTime += timer.Interval;
|
timer.TriggerTime += timer.Interval;
|
||||||
@ -491,10 +553,31 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RemoveTimer(timer.TimerId);
|
// 优化10: 延迟删除,避免在遍历时修改
|
||||||
|
AddPendingRemoval(timer.TimerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private void AddPendingRemoval(int timerId)
|
||||||
|
{
|
||||||
|
if (_pendingRemoveCount >= _pendingRemoveTimers.Length)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _pendingRemoveTimers, _pendingRemoveTimers.Length * 2);
|
||||||
|
}
|
||||||
|
_pendingRemoveTimers[_pendingRemoveCount++] = timerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private void ProcessPendingRemovals()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _pendingRemoveCount; i++)
|
||||||
|
{
|
||||||
|
RemoveTimer(_pendingRemoveTimers[i]);
|
||||||
|
}
|
||||||
|
_pendingRemoveCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void IModule.Dispose() => RemoveAllTimer();
|
void IModule.Dispose() => RemoveAllTimer();
|
||||||
|
|
||||||
public int Priority => 0;
|
public int Priority => 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user