AlicizaX/Client/Packages/com.alicizax.unity.ui/Runtime/UI/Manager/UIModule.Open.cs

168 lines
5.1 KiB
C#
Raw Normal View History

2025-03-04 18:40:14 +08:00
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
2025-04-28 19:45:45 +08:00
using AlicizaX;
2025-03-04 18:40:14 +08:00
using Cysharp.Threading.Tasks;
namespace AlicizaX.UI.Runtime
{
readonly struct LayerData
{
public readonly List<UIMetadata> OrderList; // 维护插入顺序
public readonly HashSet<RuntimeTypeHandle> HandleSet; // O(1)存在性检查
public LayerData(int initialCapacity)
{
OrderList = new List<UIMetadata>(initialCapacity);
HandleSet = new HashSet<RuntimeTypeHandle>();
}
}
2025-04-28 19:45:45 +08:00
internal sealed partial class UIModule
2025-03-04 18:40:14 +08:00
{
private readonly LayerData[] _openUI = new LayerData[(int)UILayer.All];
2025-03-11 21:03:30 +08:00
private async UniTask<UIBase> ShowUIImplAsync(UIMetadata meta, params object[] userDatas)
2025-03-04 18:40:14 +08:00
{
2025-03-11 21:03:30 +08:00
var metaInfo = GetOrCreateMeta(meta);
2025-04-28 19:45:45 +08:00
await UIHolderFactory.CreateUIResource(metaInfo, UICacheLayer);
return await FinalizeShow(metaInfo, userDatas);
2025-03-04 18:40:14 +08:00
}
2025-04-28 19:45:45 +08:00
private async UniTask CloseUIImpl(UIMetadata meta, bool force)
2025-03-04 18:40:14 +08:00
{
2025-04-28 19:45:45 +08:00
if (meta.State == UIState.Uninitialized || meta.State == UIState.CreatedUI)
2025-03-04 18:40:14 +08:00
{
return;
}
2025-04-28 19:45:45 +08:00
await meta.View.InternalClose();
2025-03-04 18:40:14 +08:00
Pop(meta);
2025-04-28 19:45:45 +08:00
SortWindowVisible(meta.MetaInfo.UILayer);
SortWindowDepth(meta.MetaInfo.UILayer);
2025-03-04 18:40:14 +08:00
CacheWindow(meta, force);
}
2025-03-11 21:03:30 +08:00
private UIBase GetUIImpl(UIMetadata meta)
2025-03-04 18:40:14 +08:00
{
2025-03-11 21:03:30 +08:00
return meta.View;
2025-03-04 18:40:14 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2025-03-11 21:03:30 +08:00
private UIMetadata GetOrCreateMeta(UIMetadata meta)
2025-03-04 18:40:14 +08:00
{
if (meta.State == UIState.Uninitialized) meta.CreateUI();
return meta;
}
2025-04-28 19:45:45 +08:00
private async UniTask<UIBase> FinalizeShow(UIMetadata meta, object[] userDatas)
2025-03-04 18:40:14 +08:00
{
if (meta.InCache)
{
2025-04-28 19:45:45 +08:00
RemoveFromCache(meta.MetaInfo.RuntimeTypeHandle);
2025-03-04 18:40:14 +08:00
Push(meta);
}
else
{
switch (meta.State)
{
case UIState.Loaded:
Push(meta);
break;
case UIState.Opened:
MoveToTop(meta);
break;
}
}
meta.View.RefreshParams(userDatas);
2025-04-28 19:45:45 +08:00
await UpdateVisualState(meta);
2025-03-04 18:40:14 +08:00
return meta.View;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Push(UIMetadata meta)
{
2025-04-28 19:45:45 +08:00
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
if (layer.HandleSet.Add(meta.MetaInfo.RuntimeTypeHandle))
2025-03-04 18:40:14 +08:00
{
layer.OrderList.Add(meta);
UpdateLayerParent(meta);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Pop(UIMetadata meta)
{
2025-04-28 19:45:45 +08:00
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
if (layer.HandleSet.Remove(meta.MetaInfo.RuntimeTypeHandle))
2025-03-04 18:40:14 +08:00
{
layer.OrderList.Remove(meta);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void UpdateLayerParent(UIMetadata meta)
{
2025-04-28 19:45:45 +08:00
if (meta.View?.Holder)
2025-03-04 18:40:14 +08:00
{
2025-04-28 19:45:45 +08:00
var layerRect = GetLayerRect(meta.MetaInfo.UILayer);
2025-03-04 18:40:14 +08:00
meta.View.Holder.transform.SetParent(layerRect);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void MoveToTop(UIMetadata meta)
{
2025-04-28 19:45:45 +08:00
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
2025-03-04 18:40:14 +08:00
int lastIdx = layer.OrderList.Count - 1;
int currentIdx = layer.OrderList.IndexOf(meta);
if (currentIdx != lastIdx && currentIdx >= 0)
{
layer.OrderList.RemoveAt(currentIdx);
layer.OrderList.Add(meta);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2025-04-28 19:45:45 +08:00
private async UniTask UpdateVisualState(UIMetadata meta)
2025-03-04 18:40:14 +08:00
{
2025-04-28 19:45:45 +08:00
SortWindowVisible(meta.MetaInfo.UILayer);
SortWindowDepth(meta.MetaInfo.UILayer);
2025-03-04 18:40:14 +08:00
if (meta.State == UIState.Loaded)
{
2025-04-28 19:45:45 +08:00
await meta.View.InternalInitlized();
2025-03-04 18:40:14 +08:00
}
2025-04-28 19:45:45 +08:00
await meta.View.InternalOpen();
2025-03-04 18:40:14 +08:00
}
private void SortWindowVisible(int layer)
{
var list = _openUI[layer].OrderList;
bool shouldHide = false;
// 反向遍历避免GC分配
for (int i = list.Count - 1; i >= 0; i--)
{
var meta = list[i];
meta.View.Visible = !shouldHide;
2025-04-28 19:45:45 +08:00
shouldHide |= meta.MetaInfo.FullScreen && meta.State == UIState.Opened;
2025-03-04 18:40:14 +08:00
}
}
private void SortWindowDepth(int layer)
{
var list = _openUI[layer].OrderList;
int baseDepth = layer * LAYER_DEEP;
for (int i = 0; i < list.Count; i++)
{
list[i].View.Depth = baseDepth + i * WINDOW_DEEP;
}
}
}
}