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 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(); return _timerService; } } }