[Opt] UI框架

增加资源确定性释放路径 UIBase 补上对应的同步销毁实现,用于服务销毁和缓存 timer 到期这种必须立即收口的路径
This commit is contained in:
陈思海 2026-04-23 20:39:58 +08:00
parent cd5de2c374
commit 6c6e61f4fe
7 changed files with 65 additions and 35 deletions

View File

@ -71,6 +71,17 @@ namespace AlicizaX.UI.Runtime
}
}
internal void DisposeImmediate()
{
CancelAsyncOperations();
if (State != UIState.Uninitialized && State != UIState.Destroying && View != null)
{
View.InternalDestroyImmediate();
View = null;
}
}
public UIMetadata(Type uiType)
{
if (uiType == null)

View File

@ -1,18 +1,17 @@
using System.Collections.Generic;
using AlicizaX.Timer.Runtime;
using UnityEngine;
namespace AlicizaX.UI.Runtime
{
internal sealed partial class UIService
{
private GameObject m_LayerBlock; //内部屏蔽对象 显示时之下的所有UI将不可操作
private int m_LastCountDownGuid; //倒计时的唯一ID
private GameObject m_LayerBlock;
private int m_LastCountDownGuid;
private void InitUIBlock()
{
m_LayerBlock = new GameObject("LayerBlock");
var rect = m_LayerBlock.AddComponent<RectTransform>();
RectTransform rect = m_LayerBlock.AddComponent<RectTransform>();
m_LayerBlock.AddComponent<CanvasRenderer>();
m_LayerBlock.AddComponent<UIBlock>();
rect.SetParent(UICanvasRoot);
@ -21,10 +20,6 @@ namespace AlicizaX.UI.Runtime
SetLayerBlockOption(false);
}
/// <summary>
/// 设置UI遮挡
/// </summary>
/// <param name="timeDuration">倒计时/s</param>
public void SetUIBlock(float timeDuration)
{
ITimerService timerService = GetTimerService();
@ -37,9 +32,6 @@ namespace AlicizaX.UI.Runtime
m_LastCountDownGuid = timerService.AddTimer(OnBlockCountDown, timeDuration);
}
/// <summary>
/// 强制退出UI遮挡
/// </summary>
public void ForceExitBlock()
{
ITimerService timerService = GetTimerService();
@ -56,23 +48,11 @@ namespace AlicizaX.UI.Runtime
RecoverLayerOptionAll();
}
/// <summary>
/// 设置UI是否可以操作
/// 不能提供此API对外操作
/// 因为有人设置过后就会忘记恢复
/// 如果你确实需要你可以设置 禁止无限时间
/// 之后调用恢复操作也可以做到
/// </summary>
/// <param name="value">true = 可以操作 = 屏蔽层会被隐藏</param>
private void SetLayerBlockOption(bool value)
{
m_LayerBlock.SetActive(value);
}
/// <summary>
/// 强制恢复层级到可操作状态
/// 此方法会强制打断倒计时 根据需求调用
/// </summary>
public void RecoverLayerOptionAll()
{
SetLayerBlockOption(false);

View File

@ -64,7 +64,7 @@ namespace AlicizaX.UI.Runtime
if (meta != null)
{
RemoveFromCache(meta.MetaInfo.RuntimeTypeHandle);
meta.Dispose();
meta.DisposeImmediate();
}
}

View File

@ -1,5 +1,4 @@
using System;
using AlicizaX.Resource.Runtime;
using AlicizaX;
using AlicizaX.Timer.Runtime;
using Cysharp.Threading.Tasks;
@ -17,7 +16,7 @@ namespace AlicizaX.UI.Runtime
protected override void OnDestroyService()
{
DestroyAllManagedUI().Forget();
DestroyAllManagedUI();
}
void IServiceTickable.Tick(float deltaTime)
@ -101,7 +100,7 @@ namespace AlicizaX.UI.Runtime
_timerService = timerService;
}
private async UniTask DestroyAllManagedUI()
private void DestroyAllManagedUI()
{
for (int layerIndex = 0; layerIndex < _openUI.Length; layerIndex++)
{
@ -121,7 +120,7 @@ namespace AlicizaX.UI.Runtime
}
meta.CancelAsyncOperations();
await meta.DisposeAsync();
meta.DisposeImmediate();
}
layer.OrderList.Clear();
@ -152,7 +151,7 @@ namespace AlicizaX.UI.Runtime
entry.Metadata.InCache = false;
entry.Metadata.CancelAsyncOperations();
await entry.Metadata.DisposeAsync();
entry.Metadata.DisposeImmediate();
}
m_CacheWindow.Clear();

View File

@ -60,6 +60,34 @@ namespace AlicizaX.UI.Runtime
_updateableChildren.Clear();
}
private void DestroyAllChildrenImmediate()
{
var temp = ArrayPool<UIMetadata>.Shared.Rent(_children.Count);
try
{
int i = 0;
foreach (var kvp in _children)
{
temp[i++] = kvp.Value;
}
for (int j = 0; j < i; j++)
{
UIMetadata metadata = temp[j];
metadata.DisposeImmediate();
UIMetadataFactory.ReturnToPool(metadata);
temp[j] = null;
}
}
finally
{
ArrayPool<UIMetadata>.Shared.Return(temp, true);
}
_children.Clear();
_updateableChildren.Clear();
}
private void ChildVisible(bool value)
{
foreach (KeyValuePair<UIBase, UIMetadata> kvp in _children)

View File

@ -303,6 +303,23 @@ namespace AlicizaX.UI.Runtime
_state = UIState.Destroyed;
}
internal void InternalDestroyImmediate()
{
if (!UIStateMachine.ValidateTransition(GetType().Name, _state, UIState.Destroying))
{
return;
}
InterruptLifecycleTransition();
_state = UIState.Destroying;
Holder?.OnWindowDestroyEvent?.Invoke();
DestroyAllChildrenImmediate();
OnDestroy();
ReleaseEventListenerProxy();
Dispose();
_state = UIState.Destroyed;
}
internal void RefreshParams(params System.Object[] userDatas)
{
this._userDatas = userDatas;

View File

@ -1,11 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using AlicizaX.Resource.Runtime;
using AlicizaX;
using AlicizaX.Timer.Runtime;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using Object = UnityEngine.Object;