using System; using AlicizaX; using UnityEngine; using YooAsset; namespace AlicizaX.Audio.Runtime { internal sealed class AudioClipCacheEntry : IMemory { private readonly Action _completedCallback; public AudioService Owner; public string Address; public AssetHandle Handle; public AudioClip Clip; public AudioLoadRequest PendingHead; public AudioLoadRequest PendingTail; public AudioClipCacheEntry LruPrev; public AudioClipCacheEntry LruNext; public AudioClipCacheEntry AllPrev; public AudioClipCacheEntry AllNext; public int RefCount; public bool Loading; public bool Pinned; public bool CacheAfterUse; public bool InLru; public float LastUseTime; public AudioClipCacheEntry() { _completedCallback = OnLoadCompleted; } public Action CompletedCallback => _completedCallback; public bool IsLoaded => Clip != null && Handle is { IsValid: true } && !Loading; public void Initialize(AudioService owner, string address, bool pinned) { Owner = owner; Address = address; Pinned = pinned; CacheAfterUse = pinned; LastUseTime = Time.realtimeSinceStartup; } public void AddPending(AudioLoadRequest request) { request.Next = null; if (PendingTail == null) { PendingHead = request; PendingTail = request; return; } PendingTail.Next = request; PendingTail = request; } public int CountPending() { int count = 0; AudioLoadRequest request = PendingHead; while (request != null) { count++; request = request.Next; } return count; } public void FillDebugInfo(AudioClipCacheDebugInfo info) { if (info == null) { return; } info.Address = Address; info.Clip = Clip; info.RefCount = RefCount; info.PendingCount = CountPending(); info.Loading = Loading; info.Pinned = Pinned; info.CacheAfterUse = CacheAfterUse; info.InLru = InLru; info.IsLoaded = IsLoaded; info.HasValidHandle = Handle is { IsValid: true }; info.LastUseTime = LastUseTime; } public void Clear() { if (Handle is { IsValid: true }) { if (Loading) { Handle.Completed -= _completedCallback; } Handle.Dispose(); } AudioLoadRequest request = PendingHead; while (request != null) { AudioLoadRequest next = request.Next; MemoryPool.Release(request); request = next; } Owner = null; Address = null; Handle = null; Clip = null; PendingHead = null; PendingTail = null; LruPrev = null; LruNext = null; AllPrev = null; AllNext = null; RefCount = 0; Loading = false; Pinned = false; CacheAfterUse = false; InLru = false; LastUseTime = 0f; } private void OnLoadCompleted(AssetHandle handle) { AudioService owner = Owner; if (owner != null) { owner.OnClipLoadCompleted(this, handle); } else if (handle is { IsValid: true }) { handle.Dispose(); } } } }