修正同时对一个资源进行异步加载的处理

修正同时对一个资源进行异步加载的处理
This commit is contained in:
ALEXTANGXIAO
2024-03-24 15:58:57 +08:00
parent df570f453a
commit da57ed845f
2 changed files with 58 additions and 3 deletions

View File

@@ -230,7 +230,7 @@ namespace TEngine
/// <param name="callback">回调函数。</param> /// <param name="callback">回调函数。</param>
/// <param name="packageName">指定资源包的名称。不传使用默认资源包</param> /// <param name="packageName">指定资源包的名称。不传使用默认资源包</param>
/// <typeparam name="T">要加载资源的类型。</typeparam> /// <typeparam name="T">要加载资源的类型。</typeparam>
void LoadAsset<T>(string location, Action<T> callback, string packageName = "") where T : UnityEngine.Object; UniTaskVoid LoadAsset<T>(string location, Action<T> callback, string packageName = "") where T : UnityEngine.Object;
/// <summary> /// <summary>
/// 同步加载子资源对象。 /// 同步加载子资源对象。

View File

@@ -109,6 +109,10 @@ namespace TEngine
/// </summary> /// </summary>
private readonly Dictionary<string, AssetInfo> _assetInfoMap = new Dictionary<string, AssetInfo>(); private readonly Dictionary<string, AssetInfo> _assetInfoMap = new Dictionary<string, AssetInfo>();
/// <summary>
/// 正在加载的资源列表。
/// </summary>
private readonly HashSet<string> _assetLoadingList = new HashSet<string>();
#endregion #endregion
/// <summary> /// <summary>
@@ -134,6 +138,8 @@ namespace TEngine
DefaultPackage = defaultPackage; DefaultPackage = defaultPackage;
} }
CancellationToken = InstanceRoot.gameObject.GetCancellationTokenOnDestroy();
IObjectPoolManager objectPoolManager = ModuleImpSystem.GetModule<IObjectPoolManager>(); IObjectPoolManager objectPoolManager = ModuleImpSystem.GetModule<IObjectPoolManager>();
SetObjectPoolManager(objectPoolManager); SetObjectPoolManager(objectPoolManager);
} }
@@ -253,7 +259,10 @@ namespace TEngine
internal override void Shutdown() internal override void Shutdown()
{ {
PackageMap.Clear();
m_AssetPool = null; m_AssetPool = null;
_assetLoadingList.Clear();
_assetInfoMap.Clear();
#if !UNITY_WEBGL #if !UNITY_WEBGL
YooAssets.Destroy(); YooAssets.Destroy();
#endif #endif
@@ -554,7 +563,7 @@ namespace TEngine
/// <param name="callback">回调函数。</param> /// <param name="callback">回调函数。</param>
/// <param name="packageName">指定资源包的名称。不传使用默认资源包</param> /// <param name="packageName">指定资源包的名称。不传使用默认资源包</param>
/// <typeparam name="T">要加载资源的类型。</typeparam> /// <typeparam name="T">要加载资源的类型。</typeparam>
public void LoadAsset<T>(string location, Action<T> callback, string packageName = "") where T : UnityEngine.Object public async UniTaskVoid LoadAsset<T>(string location, Action<T> callback, string packageName = "") where T : UnityEngine.Object
{ {
if (string.IsNullOrEmpty(location)) if (string.IsNullOrEmpty(location))
{ {
@@ -568,6 +577,9 @@ namespace TEngine
} }
string assetObjectKey = GetCacheKey(location, packageName); string assetObjectKey = GetCacheKey(location, packageName);
await TryWaitingLoading(assetObjectKey);
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey); AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null) if (assetObject != null)
{ {
@@ -575,10 +587,14 @@ namespace TEngine
return; return;
} }
_assetLoadingList.Add(assetObjectKey);
AssetHandle handle = GetHandleAsync<T>(location, packageName: packageName); AssetHandle handle = GetHandleAsync<T>(location, packageName: packageName);
handle.Completed += assetHandle => handle.Completed += assetHandle =>
{ {
_assetLoadingList.Remove(assetObjectKey);
if (assetHandle.AssetObject != null) if (assetHandle.AssetObject != null)
{ {
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this); assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
@@ -611,7 +627,7 @@ namespace TEngine
throw new NotImplementedException(); throw new NotImplementedException();
} }
public async UniTask<T> LoadAssetAsync<T>(string location, CancellationToken cancellationToken = default, string packageName = "") where T : UnityEngine.Object public async UniTask<T> LoadAssetAsync<T>(string location, CancellationToken cancellationToken = default, string packageName = "") where T : UnityEngine.Object
{ {
if (string.IsNullOrEmpty(location)) if (string.IsNullOrEmpty(location))
{ {
@@ -619,11 +635,16 @@ namespace TEngine
} }
string assetObjectKey = GetCacheKey(location, packageName); string assetObjectKey = GetCacheKey(location, packageName);
await TryWaitingLoading(assetObjectKey);
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey); AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null) if (assetObject != null)
{ {
return assetObject.Target as T; return assetObject.Target as T;
} }
_assetLoadingList.Add(assetObjectKey);
AssetHandle handle = GetHandleAsync<T>(location, packageName: packageName); AssetHandle handle = GetHandleAsync<T>(location, packageName: packageName);
@@ -636,6 +657,8 @@ namespace TEngine
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this); assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
m_AssetPool.Register(assetObject, true); m_AssetPool.Register(assetObject, true);
_assetLoadingList.Remove(assetObjectKey);
return handle.AssetObject as T; return handle.AssetObject as T;
} }
@@ -649,12 +672,17 @@ namespace TEngine
} }
string assetObjectKey = GetCacheKey(location, packageName); string assetObjectKey = GetCacheKey(location, packageName);
await TryWaitingLoading(assetObjectKey);
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey); AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null) if (assetObject != null)
{ {
return AssetsReference.Instantiate(assetObject.Target as GameObject, parent, this).gameObject; return AssetsReference.Instantiate(assetObject.Target as GameObject, parent, this).gameObject;
} }
_assetLoadingList.Add(assetObjectKey);
AssetHandle handle = GetHandleAsync<GameObject>(location, packageName: packageName); AssetHandle handle = GetHandleAsync<GameObject>(location, packageName: packageName);
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow(); bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
@@ -669,6 +697,8 @@ namespace TEngine
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this); assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
m_AssetPool.Register(assetObject, true); m_AssetPool.Register(assetObject, true);
_assetLoadingList.Remove(assetObjectKey);
return gameObject; return gameObject;
} }
@@ -696,6 +726,9 @@ namespace TEngine
} }
string assetObjectKey = GetCacheKey(location, packageName); string assetObjectKey = GetCacheKey(location, packageName);
await TryWaitingLoading(assetObjectKey);
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey); AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null) if (assetObject != null)
{ {
@@ -703,6 +736,8 @@ namespace TEngine
return; return;
} }
_assetLoadingList.Add(assetObjectKey);
AssetInfo assetInfo = GetAssetInfo(location, packageName); AssetInfo assetInfo = GetAssetInfo(location, packageName);
if (!string.IsNullOrEmpty(assetInfo.Error)) if (!string.IsNullOrEmpty(assetInfo.Error))
@@ -730,6 +765,8 @@ namespace TEngine
if (handle.AssetObject == null || handle.Status == EOperationStatus.Failed) if (handle.AssetObject == null || handle.Status == EOperationStatus.Failed)
{ {
_assetLoadingList.Remove(assetObjectKey);
string errorMessage = Utility.Text.Format("Can not load asset '{0}'.", location); string errorMessage = Utility.Text.Format("Can not load asset '{0}'.", location);
if (loadAssetCallbacks.LoadAssetFailureCallback != null) if (loadAssetCallbacks.LoadAssetFailureCallback != null)
{ {
@@ -744,6 +781,8 @@ namespace TEngine
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this); assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
m_AssetPool.Register(assetObject, true); m_AssetPool.Register(assetObject, true);
_assetLoadingList.Remove(assetObjectKey);
if (loadAssetCallbacks.LoadAssetSuccessCallback != null) if (loadAssetCallbacks.LoadAssetSuccessCallback != null)
{ {
duration = Time.time - duration; duration = Time.time - duration;
@@ -774,12 +813,17 @@ namespace TEngine
} }
string assetObjectKey = GetCacheKey(location, packageName); string assetObjectKey = GetCacheKey(location, packageName);
await TryWaitingLoading(assetObjectKey);
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey); AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null) if (assetObject != null)
{ {
loadAssetCallbacks.LoadAssetSuccessCallback(location, assetObject.Target, 0, userData); loadAssetCallbacks.LoadAssetSuccessCallback(location, assetObject.Target, 0, userData);
return; return;
} }
_assetLoadingList.Add(assetObjectKey);
AssetInfo assetInfo = GetAssetInfo(location, packageName); AssetInfo assetInfo = GetAssetInfo(location, packageName);
@@ -808,6 +852,8 @@ namespace TEngine
if (handle.AssetObject == null || handle.Status == EOperationStatus.Failed) if (handle.AssetObject == null || handle.Status == EOperationStatus.Failed)
{ {
_assetLoadingList.Remove(assetObjectKey);
string errorMessage = Utility.Text.Format("Can not load asset '{0}'.", location); string errorMessage = Utility.Text.Format("Can not load asset '{0}'.", location);
if (loadAssetCallbacks.LoadAssetFailureCallback != null) if (loadAssetCallbacks.LoadAssetFailureCallback != null)
{ {
@@ -821,6 +867,8 @@ namespace TEngine
{ {
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this); assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle,this);
m_AssetPool.Register(assetObject, true); m_AssetPool.Register(assetObject, true);
_assetLoadingList.Remove(assetObjectKey);
if (loadAssetCallbacks.LoadAssetSuccessCallback != null) 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 #endregion
#region #region