1.取消令牌传递修改
2.资源分帧卸载
This commit is contained in:
陈思海 2025-12-09 13:52:52 +08:00
parent 0045d5a7e1
commit c202e21af0
3 changed files with 80 additions and 43 deletions

View File

@ -15,7 +15,7 @@ public static class SetSpriteExtensions
/// <param name="cancellationToken">取消设置资源的Token。</param>
public static void SetSprite(this Image image, string location, bool setNativeSize = false, CancellationToken cancellationToken = default)
{
ResourceExtComponent.Instance.SetAssetByResources<Sprite>(SetSpriteObject.Create(image, location, setNativeSize, cancellationToken)).Forget();
ResourceExtComponent.Instance.SetAssetByResources<Sprite>(SetSpriteObject.Create(image, location, setNativeSize), cancellationToken).Forget();
}
/// <summary>
@ -26,7 +26,7 @@ public static class SetSpriteExtensions
/// <param name="cancellationToken">取消设置资源的Token。</param>
public static void SetSprite(this SpriteRenderer spriteRenderer, string location, CancellationToken cancellationToken = default)
{
ResourceExtComponent.Instance.SetAssetByResources<Sprite>(SetSpriteObject.Create(spriteRenderer, location, cancellationToken)).Forget();
ResourceExtComponent.Instance.SetAssetByResources<Sprite>(SetSpriteObject.Create(spriteRenderer, location), cancellationToken).Forget();
}
/// <summary>

View File

@ -83,7 +83,7 @@ namespace AlicizaX.Resource.Runtime
/// </summary>
/// <param name="setAssetObject">ISetAssetObject。</param>
/// <typeparam name="T">Unity对象类型。</typeparam>
public async UniTaskVoid SetAssetByResources<T>(ISetAssetObject setAssetObject) where T : UnityEngine.Object
public async UniTaskVoid SetAssetByResources<T>(ISetAssetObject setAssetObject,CancellationToken cancellationToken) where T : UnityEngine.Object
{
var target = setAssetObject.TargetObject;
var location = setAssetObject.Location;
@ -97,16 +97,16 @@ namespace AlicizaX.Resource.Runtime
CancelAndCleanupOldRequest(target);
// 创建新的加载状态
var cts = new CancellationTokenSource();
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
var loadingState = MemoryPool.Acquire<LoadingState>();
loadingState.Cts = cts;
loadingState.Cts = linkedTokenSource;
loadingState.Location = location;
_loadingStates[target] = loadingState;
try
{
// 等待其他可能正在进行的加载。
await TryWaitingLoading(location).AttachExternalCancellation(cts.Token);
await TryWaitingLoading(location).AttachExternalCancellation(linkedTokenSource.Token);
// 再次检查是否被新请求替换。
if (!IsCurrentLocation(target, location))
@ -137,7 +137,13 @@ namespace AlicizaX.Resource.Runtime
return;
}
_resourceModule.LoadAssetAsync(location, typeof(T), 0, _loadAssetCallbacks, setAssetObject);
T resource = await _resourceModule.LoadAssetAsync<T>(location, linkedTokenSource.Token);
if (resource != null)
{
_loadAssetCallbacks?.LoadAssetSuccessCallback.Invoke(location,resource, 0f, setAssetObject);
}
_assetLoadingList.Remove(location);
}
}
catch (OperationCanceledException)

View File

