From da57ed845f01097c788730f199354a849e0b6d67 Mon Sep 17 00:00:00 2001
From: ALEXTANGXIAO <574809918@qq.com>
Date: Sun, 24 Mar 2024 15:58:57 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=90=8C=E6=97=B6=E5=AF=B9?=
=?UTF-8?q?=E4=B8=80=E4=B8=AA=E8=B5=84=E6=BA=90=E8=BF=9B=E8=A1=8C=E5=BC=82?=
=?UTF-8?q?=E6=AD=A5=E5=8A=A0=E8=BD=BD=E7=9A=84=E5=A4=84=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
修正同时对一个资源进行异步加载的处理
---
.../ResourceModule/IResourceManager.cs | 2 +-
.../Modules/ResourceModule/ResourceManager.cs | 59 ++++++++++++++++++-
2 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/IResourceManager.cs b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/IResourceManager.cs
index a9fe3d4d..93a3b2ff 100644
--- a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/IResourceManager.cs
+++ b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/IResourceManager.cs
@@ -230,7 +230,7 @@ namespace TEngine
/// 回调函数。
/// 指定资源包的名称。不传使用默认资源包
/// 要加载资源的类型。
- void LoadAsset(string location, Action callback, string packageName = "") where T : UnityEngine.Object;
+ UniTaskVoid LoadAsset(string location, Action callback, string packageName = "") where T : UnityEngine.Object;
///
/// 同步加载子资源对象。
diff --git a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceManager.cs b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceManager.cs
index f74d0c23..f4baadbe 100644
--- a/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceManager.cs
+++ b/UnityProject/Assets/TEngine/Runtime/Modules/ResourceModule/ResourceManager.cs
@@ -109,6 +109,10 @@ namespace TEngine
///
private readonly Dictionary _assetInfoMap = new Dictionary();
+ ///
+ /// 正在加载的资源列表。
+ ///
+ private readonly HashSet _assetLoadingList = new HashSet();
#endregion
///
@@ -134,6 +138,8 @@ namespace TEngine
DefaultPackage = defaultPackage;
}
+ CancellationToken = InstanceRoot.gameObject.GetCancellationTokenOnDestroy();
+
IObjectPoolManager objectPoolManager = ModuleImpSystem.GetModule();
SetObjectPoolManager(objectPoolManager);
}
@@ -253,7 +259,10 @@ namespace TEngine
internal override void Shutdown()
{
+ PackageMap.Clear();
m_AssetPool = null;
+ _assetLoadingList.Clear();
+ _assetInfoMap.Clear();
#if !UNITY_WEBGL
YooAssets.Destroy();
#endif
@@ -554,7 +563,7 @@ namespace TEngine
/// 回调函数。
/// 指定资源包的名称。不传使用默认资源包
/// 要加载资源的类型。
- public void LoadAsset(string location, Action callback, string packageName = "") where T : UnityEngine.Object
+ public async UniTaskVoid LoadAsset(string location, Action callback, string packageName = "") where T : UnityEngine.Object
{
if (string.IsNullOrEmpty(location))
{
@@ -568,6 +577,9 @@ namespace TEngine
}
string assetObjectKey = GetCacheKey(location, packageName);
+
+ await TryWaitingLoading(assetObjectKey);
+
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null)
{
@@ -575,10 +587,14 @@ namespace TEngine
return;
}
+ _assetLoadingList.Add(assetObjectKey);
+
AssetHandle handle = GetHandleAsync(location, packageName: packageName);
handle.Completed += assetHandle =>
{
+ _assetLoadingList.Remove(assetObjectKey);
+
if (assetHandle.AssetObject != null)
{
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
@@ -611,7 +627,7 @@ namespace TEngine
throw new NotImplementedException();
}
- public async UniTask LoadAssetAsync(string location, CancellationToken cancellationToken = default, string packageName = "") where T : UnityEngine.Object
+ public async UniTask LoadAssetAsync(string location, CancellationToken cancellationToken = default, string packageName = "") where T : UnityEngine.Object
{
if (string.IsNullOrEmpty(location))
{
@@ -619,11 +635,16 @@ namespace TEngine
}
string assetObjectKey = GetCacheKey(location, packageName);
+
+ await TryWaitingLoading(assetObjectKey);
+
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null)
{
return assetObject.Target as T;
}
+
+ _assetLoadingList.Add(assetObjectKey);
AssetHandle handle = GetHandleAsync(location, packageName: packageName);
@@ -636,6 +657,8 @@ namespace TEngine
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
m_AssetPool.Register(assetObject, true);
+
+ _assetLoadingList.Remove(assetObjectKey);
return handle.AssetObject as T;
}
@@ -649,12 +672,17 @@ namespace TEngine
}
string assetObjectKey = GetCacheKey(location, packageName);
+
+ await TryWaitingLoading(assetObjectKey);
+
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null)
{
return AssetsReference.Instantiate(assetObject.Target as GameObject, parent, this).gameObject;
}
+ _assetLoadingList.Add(assetObjectKey);
+
AssetHandle handle = GetHandleAsync(location, packageName: packageName);
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
@@ -669,6 +697,8 @@ namespace TEngine
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
m_AssetPool.Register(assetObject, true);
+ _assetLoadingList.Remove(assetObjectKey);
+
return gameObject;
}
@@ -696,6 +726,9 @@ namespace TEngine
}
string assetObjectKey = GetCacheKey(location, packageName);
+
+ await TryWaitingLoading(assetObjectKey);
+
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null)
{
@@ -703,6 +736,8 @@ namespace TEngine
return;
}
+ _assetLoadingList.Add(assetObjectKey);
+
AssetInfo assetInfo = GetAssetInfo(location, packageName);
if (!string.IsNullOrEmpty(assetInfo.Error))
@@ -730,6 +765,8 @@ namespace TEngine
if (handle.AssetObject == null || handle.Status == EOperationStatus.Failed)
{
+ _assetLoadingList.Remove(assetObjectKey);
+
string errorMessage = Utility.Text.Format("Can not load asset '{0}'.", location);
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
{
@@ -744,6 +781,8 @@ namespace TEngine
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
m_AssetPool.Register(assetObject, true);
+ _assetLoadingList.Remove(assetObjectKey);
+
if (loadAssetCallbacks.LoadAssetSuccessCallback != null)
{
duration = Time.time - duration;
@@ -774,12 +813,17 @@ namespace TEngine
}
string assetObjectKey = GetCacheKey(location, packageName);
+
+ await TryWaitingLoading(assetObjectKey);
+
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null)
{
loadAssetCallbacks.LoadAssetSuccessCallback(location, assetObject.Target, 0, userData);
return;
}
+
+ _assetLoadingList.Add(assetObjectKey);
AssetInfo assetInfo = GetAssetInfo(location, packageName);
@@ -808,6 +852,8 @@ namespace TEngine
if (handle.AssetObject == null || handle.Status == EOperationStatus.Failed)
{
+ _assetLoadingList.Remove(assetObjectKey);
+
string errorMessage = Utility.Text.Format("Can not load asset '{0}'.", location);
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
{
@@ -821,6 +867,8 @@ namespace TEngine
{
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
m_AssetPool.Register(assetObject, true);
+
+ _assetLoadingList.Remove(assetObjectKey);
if (loadAssetCallbacks.LoadAssetSuccessCallback != null)
{
@@ -849,6 +897,13 @@ namespace TEngine
}
}
+ private async UniTask TryWaitingLoading(string assetObjectKey)
+ {
+ if (_assetLoadingList.Contains(assetObjectKey))
+ {
+ await UniTask.WaitUntil(() => !_assetLoadingList.Contains(assetObjectKey), cancellationToken:CancellationToken);
+ }
+ }
#endregion
#region 资源回收