opt
1.取消令牌传递修改 2.资源分帧卸载
This commit is contained in:
parent
0045d5a7e1
commit
c202e21af0
@ -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>
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user