1
This commit is contained in:
parent
a99b71b049
commit
c692b47a62
@ -26,13 +26,13 @@ namespace AlicizaX
|
|||||||
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
|
public byte HandlerType;
|
||||||
|
|
||||||
public object[] Args;
|
public object[] Args;
|
||||||
public object GenericArg;
|
public object GenericArg;
|
||||||
|
|
||||||
// 优化1: 添加层级信息,用于精确定位
|
|
||||||
public int Level; // 当前所在的时间轮层级
|
public int Level;
|
||||||
public int SlotIndex;
|
public int SlotIndex;
|
||||||
public int NextTimerIndex;
|
public int NextTimerIndex;
|
||||||
public int PrevTimerIndex;
|
public int PrevTimerIndex;
|
||||||
@ -68,7 +68,6 @@ namespace AlicizaX
|
|||||||
private int[] _freeIndices;
|
private int[] _freeIndices;
|
||||||
private int _freeCount;
|
private int _freeCount;
|
||||||
|
|
||||||
// 优化2: 延迟删除队列,避免在遍历时修改链表
|
|
||||||
private int[] _pendingRemoveTimers;
|
private int[] _pendingRemoveTimers;
|
||||||
private int _pendingRemoveCount;
|
private int _pendingRemoveCount;
|
||||||
|
|
||||||
@ -137,7 +136,6 @@ namespace AlicizaX
|
|||||||
slotIndex = (_levels[2].CurrentSlot + level2Slots) % SLOT_COUNT_LEVEL2;
|
slotIndex = (_levels[2].CurrentSlot + level2Slots) % SLOT_COUNT_LEVEL2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优化3: 记录层级信息
|
|
||||||
timer.Level = level;
|
timer.Level = level;
|
||||||
timer.SlotIndex = slotIndex;
|
timer.SlotIndex = slotIndex;
|
||||||
timer.NextTimerIndex = _levels[level].SlotHeads[slotIndex];
|
timer.NextTimerIndex = _levels[level].SlotHeads[slotIndex];
|
||||||
@ -183,30 +181,26 @@ 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)
|
||||||
{
|
{
|
||||||
ref TimerInfo timer = ref pool[currentIndex];
|
ref TimerInfo timer = ref pool[currentIndex];
|
||||||
int nextIndex = timer.NextTimerIndex;
|
int nextIndex = timer.NextTimerIndex;
|
||||||
|
|
||||||
// 断开链表连接
|
|
||||||
timer.NextTimerIndex = -1;
|
timer.NextTimerIndex = -1;
|
||||||
timer.PrevTimerIndex = -1;
|
timer.PrevTimerIndex = -1;
|
||||||
timer.Level = -1; // 标记为不在时间轮中
|
timer.Level = -1;
|
||||||
|
|
||||||
if (timer.IsActive && timer.IsRunning)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,7 +209,6 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优化5: 安全的移除方法,检查边界
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void RemoveTimer(int poolIndex, TimerInfo[] pool)
|
public void RemoveTimer(int poolIndex, TimerInfo[] pool)
|
||||||
{
|
{
|
||||||
@ -224,18 +217,15 @@ namespace AlicizaX
|
|||||||
|
|
||||||
ref TimerInfo timer = ref pool[poolIndex];
|
ref TimerInfo timer = ref pool[poolIndex];
|
||||||
|
|
||||||
// 优化6: 如果已经不在时间轮中,直接返回
|
|
||||||
if (timer.Level < 0 || timer.Level >= _levels.Length)
|
if (timer.Level < 0 || timer.Level >= _levels.Length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int level = timer.Level;
|
int level = timer.Level;
|
||||||
int slotIndex = timer.SlotIndex;
|
int slotIndex = timer.SlotIndex;
|
||||||
|
|
||||||
// 边界检查
|
|
||||||
if (slotIndex < 0 || slotIndex >= _levels[level].SlotCount)
|
if (slotIndex < 0 || slotIndex >= _levels[level].SlotCount)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// 从链表中移除
|
|
||||||
if (timer.PrevTimerIndex != -1)
|
if (timer.PrevTimerIndex != -1)
|
||||||
{
|
{
|
||||||
if (timer.PrevTimerIndex < pool.Length)
|
if (timer.PrevTimerIndex < pool.Length)
|
||||||
@ -245,7 +235,6 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 是头节点
|
|
||||||
_levels[level].SlotHeads[slotIndex] = timer.NextTimerIndex;
|
_levels[level].SlotHeads[slotIndex] = timer.NextTimerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +246,6 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除链表信息
|
|
||||||
timer.Level = -1;
|
timer.Level = -1;
|
||||||
timer.SlotIndex = -1;
|
timer.SlotIndex = -1;
|
||||||
timer.NextTimerIndex = -1;
|
timer.NextTimerIndex = -1;
|
||||||
@ -446,11 +434,9 @@ namespace AlicizaX
|
|||||||
|
|
||||||
ref TimerInfo timer = ref _timerPool[poolIndex];
|
ref TimerInfo timer = ref _timerPool[poolIndex];
|
||||||
|
|
||||||
// 先从时间轮中移除
|
|
||||||
HierarchicalTimeWheel targetWheel = timer.IsUnscaled ? _unscaledTimeWheel : _scaledTimeWheel;
|
HierarchicalTimeWheel targetWheel = timer.IsUnscaled ? _unscaledTimeWheel : _scaledTimeWheel;
|
||||||
targetWheel.RemoveTimer(poolIndex, _timerPool);
|
targetWheel.RemoveTimer(poolIndex, _timerPool);
|
||||||
|
|
||||||
// 重新计算触发时间并添加
|
|
||||||
timer.TriggerTime = (timer.IsUnscaled ? Time.unscaledTime : Time.time) + timer.Interval;
|
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);
|
||||||
}
|
}
|
||||||
@ -464,7 +450,6 @@ namespace AlicizaX
|
|||||||
ref TimerInfo timer = ref _timerPool[poolIndex];
|
ref TimerInfo timer = ref _timerPool[poolIndex];
|
||||||
timer.IsActive = false;
|
timer.IsActive = false;
|
||||||
|
|
||||||
// 优化7: 只有在时间轮中时才移除
|
|
||||||
if (timer.Level >= 0)
|
if (timer.Level >= 0)
|
||||||
{
|
{
|
||||||
HierarchicalTimeWheel targetWheel = timer.IsUnscaled ? _unscaledTimeWheel : _scaledTimeWheel;
|
HierarchicalTimeWheel targetWheel = timer.IsUnscaled ? _unscaledTimeWheel : _scaledTimeWheel;
|
||||||
@ -507,7 +492,6 @@ namespace AlicizaX
|
|||||||
_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();
|
ProcessPendingRemovals();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,7 +525,6 @@ namespace AlicizaX
|
|||||||
Log.Error($"Timer callback error: {e}");
|
Log.Error($"Timer callback error: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优化9: 回调后检查是否仍然有效
|
|
||||||
if (!timer.IsActive)
|
if (!timer.IsActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -553,7 +536,6 @@ namespace AlicizaX
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 优化10: 延迟删除,避免在遍历时修改
|
|
||||||
AddPendingRemoval(timer.TimerId);
|
AddPendingRemoval(timer.TimerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -144,7 +144,6 @@ namespace AlicizaX.UI.Runtime
|
|||||||
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
|
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
|
||||||
int lastIdx = layer.OrderList.Count - 1;
|
int lastIdx = layer.OrderList.Count - 1;
|
||||||
|
|
||||||
// O(1) lookup instead of O(n) IndexOf
|
|
||||||
if (!layer.IndexMap.TryGetValue(meta.MetaInfo.RuntimeTypeHandle, out int currentIdx))
|
if (!layer.IndexMap.TryGetValue(meta.MetaInfo.RuntimeTypeHandle, out int currentIdx))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -153,17 +152,14 @@ namespace AlicizaX.UI.Runtime
|
|||||||
layer.OrderList.RemoveAt(currentIdx);
|
layer.OrderList.RemoveAt(currentIdx);
|
||||||
layer.OrderList.Add(meta);
|
layer.OrderList.Add(meta);
|
||||||
|
|
||||||
// Update indices for shifted elements
|
|
||||||
for (int i = currentIdx; i < lastIdx; i++)
|
for (int i = currentIdx; i < lastIdx; i++)
|
||||||
{
|
{
|
||||||
var m = layer.OrderList[i];
|
var m = layer.OrderList[i];
|
||||||
layer.IndexMap[m.MetaInfo.RuntimeTypeHandle] = i;
|
layer.IndexMap[m.MetaInfo.RuntimeTypeHandle] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update moved element's index
|
|
||||||
layer.IndexMap[meta.MetaInfo.RuntimeTypeHandle] = lastIdx;
|
layer.IndexMap[meta.MetaInfo.RuntimeTypeHandle] = lastIdx;
|
||||||
|
|
||||||
// Only update depth for affected windows (from currentIdx onwards)
|
|
||||||
SortWindowDepth(meta.MetaInfo.UILayer, currentIdx);
|
SortWindowDepth(meta.MetaInfo.UILayer, currentIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +182,6 @@ namespace AlicizaX.UI.Runtime
|
|||||||
var list = _openUI[layer].OrderList;
|
var list = _openUI[layer].OrderList;
|
||||||
int count = list.Count;
|
int count = list.Count;
|
||||||
|
|
||||||
// Find topmost fullscreen window (early exit optimization)
|
|
||||||
int fullscreenIdx = -1;
|
int fullscreenIdx = -1;
|
||||||
for (int i = count - 1; i >= 0; i--)
|
for (int i = count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@ -194,14 +189,12 @@ namespace AlicizaX.UI.Runtime
|
|||||||
if (meta.MetaInfo.FullScreen && meta.State == UIState.Opened)
|
if (meta.MetaInfo.FullScreen && meta.State == UIState.Opened)
|
||||||
{
|
{
|
||||||
fullscreenIdx = i;
|
fullscreenIdx = i;
|
||||||
break; // Early exit - found topmost fullscreen
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set visibility based on fullscreen index
|
|
||||||
if (fullscreenIdx == -1)
|
if (fullscreenIdx == -1)
|
||||||
{
|
{
|
||||||
// No fullscreen window, all visible
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
list[i].View.Visible = true;
|
list[i].View.Visible = true;
|
||||||
@ -209,7 +202,6 @@ namespace AlicizaX.UI.Runtime
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Hide windows below fullscreen, show from fullscreen onwards
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
list[i].View.Visible = (i >= fullscreenIdx);
|
list[i].View.Visible = (i >= fullscreenIdx);
|
||||||
@ -222,12 +214,10 @@ namespace AlicizaX.UI.Runtime
|
|||||||
var list = _openUI[layer].OrderList;
|
var list = _openUI[layer].OrderList;
|
||||||
int baseDepth = layer * LAYER_DEEP;
|
int baseDepth = layer * LAYER_DEEP;
|
||||||
|
|
||||||
// Only update from startIndex onwards (optimization for partial updates)
|
|
||||||
for (int i = startIndex; i < list.Count; i++)
|
for (int i = startIndex; i < list.Count; i++)
|
||||||
{
|
{
|
||||||
int newDepth = baseDepth + i * WINDOW_DEEP;
|
int newDepth = baseDepth + i * WINDOW_DEEP;
|
||||||
|
|
||||||
// Only set if changed to avoid unnecessary Canvas updates
|
|
||||||
if (list[i].View.Depth != newDepth)
|
if (list[i].View.Depth != newDepth)
|
||||||
{
|
{
|
||||||
list[i].View.Depth = newDepth;
|
list[i].View.Depth = newDepth;
|
||||||
|
|||||||
@ -12,11 +12,10 @@ namespace AlicizaX.UI.Runtime
|
|||||||
public abstract partial class UIBase
|
public abstract partial class UIBase
|
||||||
{
|
{
|
||||||
private readonly Dictionary<UIBase, UIMetadata> _children = new();
|
private readonly Dictionary<UIBase, UIMetadata> _children = new();
|
||||||
private readonly List<UIMetadata> _updateableChildren = new(); // Cache for widgets that need updates
|
private readonly List<UIMetadata> _updateableChildren = new();
|
||||||
|
|
||||||
private void UpdateChildren()
|
private void UpdateChildren()
|
||||||
{
|
{
|
||||||
// Use cached list to avoid dictionary enumeration allocation
|
|
||||||
for (int i = 0; i < _updateableChildren.Count; i++)
|
for (int i = 0; i < _updateableChildren.Count; i++)
|
||||||
{
|
{
|
||||||
var meta = _updateableChildren[i];
|
var meta = _updateableChildren[i];
|
||||||
@ -33,7 +32,6 @@ namespace AlicizaX.UI.Runtime
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
// Use struct enumerator to avoid allocation
|
|
||||||
foreach (var kvp in _children)
|
foreach (var kvp in _children)
|
||||||
{
|
{
|
||||||
temp[i++] = kvp.Value;
|
temp[i++] = kvp.Value;
|
||||||
@ -56,7 +54,6 @@ namespace AlicizaX.UI.Runtime
|
|||||||
|
|
||||||
private void ChildVisible(bool value)
|
private void ChildVisible(bool value)
|
||||||
{
|
{
|
||||||
// Use struct enumerator to avoid allocation
|
|
||||||
foreach (var kvp in _children)
|
foreach (var kvp in _children)
|
||||||
{
|
{
|
||||||
var view = kvp.Value.View;
|
var view = kvp.Value.View;
|
||||||
@ -164,7 +161,6 @@ namespace AlicizaX.UI.Runtime
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to updateable list if widget needs updates
|
|
||||||
if (meta.MetaInfo.NeedUpdate)
|
if (meta.MetaInfo.NeedUpdate)
|
||||||
{
|
{
|
||||||
_updateableChildren.Add(meta);
|
_updateableChildren.Add(meta);
|
||||||
@ -180,7 +176,6 @@ namespace AlicizaX.UI.Runtime
|
|||||||
meta.CancelAsyncOperations();
|
meta.CancelAsyncOperations();
|
||||||
await widget.InternalClose();
|
await widget.InternalClose();
|
||||||
|
|
||||||
// Remove from updateable list if present
|
|
||||||
if (meta.MetaInfo.NeedUpdate)
|
if (meta.MetaInfo.NeedUpdate)
|
||||||
{
|
{
|
||||||
_updateableChildren.Remove(meta);
|
_updateableChildren.Remove(meta);
|
||||||
|
|||||||
@ -233,7 +233,7 @@ namespace AlicizaX.UI.Runtime
|
|||||||
internal async UniTask InternalClose(CancellationToken cancellationToken = default)
|
internal async UniTask InternalClose(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (_state != UIState.Opened)
|
if (_state != UIState.Opened)
|
||||||
return; // Not open, nothing to close
|
return;
|
||||||
|
|
||||||
if (!UIStateMachine.ValidateTransition(GetType().Name, _state, UIState.Closed))
|
if (!UIStateMachine.ValidateTransition(GetType().Name, _state, UIState.Closed))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -68,10 +68,7 @@ namespace AlicizaX.UI.Runtime
|
|||||||
|
|
||||||
private bool _isAlive = true;
|
private bool _isAlive = true;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if this holder is still valid (not destroyed).
|
|
||||||
/// Use this instead of null check for better clarity.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsValid()
|
public bool IsValid()
|
||||||
{
|
{
|
||||||
return this != null && _isAlive;
|
return this != null && _isAlive;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user