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