[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) public UIMetadata(Type uiType)
{ {
if (uiType == null) if (uiType == null)

View File

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

View File

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

View File

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

View File

@ -60,6 +60,34 @@ namespace AlicizaX.UI.Runtime
_updateableChildren.Clear(); _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) private void ChildVisible(bool value)
{ {
foreach (KeyValuePair<UIBase, UIMetadata> kvp in _children) foreach (KeyValuePair<UIBase, UIMetadata> kvp in _children)

View File

@ -303,6 +303,23 @@ namespace AlicizaX.UI.Runtime
_state = UIState.Destroyed; _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) internal void RefreshParams(params System.Object[] userDatas)
{ {
this._userDatas = 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 System.Runtime.CompilerServices;
using AlicizaX.Resource.Runtime;
using AlicizaX; using AlicizaX;
using AlicizaX.Timer.Runtime; using AlicizaX.Timer.Runtime;
using Cysharp.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;