修正同时对一个图片进行异步SetSprite的处理

修正同时对一个图片进行异步SetSprite的处理
This commit is contained in:
ALEXTANG
2024-04-07 15:45:32 +08:00
parent d5bb64b314
commit 7ae6ef94ba
3 changed files with 47 additions and 4 deletions

View File

@@ -12,7 +12,7 @@ public static class SetSpriteExtensions
/// <param name="setNativeSize">是否使用原始分辨率。</param> /// <param name="setNativeSize">是否使用原始分辨率。</param>
public static void SetSprite(this Image image, string location, bool setNativeSize = false) public static void SetSprite(this Image image, string location, bool setNativeSize = false)
{ {
GameModule.ResourceExt.SetAssetByResources<Sprite>(SetSpriteObject.Create(image, location, setNativeSize)); GameModule.ResourceExt.SetAssetByResources<Sprite>(SetSpriteObject.Create(image, location, setNativeSize)).Forget();
} }
/// <summary> /// <summary>
@@ -22,6 +22,6 @@ public static class SetSpriteExtensions
/// <param name="location">资源定位地址。</param> /// <param name="location">资源定位地址。</param>
public static void SetSprite(this SpriteRenderer spriteRenderer, string location) public static void SetSprite(this SpriteRenderer spriteRenderer, string location)
{ {
GameModule.ResourceExt.SetAssetByResources<Sprite>(SetSpriteObject.Create(spriteRenderer, location)); GameModule.ResourceExt.SetAssetByResources<Sprite>(SetSpriteObject.Create(spriteRenderer, location)).Forget();
} }
} }

View File

@@ -1,3 +1,5 @@
using Cysharp.Threading.Tasks;
namespace TEngine namespace TEngine
{ {
public partial class ResourceExtComponent public partial class ResourceExtComponent
@@ -17,11 +19,13 @@ namespace TEngine
private void OnLoadAssetFailure(string assetName, LoadResourceStatus status, string errormessage, object userdata) private void OnLoadAssetFailure(string assetName, LoadResourceStatus status, string errormessage, object userdata)
{ {
_assetLoadingList.Remove(assetName);
Log.Error("Can not load asset from '{1}' with error message '{2}'.", assetName, errormessage); Log.Error("Can not load asset from '{1}' with error message '{2}'.", assetName, errormessage);
} }
private void OnLoadAssetSuccess(string assetName, object asset, float duration, object userdata) private void OnLoadAssetSuccess(string assetName, object asset, float duration, object userdata)
{ {
_assetLoadingList.Remove(assetName);
ISetAssetObject setAssetObject = (ISetAssetObject)userdata; ISetAssetObject setAssetObject = (ISetAssetObject)userdata;
UnityEngine.Object assetObject = asset as UnityEngine.Object; UnityEngine.Object assetObject = asset as UnityEngine.Object;
if (assetObject != null) if (assetObject != null)
@@ -39,8 +43,10 @@ namespace TEngine
/// 通过资源系统设置资源。 /// 通过资源系统设置资源。
/// </summary> /// </summary>
/// <param name="setAssetObject">需要设置的对象。</param> /// <param name="setAssetObject">需要设置的对象。</param>
public void SetAssetByResources<T>(ISetAssetObject setAssetObject) where T : UnityEngine.Object public async UniTaskVoid SetAssetByResources<T>(ISetAssetObject setAssetObject) where T : UnityEngine.Object
{ {
await TryWaitingLoading(setAssetObject.Location);
if (m_AssetItemPool.CanSpawn(setAssetObject.Location)) if (m_AssetItemPool.CanSpawn(setAssetObject.Location))
{ {
var assetObject = (T)m_AssetItemPool.Spawn(setAssetObject.Location).Target; var assetObject = (T)m_AssetItemPool.Spawn(setAssetObject.Location).Target;
@@ -48,6 +54,7 @@ namespace TEngine
} }
else else
{ {
_assetLoadingList.Add(setAssetObject.Location);
m_ResourceModule.LoadAssetAsync(setAssetObject.Location, typeof(T), m_LoadAssetCallbacks, setAssetObject); m_ResourceModule.LoadAssetAsync(setAssetObject.Location, typeof(T), m_LoadAssetCallbacks, setAssetObject);
} }
} }

View File

@@ -1,6 +1,9 @@
using System.Collections; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine; using UnityEngine;
using Object = UnityEngine.Object;
#if ODIN_INSPECTOR #if ODIN_INSPECTOR
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
#endif #endif
@@ -13,6 +16,13 @@ namespace TEngine
[DisallowMultipleComponent] [DisallowMultipleComponent]
public partial class ResourceExtComponent : Module public partial class ResourceExtComponent : Module
{ {
private readonly TimeoutController _timeoutController = new TimeoutController();
/// <summary>
/// 正在加载的资源列表。
/// </summary>
private readonly HashSet<string> _assetLoadingList = new HashSet<string>();
/// <summary> /// <summary>
/// 检查是否可以释放间隔 /// 检查是否可以释放间隔
/// </summary> /// </summary>
@@ -104,5 +114,31 @@ namespace TEngine
m_LoadAssetObjectsLinkedList.AddLast(new LoadAssetObject(setAssetObject, assetObject)); m_LoadAssetObjectsLinkedList.AddLast(new LoadAssetObject(setAssetObject, assetObject));
setAssetObject.SetAsset(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}");
}
}
}
}
} }
} }