com.alicizax.unity.framework/Runtime/UI/Manager/UIService.Cache.cs

96 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
using AlicizaX;
using AlicizaX.Timer.Runtime;
namespace AlicizaX.UI.Runtime
{
internal sealed partial class UIService
{
private readonly struct CacheEntry
{
public readonly UIMetadata Metadata;
public readonly ulong TimerHandle;
public CacheEntry(UIMetadata metadata, ulong timerHandle)
{
Metadata = metadata;
TimerHandle = timerHandle;
}
}
private readonly Dictionary<RuntimeTypeHandle, CacheEntry> m_CacheWindow = new();
private void CacheWindow(UIMetadata uiMetadata, bool force)
{
if (uiMetadata?.View?.Holder == null)
{
Log.Error("Cannot cache null UI metadata or holder");
return;
}
if (force || uiMetadata.MetaInfo.CacheTime == 0)
{
uiMetadata.DisposeImmediate();
return;
}
RemoveFromCache(uiMetadata.MetaInfo.RuntimeTypeHandle);
ulong timerHandle = 0UL;
uiMetadata.View.Holder.transform.SetParent(UICacheLayer);
if (uiMetadata.MetaInfo.CacheTime > 0)
{
ITimerService timerService = GetTimerService();
timerHandle = timerService.AddTimer(
OnTimerDisposeWindow,
uiMetadata,
uiMetadata.MetaInfo.CacheTime,
isLoop: false,
isUnscaled: true);
if (timerHandle == 0UL)
{
Log.Warning($"Failed to create cache timer for {uiMetadata.UILogicType.Name}");
}
}
uiMetadata.InCache = true;
m_CacheWindow.Add(uiMetadata.MetaInfo.RuntimeTypeHandle, new CacheEntry(uiMetadata, timerHandle));
}
private void OnTimerDisposeWindow(UIMetadata meta)
{
if (meta != null)
{
RemoveFromCache(meta.MetaInfo.RuntimeTypeHandle);
meta.DisposeImmediate();
}
}
private void RemoveFromCache(RuntimeTypeHandle typeHandle)
{
if (m_CacheWindow.TryGetValue(typeHandle, out var entry))
{
m_CacheWindow.Remove(typeHandle);
entry.Metadata.InCache = false;
if (entry.TimerHandle != 0UL && _timerService != null)
{
_timerService.RemoveTimer(entry.TimerHandle);
}
}
}
private ITimerService GetTimerService()
{
if (_timerService != null)
{
return _timerService;
}
_timerService = AppServices.Require<ITimerService>();
return _timerService;
}
}
}