com.alicizax.unity.framework/Runtime/UI/Manager/UIService.cs
陈思海 6c6e61f4fe [Opt] UI框架
增加资源确定性释放路径 UIBase 补上对应的同步销毁实现,用于服务销毁和缓存 timer 到期这种必须立即收口的路径
2026-04-23 20:39:58 +08:00

180 lines
5.3 KiB
C#

using System;
using AlicizaX;
using AlicizaX.Timer.Runtime;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace AlicizaX.UI.Runtime
{
internal sealed partial class UIService : ServiceBase, IUIService, IServiceTickable
{
private ITimerService _timerService;
protected override void OnInitialize()
{
}
protected override void OnDestroyService()
{
DestroyAllManagedUI();
}
void IServiceTickable.Tick(float deltaTime)
{
for (int layerIndex = 0; layerIndex < _openUI.Length; layerIndex++)
{
var layer = _openUI[layerIndex];
int count = layer.OrderList.Count;
if (count == 0) continue;
for (int i = 0; i < count; i++)
{
if (layer.OrderList.Count != count)
{
break;
}
var window = layer.OrderList[i];
if (window.MetaInfo.NeedUpdate)
window.View.InternalUpdate();
}
}
}
public UniTask<UIBase>? ShowUI(string type, params object[] userDatas)
{
if (UIMetaRegistry.TryGet(type, out var metaRegistry))
{
UIMetadata metadata = UIMetadataFactory.GetWindowMetadata(metaRegistry.RuntimeTypeHandle);
return ShowUI(metadata, userDatas);
}
return null;
}
public T ShowUISync<T>(params object[] userDatas) where T : UIBase
{
return (T)ShowUIImplSync(UIMetadataFactory.GetWindowMetadata<T>(), userDatas);
}
public async UniTask<T> ShowUI<T>(params System.Object[] userDatas) where T : UIBase
{
return (T)await ShowUIAsync(UIMetadataFactory.GetWindowMetadata<T>(), userDatas);
}
public void CloseUI<T>(bool force = false) where T : UIBase
{
CloseUIImpl(UIMetadataFactory.GetWindowMetadata<T>(), force).Forget();
}
public T GetUI<T>() where T : UIBase
{
return (T)GetUIImpl(UIMetadataFactory.GetWindowMetadata<T>());
}
private UniTask<UIBase> ShowUI(UIMetadata meta, params System.Object[] userDatas)
{
return ShowUIImplAsync(meta, userDatas);
}
private async UniTask<UIBase> ShowUIAsync(UIMetadata meta, params System.Object[] userDatas)
{
return await ShowUIImplAsync(meta, userDatas);
}
public void CloseUI(RuntimeTypeHandle handle, bool force = false)
{
var metadata = UIMetadataFactory.GetWindowMetadata(handle);
if (metadata.State != UIState.Uninitialized && metadata.State != UIState.Destroying)
{
CloseUIImpl(metadata, force).Forget();
}
}
void IUIService.SetTimerService(ITimerService timerService)
{
_timerService = timerService;
}
private void DestroyAllManagedUI()
{
for (int layerIndex = 0; layerIndex < _openUI.Length; layerIndex++)
{
LayerData layer = _openUI[layerIndex];
if (layer == null)
{
continue;
}
int count = layer.OrderList.Count;
for (int i = count - 1; i >= 0; i--)
{
UIMetadata meta = layer.OrderList[i];
if (meta == null)
{
continue;
}
meta.CancelAsyncOperations();
meta.DisposeImmediate();
}
layer.OrderList.Clear();
layer.IndexMap.Clear();
layer.LastFullscreenIndex = -1;
}
if (m_CacheWindow.Count > 0)
{
RuntimeTypeHandle[] handles = new RuntimeTypeHandle[m_CacheWindow.Count];
int writeIndex = 0;
foreach (var pair in m_CacheWindow)
{
handles[writeIndex++] = pair.Key;
}
for (int i = 0; i < writeIndex; i++)
{
if (!m_CacheWindow.TryGetValue(handles[i], out CacheEntry entry))
{
continue;
}
if (entry.TimerId > 0 && _timerService != null)
{
_timerService.RemoveTimer(entry.TimerId);
}
entry.Metadata.InCache = false;
entry.Metadata.CancelAsyncOperations();
entry.Metadata.DisposeImmediate();
}
m_CacheWindow.Clear();
}
if (m_LastCountDownGuid != 0 && _timerService != null)
{
_timerService.RemoveTimer(m_LastCountDownGuid);
m_LastCountDownGuid = 0;
}
if (m_LayerBlock != null)
{
UnityEngine.Object.Destroy(m_LayerBlock);
m_LayerBlock = null;
}
UICacheLayer = null;
UICanvasRoot = null;
UICanvas = null;
UICamera = null;
UIRoot = null;
}
}
}