@ -1,19 +1,22 @@
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 UnityEngine.Serialization;
using Object = UnityEngine.Object;
namespace AlicizaX.Resource.Runtime
{
/// <summary>
/// 资源组件拓展。
/// </summary>
[DisallowMultipleComponent]
public partial class ResourceExtComponent : MonoBehaviour
{
public static ResourceExtComponent Instance { private set; get; }
private readonly TimeoutController _timeoutController = new TimeoutController();
/// <summary>
@ -22,25 +25,37 @@ namespace AlicizaX.Resource.Runtime
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>
[SerializeField]
private LinkedList<LoadAssetObject> m_LoadAssetObjectsLinkedList;
private float checkCanReleaseInterval = 30f;
private float _checkCanReleaseTime = 0.0f;
/// <summary>
/// 散图集合对象池
/// 对象池自动释放时间间隔。
/// </summary>
[SerializeField]
private float autoReleaseInterval = 60f;
/// <summary>
/// 每帧最大处理资源数量,用于分帧处理避免卡顿。
/// </summary>
[SerializeField]
private int maxProcessPerFrame = 50;
/// <summary>
/// 当前正在处理的节点,用于分帧处理。
/// </summary>
private LinkedListNode<LoadAssetObject> _currentProcessNode;
/// <summary>
/// 保存加载的图片对象。
/// </summary>
private LinkedList<LoadAssetObject> _loadAssetObjectsLinkedList;
/// <summary>
/// 散图集合对象池。
/// </summary>
private IObjectPool<AssetItemObject> _assetItemPool;
@ -48,31 +63,27 @@ namespace AlicizaX.Resource.Runtime
#if UNITY_EDITOR
public LinkedList<LoadAssetObject> LoadAssetObjectsLinkedList
{
get => m_LoadAssetObjectsLinkedList;
set => m_LoadAssetObjectsLinkedList = value;
get => _loadAssetObjectsLinkedList;
set => _loadAssetObjectsLinkedList = value;
}
#endif
private void Awake()
{
Instance = this;
}
private IEnumerator Start()
{
Instance = this;
yield return new WaitForEndOfFrame();
IObjectPoolModule objectPoolComponent = ModuleSystem.GetModule<IObjectPoolModule>();
_assetItemPool = objectPoolComponent.CreateMultiSpawnObjectPool<AssetItemObject>(
"SetAssetPool",
m_AutoReleaseInterval, 16, 60, 0);
m_LoadAssetObjectsLinkedList = new LinkedList<LoadAssetObject>();
autoReleaseInterval, 16, 60, 0);
_loadAssetObjectsLinkedList = new LinkedList<LoadAssetObject>();
InitializedResources();
}
private void Update()
{
m_CheckCanReleaseTime += Time.unscaledDeltaTime;
if (m_CheckCanReleaseTime < (double)m_CheckCanReleaseInterval)
_checkCanReleaseTime += Time.unscaledDeltaTime;
if (_checkCanReleaseTime < (double)checkCanReleaseInterval)
{
return;
}
@ -80,37 +91,57 @@ namespace AlicizaX.Resource.Runtime
ReleaseUnused();
}
/// <summary>
/// 回收无引用的缓存资产。
/// 使用分帧处理优化性能,避免一次性处理大量资源导致卡顿。
/// </summary>
public void ReleaseUnused()
{
if (m_LoadAssetObjectsLinkedList == null)
if (_loadAssetObjectsLinkedList == null || _loadAssetObjectsLinkedList.Count == 0)
{
_currentProcessNode = null;
_checkCanReleaseTime = 0f;
return;
}
LinkedListNode<LoadAssetObject> current = m_LoadAssetObjectsLinkedList.First;
while (current != null)
// 如果当前没有正在处理的节点,从头开始
if (_currentProcessNode == null)
{
_currentProcessNode = _loadAssetObjectsLinkedList.First;
}
int processedCount = 0;
LinkedListNode<LoadAssetObject> current = _currentProcessNode;
// 分帧处理:每帧最多处理 maxProcessPerFrame 个资源
while (current != null && processedCount < maxProcessPerFrame)
{
var next = current.Next;
if (current.Value.AssetObject.IsCanRelease())
{
_assetItemPool.Unspawn(current.Value.AssetTarget);
MemoryPool.Release(current.Value.AssetObject);
m_LoadAssetObjectsLinkedList.Remove(current);
_loadAssetObjectsLinkedList.Remove(current);
}
current = next;
processedCount++;
}
m_CheckCanReleaseTime = 0f;
// 更新当前处理节点
_currentProcessNode = current;
// 如果已经处理完所有节点,重置状态
if (_currentProcessNode == null)
{
_checkCanReleaseTime = 0f;
}
}
private void SetAsset(ISetAssetObject setAssetObject, Object assetObject)
{
m_LoadAssetObjectsLinkedList.AddLast(new LoadAssetObject(setAssetObject, assetObject));
_loadAssetObjectsLinkedList.AddLast(new LoadAssetObject(setAssetObject, assetObject));
setAssetObject.SetAsset(assetObject);
}