using System; using System.Buffers; using System.Collections; using System.Collections.Generic; using AlicizaX.ObjectPool; using AlicizaX.Resource.Runtime; using AlicizaX.Runtime; using Cysharp.Threading.Tasks; using UnityEngine; using Object = UnityEngine.Object; #if ODIN_INSPECTOR using Sirenix.OdinInspector; #endif namespace AlicizaX.Resource.Runtime { public partial class ResourceExtComponent : GameFrameworkComponent { private readonly TimeoutController _timeoutController = new TimeoutController(); /// /// 正在加载的资源列表。 /// private readonly HashSet _assetLoadingList = new HashSet(); /// /// 检查是否可以释放间隔 /// [SerializeField] private float m_CheckCanReleaseInterval = 30f; private float m_CheckCanReleaseTime = 0.0f; /// /// 对象池自动释放时间间隔 /// [SerializeField] private float m_AutoReleaseInterval = 60f; /// /// 保存加载的图片对象 /// #if ODIN_INSPECTOR [ShowInInspector] #endif private LinkedList m_LoadAssetObjectsLinkedList; /// /// 散图集合对象池 /// private IObjectPool m_AssetItemPool; #if UNITY_EDITOR public LinkedList LoadAssetObjectsLinkedList { get => m_LoadAssetObjectsLinkedList; set => m_LoadAssetObjectsLinkedList = value; } #endif protected override void Awake() { IsAutoRegister = false; base.Awake(); } private IEnumerator Start() { yield return new WaitForEndOfFrame(); IObjectPoolManager objectPoolComponent = SysModuleCenter.GetModule(); m_AssetItemPool = objectPoolComponent.CreateMultiSpawnObjectPool( "SetAssetPool", m_AutoReleaseInterval, 16, 60, 0); m_LoadAssetObjectsLinkedList = new LinkedList(); InitializedResources(); } private void Update() { m_CheckCanReleaseTime += Time.unscaledDeltaTime; if (m_CheckCanReleaseTime < (double)m_CheckCanReleaseInterval) { return; } ReleaseUnused(); } /// /// 回收无引用的缓存资产。 /// #if ODIN_INSPECTOR [Button("Release Unused")] #endif public void ReleaseUnused() { if (m_LoadAssetObjectsLinkedList == null) { return; } LinkedListNode current = m_LoadAssetObjectsLinkedList.First; while (current != null) { var next = current.Next; if (current.Value.AssetObject.IsCanRelease()) { m_AssetItemPool.Unspawn(current.Value.AssetTarget); ReferencePool.Release(current.Value.AssetObject); m_LoadAssetObjectsLinkedList.Remove(current); } current = next; } m_CheckCanReleaseTime = 0f; } private void SetAsset(ISetAssetObject setAssetObject, Object assetObject) { m_LoadAssetObjectsLinkedList.AddLast(new LoadAssetObject(setAssetObject, assetObject)); setAssetObject.SetAsset(assetObject); } private async UniTask TryWaitingLoading(string assetObjectKey) { if (_assetLoadingList.Contains(assetObjectKey)) { try { await UniTask.WaitUntil( () => !_assetLoadingList.Contains(assetObjectKey)) #if UNITY_EDITOR .AttachExternalCancellation(_timeoutController.Timeout(TimeSpan.FromSeconds(60))); _timeoutController.Reset(); #else ; #endif } catch (OperationCanceledException ex) { if (_timeoutController.IsTimeout()) { Log.Error($"LoadAssetAsync Waiting {assetObjectKey} timeout. reason:{ex.Message}"); } } } } } }