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>
|
/// <param name="cancellationToken">取消设置资源的Token。</param>
|
||||||
public static void SetSprite(this Image image, string location, bool setNativeSize = false, CancellationToken cancellationToken = default)
|
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>
|
/// <summary>
|
||||||
@ -26,7 +26,7 @@ public static class SetSpriteExtensions
|
|||||||
/// <param name="cancellationToken">取消设置资源的Token。</param>
|
/// <param name="cancellationToken">取消设置资源的Token。</param>
|
||||||
public static void SetSprite(this SpriteRenderer spriteRenderer, string location, CancellationToken cancellationToken = default)
|
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>
|
/// <summary>
|
||||||
|
|||||||
@ -83,7 +83,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setAssetObject">ISetAssetObject。</param>
|
/// <param name="setAssetObject">ISetAssetObject。</param>
|
||||||
/// <typeparam name="T">Unity对象类型。</typeparam>
|
/// <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 target = setAssetObject.TargetObject;
|
||||||
var location = setAssetObject.Location;
|
var location = setAssetObject.Location;
|
||||||
@ -97,16 +97,16 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
CancelAndCleanupOldRequest(target);
|
CancelAndCleanupOldRequest(target);
|
||||||
|
|
||||||
// 创建新的加载状态
|
// 创建新的加载状态
|
||||||
var cts = new CancellationTokenSource();
|
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||||
var loadingState = MemoryPool.Acquire<LoadingState>();
|
var loadingState = MemoryPool.Acquire<LoadingState>();
|
||||||
loadingState.Cts = cts;
|
loadingState.Cts = linkedTokenSource;
|
||||||
loadingState.Location = location;
|
loadingState.Location = location;
|
||||||
_loadingStates[target] = loadingState;
|
_loadingStates[target] = loadingState;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 等待其他可能正在进行的加载。
|
// 等待其他可能正在进行的加载。
|
||||||
await TryWaitingLoading(location).AttachExternalCancellation(cts.Token);
|
await TryWaitingLoading(location).AttachExternalCancellation(linkedTokenSource.Token);
|
||||||
|
|
||||||
// 再次检查是否被新请求替换。
|
// 再次检查是否被新请求替换。
|
||||||
if (!IsCurrentLocation(target, location))
|
if (!IsCurrentLocation(target, location))
|
||||||
@ -137,7 +137,13 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
return;
|
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)
|
catch (OperationCanceledException)
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using AlicizaX.ObjectPool;
|
using AlicizaX.ObjectPool;
|
||||||
using AlicizaX.Resource.Runtime;
|
|
||||||
using AlicizaX;
|
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace AlicizaX.Resource.Runtime
|
namespace AlicizaX.Resource.Runtime
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 资源组件拓展。
|
||||||
|
/// </summary>
|
||||||
|
[DisallowMultipleComponent]
|
||||||
public partial class ResourceExtComponent : MonoBehaviour
|
public partial class ResourceExtComponent : MonoBehaviour
|
||||||
{
|
{
|
||||||
public static ResourceExtComponent Instance { private set; get; }
|
public static ResourceExtComponent Instance { private set; get; }
|
||||||
|
|
||||||
private readonly TimeoutController _timeoutController = new TimeoutController();
|
private readonly TimeoutController _timeoutController = new TimeoutController();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -22,25 +25,37 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
private readonly HashSet<string> _assetLoadingList = new HashSet<string>();
|
private readonly HashSet<string> _assetLoadingList = new HashSet<string>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检查是否可以释放间隔
|
/// 检查是否可以释放间隔。
|
||||||
/// </summary>
|
|
||||||
[SerializeField] private float m_CheckCanReleaseInterval = 30f;
|
|
||||||
|
|
||||||
private float m_CheckCanReleaseTime = 0.0f;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 对象池自动释放时间间隔
|
|
||||||
/// </summary>
|
|
||||||
[SerializeField] private float m_AutoReleaseInterval = 60f;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 保存加载的图片对象
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private LinkedList<LoadAssetObject> m_LoadAssetObjectsLinkedList;
|
private float checkCanReleaseInterval = 30f;
|
||||||
|
|
||||||
|
private float _checkCanReleaseTime = 0.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
private IObjectPool<AssetItemObject> _assetItemPool;
|
private IObjectPool<AssetItemObject> _assetItemPool;
|
||||||
|
|
||||||
@ -48,31 +63,27 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
public LinkedList<LoadAssetObject> LoadAssetObjectsLinkedList
|
public LinkedList<LoadAssetObject> LoadAssetObjectsLinkedList
|
||||||
{
|
{
|
||||||
get => m_LoadAssetObjectsLinkedList;
|
get => _loadAssetObjectsLinkedList;
|
||||||
set => m_LoadAssetObjectsLinkedList = value;
|
set => _loadAssetObjectsLinkedList = value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
private void Awake()
|
|
||||||
{
|
|
||||||
Instance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator Start()
|
private IEnumerator Start()
|
||||||
{
|
{
|
||||||
|
Instance = this;
|
||||||
yield return new WaitForEndOfFrame();
|
yield return new WaitForEndOfFrame();
|
||||||
IObjectPoolModule objectPoolComponent = ModuleSystem.GetModule<IObjectPoolModule>();
|
IObjectPoolModule objectPoolComponent = ModuleSystem.GetModule<IObjectPoolModule>();
|
||||||
_assetItemPool = objectPoolComponent.CreateMultiSpawnObjectPool<AssetItemObject>(
|
_assetItemPool = objectPoolComponent.CreateMultiSpawnObjectPool<AssetItemObject>(
|
||||||
"SetAssetPool",
|
"SetAssetPool",
|
||||||
m_AutoReleaseInterval, 16, 60, 0);
|
autoReleaseInterval, 16, 60, 0);
|
||||||
m_LoadAssetObjectsLinkedList = new LinkedList<LoadAssetObject>();
|
_loadAssetObjectsLinkedList = new LinkedList<LoadAssetObject>();
|
||||||
|
|
||||||
InitializedResources();
|
InitializedResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
m_CheckCanReleaseTime += Time.unscaledDeltaTime;
|
_checkCanReleaseTime += Time.unscaledDeltaTime;
|
||||||
if (m_CheckCanReleaseTime < (double)m_CheckCanReleaseInterval)
|
if (_checkCanReleaseTime < (double)checkCanReleaseInterval)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -80,37 +91,57 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
ReleaseUnused();
|
ReleaseUnused();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 回收无引用的缓存资产。
|
/// 回收无引用的缓存资产。
|
||||||
|
/// 使用分帧处理优化性能,避免一次性处理大量资源导致卡顿。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ReleaseUnused()
|
public void ReleaseUnused()
|
||||||
{
|
{
|
||||||
if (m_LoadAssetObjectsLinkedList == null)
|
if (_loadAssetObjectsLinkedList == null || _loadAssetObjectsLinkedList.Count == 0)
|
||||||
{
|
{
|
||||||
|
_currentProcessNode = null;
|
||||||
|
_checkCanReleaseTime = 0f;
|
||||||
return;
|
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;
|
var next = current.Next;
|
||||||
|
|
||||||
if (current.Value.AssetObject.IsCanRelease())
|
if (current.Value.AssetObject.IsCanRelease())
|
||||||
{
|
{
|
||||||
_assetItemPool.Unspawn(current.Value.AssetTarget);
|
_assetItemPool.Unspawn(current.Value.AssetTarget);
|
||||||
MemoryPool.Release(current.Value.AssetObject);
|
MemoryPool.Release(current.Value.AssetObject);
|
||||||
m_LoadAssetObjectsLinkedList.Remove(current);
|
_loadAssetObjectsLinkedList.Remove(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
current = next;
|
current = next;
|
||||||
|
processedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CheckCanReleaseTime = 0f;
|
// 更新当前处理节点
|
||||||
|
_currentProcessNode = current;
|
||||||
|
|
||||||
|
// 如果已经处理完所有节点,重置状态
|
||||||
|
if (_currentProcessNode == null)
|
||||||
|
{
|
||||||
|
_checkCanReleaseTime = 0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetAsset(ISetAssetObject setAssetObject, Object assetObject)
|
private void SetAsset(ISetAssetObject setAssetObject, Object assetObject)
|
||||||
{
|
{
|
||||||
m_LoadAssetObjectsLinkedList.AddLast(new LoadAssetObject(setAssetObject, assetObject));
|
_loadAssetObjectsLinkedList.AddLast(new LoadAssetObject(setAssetObject, assetObject));
|
||||||
setAssetObject.SetAsset(assetObject);
|
setAssetObject.SetAsset(assetObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user