com.alicizax.unity.framework/Runtime/Resource/Resource/Extension/ResourceExtComponent.cs
2025-11-05 19:31:37 +08:00

151 lines
4.5 KiB
C#

using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using AlicizaX.ObjectPool;
using AlicizaX.Resource.Runtime;
using AlicizaX;
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 : MonoBehaviour
{
public static ResourceExtComponent Instance { private set; get; }
private readonly TimeoutController _timeoutController = new TimeoutController();
/// <summary>
/// 正在加载的资源列表。
/// </summary>
private readonly HashSet<string> _assetLoadingList = new HashSet<string>();
/// <summary>
/// 检查是否可以释放间隔
/// </summary>
[SerializeField] private float m_CheckCanReleaseInterval = 30f;
private float m_CheckCanReleaseTime = 0.0f;
/// <summary>
/// 对象池自动释放时间间隔
/// </summary>
[SerializeField] private float m_AutoReleaseInterval = 60f;
/// <summary>
/// 保存加载的图片对象
/// </summary>
#if ODIN_INSPECTOR
[ShowInInspector]
#endif
private LinkedList<LoadAssetObject> m_LoadAssetObjectsLinkedList;
/// <summary>
/// 散图集合对象池
/// </summary>
private IObjectPool<AssetItemObject> _assetItemPool;
#if UNITY_EDITOR
public LinkedList<LoadAssetObject> LoadAssetObjectsLinkedList
{
get => m_LoadAssetObjectsLinkedList;
set => m_LoadAssetObjectsLinkedList = value;
}
#endif
private void Awake()
{
Instance = this;
}
private IEnumerator Start()
{
yield return new WaitForEndOfFrame();
IObjectPoolModule objectPoolComponent = ModuleSystem.GetModule<IObjectPoolModule>();
_assetItemPool = objectPoolComponent.CreateMultiSpawnObjectPool<AssetItemObject>(
"SetAssetPool",
m_AutoReleaseInterval, 16, 60, 0);
m_LoadAssetObjectsLinkedList = new LinkedList<LoadAssetObject>();
InitializedResources();
}
private void Update()
{
m_CheckCanReleaseTime += Time.unscaledDeltaTime;
if (m_CheckCanReleaseTime < (double)m_CheckCanReleaseInterval)
{
return;
}
ReleaseUnused();
}
/// <summary>
/// 回收无引用的缓存资产。
/// </summary>
#if ODIN_INSPECTOR
[Button("Release Unused")]
#endif
public void ReleaseUnused()
{
if (m_LoadAssetObjectsLinkedList == null)
{
return;
}
LinkedListNode<LoadAssetObject> current = m_LoadAssetObjectsLinkedList.First;
while (current != null)
{
var next = current.Next;
if (current.Value.AssetObject.IsCanRelease())
{
_assetItemPool.Unspawn(current.Value.AssetTarget);
MemoryPool.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}");
}
}
}
}
}
}