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

修正同时对一个资源进行异步加载的处理
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="packageName">指定资源包的名称。不传使用默认资源包</param>
/// <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>
/// 同步加载子资源对象。

View File

@@ -109,6 +109,10 @@ namespace TEngine
/// </summary>
private readonly Dictionary<string, AssetInfo> _assetInfoMap = new Dictionary<string, AssetInfo>();
/// <summary>
/// 正在加载的资源列表。
/// </summary>
private readonly HashSet<string> _assetLoadingList = new HashSet<string>();
#endregion
/// <summary>
@@ -134,6 +138,8 @@ namespace TEngine
DefaultPackage = defaultPackage;
}
CancellationToken = InstanceRoot.gameObject.GetCancellationTokenOnDestroy();
IObjectPoolManager objectPoolManager = ModuleImpSystem.GetModule<IObjectPoolManager>();
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
/// <param name="callback">回调函数。</param>
/// <param name="packageName">指定资源包的名称。不传使用默认资源包</param>
/// <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))
{
@@ -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<T>(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<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))
{
@@ -619,12 +635,17 @@ 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<T>(location, packageName: packageName);
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
@@ -637,6 +658,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<GameObject>(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,6 +813,9 @@ namespace TEngine
}
string assetObjectKey = GetCacheKey(location, packageName);
await TryWaitingLoading(assetObjectKey);
AssetObject assetObject = m_AssetPool.Spawn(assetObjectKey);
if (assetObject != null)
{
@@ -781,6 +823,8 @@ namespace TEngine
return;
}
_assetLoadingList.Add(assetObjectKey);
AssetInfo assetInfo = GetAssetInfo(location, packageName);
if (!string.IsNullOrEmpty(assetInfo.Error))
@@ -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)
{
@@ -822,6 +868,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;
@@ -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