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

177 lines
5.2 KiB
C#
Raw Normal View History

2025-09-05 19:46:30 +08:00
using System;
using AlicizaX;
using AlicizaX.Timer.Runtime;
using Cysharp.Text;
2025-09-05 19:46:30 +08:00
namespace AlicizaX.UI.Runtime
{
internal sealed partial class UIService
2025-09-05 19:46:30 +08:00
{
private readonly struct CacheEntry
{
public readonly UIMetadata Metadata;
2026-04-27 12:06:09 +08:00
public readonly ulong TimerHandle;
2026-04-27 12:06:09 +08:00
public CacheEntry(UIMetadata metadata, ulong timerHandle)
{
Metadata = metadata;
2026-04-27 12:06:09 +08:00
TimerHandle = timerHandle;
}
}
private CacheEntry[] m_CacheWindow = new CacheEntry[8];
private int[] m_CacheTypeIdToIndex = CreateCacheIndexArray(8);
private int m_CacheWindowCount;
2025-09-05 19:46:30 +08:00
private void CacheWindow(UIMetadata uiMetadata, bool force)
{
2025-12-24 20:44:36 +08:00
if (uiMetadata?.View?.Holder == null)
2025-09-05 19:46:30 +08:00
{
2025-12-24 20:44:36 +08:00
Log.Error("Cannot cache null UI metadata or holder");
2025-09-05 19:46:30 +08:00
return;
}
if (force || uiMetadata.MetaInfo.CacheTime == 0)
{
2026-04-24 09:21:37 +08:00
uiMetadata.DisposeImmediate();
2025-09-05 19:46:30 +08:00
return;
}
RemoveFromCache(uiMetadata.MetaInfo.TypeId);
2026-04-27 12:06:09 +08:00
ulong timerHandle = 0UL;
2025-09-05 19:46:30 +08:00
uiMetadata.View.Holder.transform.SetParent(UICacheLayer);
if (uiMetadata.MetaInfo.CacheTime > 0)
{
ITimerService timerService = GetTimerService();
2026-04-27 12:06:09 +08:00
timerHandle = timerService.AddTimer(
2025-12-24 20:44:36 +08:00
OnTimerDisposeWindow,
2026-03-24 17:45:15 +08:00
uiMetadata,
2025-12-24 20:44:36 +08:00
uiMetadata.MetaInfo.CacheTime,
isLoop: false,
isUnscaled: true);
2025-12-24 20:44:36 +08:00
2026-04-27 12:06:09 +08:00
if (timerHandle == 0UL)
2025-12-24 20:44:36 +08:00
{
Log.Warning(ZString.Format("Failed to create cache timer for {0}", uiMetadata.UILogicType.Name));
2025-12-24 20:44:36 +08:00
}
2025-09-05 19:46:30 +08:00
}
uiMetadata.InCache = true;
AddToCache(uiMetadata, timerHandle);
2025-09-05 19:46:30 +08:00
}
2026-03-24 17:45:15 +08:00
private void OnTimerDisposeWindow(UIMetadata meta)
2025-09-05 19:46:30 +08:00
{
2025-12-24 20:44:36 +08:00
if (meta != null)
{
RemoveFromCache(meta.MetaInfo.TypeId);
meta.DisposeImmediate();
2025-12-24 20:44:36 +08:00
}
2025-09-05 19:46:30 +08:00
}
2026-04-15 09:45:52 +08:00
private void RemoveFromCache(RuntimeTypeHandle typeHandle)
2025-09-05 19:46:30 +08:00
{
if (UIMetaRegistry.TryGet(typeHandle, out UIMetaRegistry.UIMetaInfo metaInfo))
2025-09-05 19:46:30 +08:00
{
RemoveFromCache(metaInfo.TypeId);
}
}
private void RemoveFromCache(int typeId)
{
if ((uint)typeId >= (uint)m_CacheTypeIdToIndex.Length)
{
return;
}
int index = m_CacheTypeIdToIndex[typeId];
if (index < 0 || index >= m_CacheWindowCount)
{
return;
}
CacheEntry entry = m_CacheWindow[index];
int lastIndex = m_CacheWindowCount - 1;
CacheEntry last = m_CacheWindow[lastIndex];
m_CacheWindow[index] = last;
m_CacheWindow[lastIndex] = default;
m_CacheWindowCount = lastIndex;
m_CacheTypeIdToIndex[typeId] = -1;
if (index != lastIndex && last.Metadata != null)
{
m_CacheTypeIdToIndex[last.Metadata.MetaInfo.TypeId] = index;
}
entry.Metadata.InCache = false;
if (entry.TimerHandle != 0UL && _timerService != null)
{
_timerService.RemoveTimer(entry.TimerHandle);
}
}
private void AddToCache(UIMetadata metadata, ulong timerHandle)
{
int typeId = metadata.MetaInfo.TypeId;
EnsureCacheIndexCapacity(typeId);
EnsureCacheCapacity();
int index = m_CacheWindowCount++;
m_CacheWindow[index] = new CacheEntry(metadata, timerHandle);
m_CacheTypeIdToIndex[typeId] = index;
}
private void EnsureCacheCapacity()
{
if (m_CacheWindowCount < m_CacheWindow.Length)
{
return;
}
Array.Resize(ref m_CacheWindow, m_CacheWindow.Length << 1);
}
private void EnsureCacheIndexCapacity(int typeId)
{
if ((uint)typeId < (uint)m_CacheTypeIdToIndex.Length)
{
return;
2025-09-05 19:46:30 +08:00
}
int oldLength = m_CacheTypeIdToIndex.Length;
int newLength = oldLength;
while (newLength <= typeId)
{
newLength <<= 1;
}
Array.Resize(ref m_CacheTypeIdToIndex, newLength);
for (int i = oldLength; i < newLength; i++)
{
m_CacheTypeIdToIndex[i] = -1;
}
}
private static int[] CreateCacheIndexArray(int capacity)
{
int[] values = new int[capacity];
for (int i = 0; i < values.Length; i++)
{
values[i] = -1;
}
return values;
2025-09-05 19:46:30 +08:00
}
private ITimerService GetTimerService()
{
if (_timerService != null)
{
return _timerService;
}
_timerService = AppServices.Require<ITimerService>();
return _timerService;
}
2025-09-05 19:46:30 +08:00
}
}