资源模块更新
This commit is contained in:
parent
d2b3a36da6
commit
3d6caf4028
@ -8,7 +8,6 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
public partial class ResourceExtComponent
|
public partial class ResourceExtComponent
|
||||||
{
|
{
|
||||||
private static IResourceModule _resourceModule;
|
private static IResourceModule _resourceModule;
|
||||||
private LoadAssetCallbacks _loadAssetCallbacks;
|
|
||||||
|
|
||||||
public static IResourceModule ResourceModule => _resourceModule;
|
public static IResourceModule ResourceModule => _resourceModule;
|
||||||
|
|
||||||
@ -30,30 +29,20 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Dictionary<UnityEngine.Object, LoadingState> _loadingStates = new Dictionary<UnityEngine.Object, LoadingState>();
|
private readonly Dictionary<UnityEngine.Object, LoadingState> _loadingStates = new Dictionary<UnityEngine.Object, LoadingState>();
|
||||||
|
|
||||||
private void InitializedResources()
|
private void InitializedResources()
|
||||||
{
|
{
|
||||||
_resourceModule = ModuleSystem.GetModule<IResourceModule>();
|
_resourceModule = ModuleSystem.GetModule<IResourceModule>();
|
||||||
_loadAssetCallbacks = new LoadAssetCallbacks(OnLoadAssetSuccess, OnLoadAssetFailure);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnLoadAssetFailure(string assetName, LoadResourceStatus status, string errormessage, object userdata)
|
|
||||||
{
|
|
||||||
_assetLoadingList.Remove(assetName);
|
|
||||||
ISetAssetObject setAssetObject = (ISetAssetObject)userdata;
|
|
||||||
if (setAssetObject != null)
|
|
||||||
{
|
|
||||||
ClearLoadingState(setAssetObject.TargetObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.Error("Can not load asset from '{0}' with error message '{1}'.", 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;
|
||||||
|
if (setAssetObject == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
UnityEngine.Object assetObject = asset as UnityEngine.Object;
|
UnityEngine.Object assetObject = asset as UnityEngine.Object;
|
||||||
|
|
||||||
if (assetObject != null)
|
if (assetObject != null)
|
||||||
@ -63,8 +52,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
{
|
{
|
||||||
ClearLoadingState(setAssetObject.TargetObject);
|
ClearLoadingState(setAssetObject.TargetObject);
|
||||||
|
|
||||||
_assetItemPool.Register(AssetItemObject.Create(setAssetObject.Location, assetObject), true);
|
SetAsset(setAssetObject, TrackLoadedAsset(setAssetObject.Location, assetObject));
|
||||||
SetAsset(setAssetObject, assetObject);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -74,7 +62,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error($"Load failure asset type is {asset.GetType()}.");
|
Log.Error($"Load failure asset type is {asset?.GetType()}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +94,6 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 等待其他可能正在进行的加载。
|
// 等待其他可能正在进行的加载。
|
||||||
await TryWaitingLoading(location).AttachExternalCancellation(linkedTokenSource.Token);
|
|
||||||
|
|
||||||
// 再次检查是否被新请求替换。
|
// 再次检查是否被新请求替换。
|
||||||
if (!IsCurrentLocation(target, location))
|
if (!IsCurrentLocation(target, location))
|
||||||
@ -121,6 +108,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
var assetObject = (T)_assetItemPool.Spawn(location).Target;
|
var assetObject = (T)_assetItemPool.Spawn(location).Target;
|
||||||
SetAsset(setAssetObject, assetObject);
|
SetAsset(setAssetObject, assetObject);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -131,23 +119,26 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 防止重复加载同一资源。
|
// 防止重复加载同一资源。
|
||||||
if (!_assetLoadingList.Add(location))
|
if (!IsCurrentLocation(target, location))
|
||||||
{
|
{
|
||||||
// 已经在加载中,等待回调处理。
|
// 已经在加载中,等待回调处理。
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
T resource = await _resourceModule.LoadAssetAsync<T>(location, linkedTokenSource.Token);
|
T resource = await _resourceModule.LoadAssetAsync<T>(location, linkedTokenSource.Token);
|
||||||
if (resource != null)
|
if (resource == null)
|
||||||
{
|
{
|
||||||
_loadAssetCallbacks?.LoadAssetSuccessCallback.Invoke(location,resource, 0f, setAssetObject);
|
ClearLoadingState(target);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
_assetLoadingList.Remove(location);
|
|
||||||
|
OnLoadAssetSuccess(location, resource, 0f, setAssetObject);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
ClearLoadingState(target);
|
||||||
// 请求被取消,正常情况,无需处理。
|
// 请求被取消,正常情况,无需处理。
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -195,6 +186,19 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
return _loadingStates.TryGetValue(target, out var state) && state.Location == location;
|
return _loadingStates.TryGetValue(target, out var state) && state.Location == location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UnityEngine.Object TrackLoadedAsset(string location, UnityEngine.Object assetObject)
|
||||||
|
{
|
||||||
|
if (_assetItemPool.CanSpawn(location))
|
||||||
|
{
|
||||||
|
var cachedAsset = _assetItemPool.Spawn(location).Target as UnityEngine.Object;
|
||||||
|
_resourceModule.UnloadAsset(assetObject);
|
||||||
|
return cachedAsset;
|
||||||
|
}
|
||||||
|
|
||||||
|
_assetItemPool.Register(AssetItemObject.Create(location, assetObject), true);
|
||||||
|
return assetObject;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 组件销毁时清理所有资源。
|
/// 组件销毁时清理所有资源。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -14,6 +15,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
{
|
{
|
||||||
private readonly Dictionary<string, SubAssetsHandle> _subAssetsHandles = new Dictionary<string, SubAssetsHandle>();
|
private readonly Dictionary<string, SubAssetsHandle> _subAssetsHandles = new Dictionary<string, SubAssetsHandle>();
|
||||||
private readonly Dictionary<string, int> _subSpriteReferences = new Dictionary<string, int>();
|
private readonly Dictionary<string, int> _subSpriteReferences = new Dictionary<string, int>();
|
||||||
|
private readonly Dictionary<string, UniTaskCompletionSource<SubAssetsHandle>> _subAssetLoadingOperations = new Dictionary<string, UniTaskCompletionSource<SubAssetsHandle>>();
|
||||||
|
|
||||||
public async UniTask SetSubSprite(Image image, string location, string spriteName, bool setNativeSize = false, CancellationToken cancellationToken = default)
|
public async UniTask SetSubSprite(Image image, string location, string spriteName, bool setNativeSize = false, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
@ -22,6 +24,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
if (image == null)
|
if (image == null)
|
||||||
{
|
{
|
||||||
Log.Warning($"SetSubAssets Image is null");
|
Log.Warning($"SetSubAssets Image is null");
|
||||||
|
ReleaseSubAssetsIfUnused(location);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +44,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
if (spriteRenderer == null)
|
if (spriteRenderer == null)
|
||||||
{
|
{
|
||||||
Log.Warning($"SetSubAssets Image is null");
|
Log.Warning($"SetSubAssets Image is null");
|
||||||
|
ReleaseSubAssetsIfUnused(location);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,14 +60,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
throw new GameFrameworkException($"Invalid location: {location}");
|
throw new GameFrameworkException($"Invalid location: {location}");
|
||||||
}
|
}
|
||||||
|
|
||||||
await TryWaitingLoading(location);
|
var subAssetsHandle = await GetOrLoadSubAssetsHandleAsync(location, cancellationToken);
|
||||||
|
|
||||||
if (!_subAssetsHandles.TryGetValue(location, out var subAssetsHandle))
|
|
||||||
{
|
|
||||||
subAssetsHandle = YooAssets.LoadSubAssetsAsync<Sprite>(location);
|
|
||||||
await subAssetsHandle.ToUniTask(cancellationToken: cancellationToken);
|
|
||||||
_subAssetsHandles[location] = subAssetsHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
var subSprite = subAssetsHandle.GetSubAssetObject<Sprite>(spriteName);
|
var subSprite = subAssetsHandle.GetSubAssetObject<Sprite>(spriteName);
|
||||||
if (subSprite == null)
|
if (subSprite == null)
|
||||||
@ -82,8 +79,10 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
subSpriteReference = target.AddComponent<SubSpriteReference>();
|
subSpriteReference = target.AddComponent<SubSpriteReference>();
|
||||||
}
|
}
|
||||||
|
|
||||||
_subSpriteReferences[location] = _subSpriteReferences.TryGetValue(location, out var count) ? count + 1 : 1;
|
if (subSpriteReference.Reference(location))
|
||||||
subSpriteReference.Reference(location);
|
{
|
||||||
|
_subSpriteReferences[location] = _subSpriteReferences.TryGetValue(location, out var count) ? count + 1 : 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void DeleteReference(string location)
|
internal void DeleteReference(string location)
|
||||||
@ -93,13 +92,85 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_subSpriteReferences[location] = _subSpriteReferences.TryGetValue(location, out var count) ? count - 1 : 0;
|
int nextCount = _subSpriteReferences.TryGetValue(location, out var count) ? count - 1 : 0;
|
||||||
if (_subSpriteReferences[location] <= 0)
|
if (nextCount > 0)
|
||||||
|
{
|
||||||
|
_subSpriteReferences[location] = nextCount;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_subSpriteReferences.Remove(location);
|
||||||
|
if (_subAssetsHandles.TryGetValue(location, out var subAssetsHandle))
|
||||||
|
{
|
||||||
|
subAssetsHandle.Dispose();
|
||||||
|
_subAssetsHandles.Remove(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async UniTask<SubAssetsHandle> GetOrLoadSubAssetsHandleAsync(string location, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (_subAssetsHandles.TryGetValue(location, out var cachedHandle))
|
||||||
|
{
|
||||||
|
return cachedHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_subAssetLoadingOperations.TryGetValue(location, out var loadingOperation))
|
||||||
|
{
|
||||||
|
if (cancellationToken.CanBeCanceled)
|
||||||
|
{
|
||||||
|
await loadingOperation.Task.AttachExternalCancellation(cancellationToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await loadingOperation.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var completionSource = new UniTaskCompletionSource<SubAssetsHandle>();
|
||||||
|
_subAssetLoadingOperations.Add(location, completionSource);
|
||||||
|
|
||||||
|
SubAssetsHandle subAssetsHandle = default;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
subAssetsHandle = YooAssets.LoadSubAssetsAsync<Sprite>(location);
|
||||||
|
await subAssetsHandle.ToUniTask();
|
||||||
|
_subAssetsHandles[location] = subAssetsHandle;
|
||||||
|
completionSource.TrySetResult(subAssetsHandle);
|
||||||
|
return subAssetsHandle;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
subAssetsHandle?.Dispose();
|
||||||
|
completionSource.TrySetException(ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_subAssetLoadingOperations.Remove(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReleaseSubAssetsIfUnused(string location)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(location))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_subSpriteReferences.TryGetValue(location, out var count) && count > 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_subAssetsHandles.TryGetValue(location, out var subAssetsHandle))
|
||||||
{
|
{
|
||||||
var subAssetsHandle = _subAssetsHandles[location];
|
|
||||||
subAssetsHandle.Dispose();
|
subAssetsHandle.Dispose();
|
||||||
_subAssetsHandles.Remove(location);
|
_subAssetsHandles.Remove(location);
|
||||||
_subSpriteReferences.Remove(location);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,14 +180,20 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
{
|
{
|
||||||
private string _location;
|
private string _location;
|
||||||
|
|
||||||
public void Reference(string location)
|
public bool Reference(string location)
|
||||||
{
|
{
|
||||||
|
if (_location == location)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_location != null && _location != location)
|
if (_location != null && _location != location)
|
||||||
{
|
{
|
||||||
ResourceExtComponent.Instance?.DeleteReference(_location);
|
ResourceExtComponent.Instance?.DeleteReference(_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
_location = location;
|
_location = location;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
|
|||||||
@ -17,13 +17,6 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
{
|
{
|
||||||
public static ResourceExtComponent Instance { private set; get; }
|
public static ResourceExtComponent Instance { private set; get; }
|
||||||
|
|
||||||
private readonly TimeoutController _timeoutController = new TimeoutController();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 正在加载的资源列表。
|
|
||||||
/// </summary>
|
|
||||||
private readonly HashSet<string> _assetLoadingList = new HashSet<string>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检查是否可以释放间隔。
|
/// 检查是否可以释放间隔。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -144,30 +137,5 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
_loadAssetObjectsLinkedList.AddLast(new LoadAssetObject(setAssetObject, assetObject));
|
_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}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,69 +29,61 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
private List<AssetsRefInfo> refAssetInfoList;
|
private List<AssetsRefInfo> refAssetInfoList;
|
||||||
|
|
||||||
private static IResourceModule _resourceModule;
|
private static IResourceModule _resourceModule;
|
||||||
|
private HashSet<int> _refAssetIds;
|
||||||
|
|
||||||
private static Dictionary<GameObject, AssetsReference> _originalRefs = new();
|
private bool TryEnsureResourceModule()
|
||||||
|
|
||||||
|
|
||||||
private void CheckInit()
|
|
||||||
{
|
{
|
||||||
if (_resourceModule != null)
|
if (_resourceModule != null)
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_resourceModule = ModuleSystem.GetModule<IResourceModule>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_resourceModule == null)
|
_resourceModule = ModuleSystem.GetModule<IResourceModule>();
|
||||||
{
|
return _resourceModule != null;
|
||||||
throw new GameFrameworkException($"resourceModule is null.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckRelease()
|
private void ReleaseSourceReference()
|
||||||
{
|
{
|
||||||
if (sourceGameObject != null)
|
if (sourceGameObject != null)
|
||||||
{
|
{
|
||||||
_resourceModule.UnloadAsset(sourceGameObject);
|
_resourceModule.UnloadAsset(sourceGameObject);
|
||||||
|
sourceGameObject = null;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
private void EnsureReferenceCache()
|
||||||
|
{
|
||||||
|
if (_refAssetIds != null)
|
||||||
{
|
{
|
||||||
Log.Warning($"sourceGameObject is not invalid.");
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
_refAssetIds = new HashSet<int>();
|
||||||
private void Awake()
|
if (refAssetInfoList == null)
|
||||||
{
|
|
||||||
// If it is a clone, clear the reference records before cloning
|
|
||||||
if (!IsOriginalInstance())
|
|
||||||
{
|
{
|
||||||
ClearCloneReferences();
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsOriginalInstance()
|
foreach (var refInfo in refAssetInfoList)
|
||||||
{
|
{
|
||||||
return _originalRefs.TryGetValue(gameObject, out var originalComponent) &&
|
if (refInfo.refAsset != null)
|
||||||
originalComponent == this;
|
{
|
||||||
}
|
_refAssetIds.Add(refInfo.instanceId != 0 ? refInfo.instanceId : refInfo.refAsset.GetInstanceID());
|
||||||
|
}
|
||||||
private void ClearCloneReferences()
|
}
|
||||||
{
|
|
||||||
sourceGameObject = null;
|
|
||||||
refAssetInfoList?.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
CheckInit();
|
if (!TryEnsureResourceModule())
|
||||||
if (sourceGameObject != null)
|
|
||||||
{
|
{
|
||||||
CheckRelease();
|
sourceGameObject = null;
|
||||||
|
refAssetInfoList?.Clear();
|
||||||
|
_refAssetIds?.Clear();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReleaseSourceReference();
|
||||||
ReleaseRefAssetInfoList();
|
ReleaseRefAssetInfoList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +98,8 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
refAssetInfoList.Clear();
|
refAssetInfoList.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_refAssetIds?.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssetsReference Ref(GameObject source, IResourceModule resourceModule = null)
|
public AssetsReference Ref(GameObject source, IResourceModule resourceModule = null)
|
||||||
@ -120,14 +114,17 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
throw new GameFrameworkException($"Source gameObject is in scene.");
|
throw new GameFrameworkException($"Source gameObject is in scene.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_resourceModule = resourceModule;
|
if (resourceModule != null)
|
||||||
sourceGameObject = source;
|
|
||||||
|
|
||||||
if (!_originalRefs.ContainsKey(gameObject))
|
|
||||||
{
|
{
|
||||||
_originalRefs.Add(gameObject, this);
|
_resourceModule = resourceModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sourceGameObject != null && sourceGameObject != source && TryEnsureResourceModule())
|
||||||
|
{
|
||||||
|
ReleaseSourceReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceGameObject = source;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +135,18 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
throw new GameFrameworkException($"Source gameObject is null.");
|
throw new GameFrameworkException($"Source gameObject is null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_resourceModule = resourceModule;
|
if (resourceModule != null)
|
||||||
|
{
|
||||||
|
_resourceModule = resourceModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureReferenceCache();
|
||||||
|
int instanceId = source.GetInstanceID();
|
||||||
|
if (!_refAssetIds.Add(instanceId))
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
if (refAssetInfoList == null)
|
if (refAssetInfoList == null)
|
||||||
{
|
{
|
||||||
refAssetInfoList = new List<AssetsRefInfo>();
|
refAssetInfoList = new List<AssetsRefInfo>();
|
||||||
|
|||||||
@ -246,11 +246,15 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
_forceUnloadUnusedAssets = false;
|
_forceUnloadUnusedAssets = false;
|
||||||
_preorderUnloadUnusedAssets = false;
|
_preorderUnloadUnusedAssets = false;
|
||||||
_lastUnloadUnusedAssetsOperationElapseSeconds = 0f;
|
_lastUnloadUnusedAssetsOperationElapseSeconds = 0f;
|
||||||
_asyncOperation = Resources.UnloadUnusedAssets();
|
_resourceModule.UnloadUnusedAssets();
|
||||||
if (useSystemUnloadUnusedAssets)
|
_asyncOperation = useSystemUnloadUnusedAssets ? Resources.UnloadUnusedAssets() : null;
|
||||||
{
|
}
|
||||||
_resourceModule.UnloadUnusedAssets();
|
|
||||||
}
|
if (_asyncOperation == null && _performGCCollect)
|
||||||
|
{
|
||||||
|
Log.Info("GC.Collect...");
|
||||||
|
_performGCCollect = false;
|
||||||
|
GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_asyncOperation is { isDone: true })
|
if (_asyncOperation is { isDone: true })
|
||||||
|
|||||||
@ -85,9 +85,11 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
private readonly Dictionary<string, AssetInfo> _assetInfoMap = new Dictionary<string, AssetInfo>();
|
private readonly Dictionary<string, AssetInfo> _assetInfoMap = new Dictionary<string, AssetInfo>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 正在加载的资源列表。
|
/// 正在加载的资源任务。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly HashSet<string> _assetLoadingList = new HashSet<string>();
|
private readonly Dictionary<string, UniTaskCompletionSource<bool>> _assetLoadingOperations = new Dictionary<string, UniTaskCompletionSource<bool>>();
|
||||||
|
|
||||||
|
private const float ProgressCallbackThreshold = 0.01f;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -107,6 +109,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
DefaultPackage = defaultPackage;
|
DefaultPackage = defaultPackage;
|
||||||
|
PackageMap[packageName] = defaultPackage;
|
||||||
|
|
||||||
IObjectPoolModule objectPoolModule = ModuleSystem.GetModule<IObjectPoolModule>();
|
IObjectPoolModule objectPoolModule = ModuleSystem.GetModule<IObjectPoolModule>();
|
||||||
SetObjectPoolModule(objectPoolModule);
|
SetObjectPoolModule(objectPoolModule);
|
||||||
@ -115,9 +118,14 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
void IModule.Dispose()
|
void IModule.Dispose()
|
||||||
{
|
{
|
||||||
|
foreach (var loadingOperation in _assetLoadingOperations.Values)
|
||||||
|
{
|
||||||
|
loadingOperation.TrySetResult(false);
|
||||||
|
}
|
||||||
|
|
||||||
PackageMap.Clear();
|
PackageMap.Clear();
|
||||||
_assetPool = null;
|
_assetPool = null;
|
||||||
_assetLoadingList.Clear();
|
_assetLoadingOperations.Clear();
|
||||||
_assetInfoMap.Clear();
|
_assetInfoMap.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,7 +471,7 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
AssetInfo assetInfo = GetAssetInfo(location, packageName);
|
AssetInfo assetInfo = GetAssetInfo(location, packageName);
|
||||||
|
|
||||||
if (!CheckLocationValid(location))
|
if (!CheckLocationValid(location, packageName))
|
||||||
{
|
{
|
||||||
return HasAssetResult.Valid;
|
return HasAssetResult.Valid;
|
||||||
}
|
}
|
||||||
@ -535,20 +543,25 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
/// <param name="packageName">指定资源包的名称。不传使用默认资源包</param>
|
/// <param name="packageName">指定资源包的名称。不传使用默认资源包</param>
|
||||||
/// <typeparam name="T">资源类型。</typeparam>
|
/// <typeparam name="T">资源类型。</typeparam>
|
||||||
/// <returns>资源句柄。</returns>
|
/// <returns>资源句柄。</returns>
|
||||||
private AssetHandle GetHandleAsync<T>(string location, string packageName = "") where T : UnityEngine.Object
|
private AssetHandle GetHandleAsync<T>(string location, string packageName = "", uint priority = 0) where T : UnityEngine.Object
|
||||||
{
|
{
|
||||||
return GetHandleAsync(location, typeof(T), packageName);
|
return GetHandleAsync(location, typeof(T), packageName, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AssetHandle GetHandleAsync(string location, Type assetType, string packageName = "")
|
private AssetHandle GetHandleAsync(string location, Type assetType, string packageName = "", uint priority = 0)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(packageName))
|
if (string.IsNullOrEmpty(packageName))
|
||||||
{
|
{
|
||||||
return YooAssets.LoadAssetAsync(location, assetType);
|
return YooAssets.LoadAssetAsync(location, assetType, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
var package = YooAssets.GetPackage(packageName);
|
var package = YooAssets.GetPackage(packageName);
|
||||||
return package.LoadAssetAsync(location, assetType);
|
return package.LoadAssetAsync(location, assetType, priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint NormalizePriority(int priority)
|
||||||
|
{
|
||||||
|
return priority > 0 ? (uint)priority : 0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -652,37 +665,16 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
string assetObjectKey = GetCacheKey(location, packageName);
|
string assetObjectKey = GetCacheKey(location, packageName);
|
||||||
|
try
|
||||||
await TryWaitingLoading(assetObjectKey);
|
|
||||||
|
|
||||||
AssetObject assetObject = _assetPool.Spawn(assetObjectKey);
|
|
||||||
if (assetObject != null)
|
|
||||||
{
|
{
|
||||||
await UniTask.Yield();
|
var asset = await GetOrLoadAssetAsync(location, typeof(T), packageName, assetObjectKey);
|
||||||
callback?.Invoke(assetObject.Target as T);
|
callback?.Invoke(asset as T);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
_assetLoadingList.Add(assetObjectKey);
|
|
||||||
|
|
||||||
AssetHandle handle = GetHandleAsync<T>(location, packageName: packageName);
|
|
||||||
|
|
||||||
handle.Completed += assetHandle =>
|
|
||||||
{
|
{
|
||||||
_assetLoadingList.Remove(assetObjectKey);
|
Log.Error($"Can not load asset '{location}'. {ex}");
|
||||||
|
callback?.Invoke(null);
|
||||||
if (assetHandle.AssetObject != null)
|
}
|
||||||
{
|
|
||||||
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle, this);
|
|
||||||
_assetPool.Register(assetObject, true);
|
|
||||||
|
|
||||||
callback?.Invoke(assetObject.Target as T);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
callback?.Invoke(null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@ -701,33 +693,8 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
string assetObjectKey = GetCacheKey(location, packageName);
|
string assetObjectKey = GetCacheKey(location, packageName);
|
||||||
|
|
||||||
await TryWaitingLoading(assetObjectKey);
|
var asset = await GetOrLoadAssetAsync(location, typeof(T), packageName, assetObjectKey, cancellationToken);
|
||||||
|
return asset as T;
|
||||||
AssetObject assetObject = _assetPool.Spawn(assetObjectKey);
|
|
||||||
if (assetObject != null)
|
|
||||||
{
|
|
||||||
await UniTask.Yield();
|
|
||||||
return assetObject.Target as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
_assetLoadingList.Add(assetObjectKey);
|
|
||||||
|
|
||||||
AssetHandle handle = GetHandleAsync<T>(location, packageName: packageName);
|
|
||||||
|
|
||||||
bool cancelOrFailed = await handle.ToUniTask().AttachExternalCancellation(cancellationToken).SuppressCancellationThrow();
|
|
||||||
|
|
||||||
if (cancelOrFailed)
|
|
||||||
{
|
|
||||||
_assetLoadingList.Remove(assetObjectKey);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle, this);
|
|
||||||
_assetPool.Register(assetObject, true);
|
|
||||||
|
|
||||||
_assetLoadingList.Remove(assetObjectKey);
|
|
||||||
|
|
||||||
return handle.AssetObject as T;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async UniTask<GameObject> LoadGameObjectAsync(string location, Transform parent = null, CancellationToken cancellationToken = default, string packageName = "")
|
public async UniTask<GameObject> LoadGameObjectAsync(string location, Transform parent = null, CancellationToken cancellationToken = default, string packageName = "")
|
||||||
@ -745,35 +712,8 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
string assetObjectKey = GetCacheKey(location, packageName);
|
string assetObjectKey = GetCacheKey(location, packageName);
|
||||||
|
|
||||||
await TryWaitingLoading(assetObjectKey);
|
var asset = await GetOrLoadAssetAsync(location, typeof(GameObject), packageName, assetObjectKey, cancellationToken);
|
||||||
|
return asset != null ? AssetsReference.Instantiate(asset as GameObject, parent, this).gameObject : null;
|
||||||
AssetObject assetObject = _assetPool.Spawn(assetObjectKey);
|
|
||||||
if (assetObject != null)
|
|
||||||
{
|
|
||||||
await UniTask.Yield();
|
|
||||||
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();
|
|
||||||
|
|
||||||
if (cancelOrFailed)
|
|
||||||
{
|
|
||||||
_assetLoadingList.Remove(assetObjectKey);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameObject gameObject = AssetsReference.Instantiate(handle.AssetObject as GameObject, parent, this).gameObject;
|
|
||||||
|
|
||||||
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle, this);
|
|
||||||
_assetPool.Register(assetObject, true);
|
|
||||||
|
|
||||||
_assetLoadingList.Remove(assetObjectKey);
|
|
||||||
|
|
||||||
return gameObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -813,26 +753,12 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
string assetObjectKey = GetCacheKey(location, packageName);
|
string assetObjectKey = GetCacheKey(location, packageName);
|
||||||
|
|
||||||
await TryWaitingLoading(assetObjectKey);
|
|
||||||
|
|
||||||
float duration = Time.time;
|
float duration = Time.time;
|
||||||
|
|
||||||
AssetObject assetObject = _assetPool.Spawn(assetObjectKey);
|
|
||||||
if (assetObject != null)
|
|
||||||
{
|
|
||||||
await UniTask.Yield();
|
|
||||||
loadAssetCallbacks.LoadAssetSuccessCallback(location, assetObject.Target, Time.time - duration, userData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_assetLoadingList.Add(assetObjectKey);
|
|
||||||
|
|
||||||
AssetInfo assetInfo = GetAssetInfo(location, packageName);
|
AssetInfo assetInfo = GetAssetInfo(location, packageName);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(assetInfo.Error))
|
if (!string.IsNullOrEmpty(assetInfo.Error))
|
||||||
{
|
{
|
||||||
_assetLoadingList.Remove(assetObjectKey);
|
|
||||||
|
|
||||||
string errorMessage = Utility.Text.Format("Can not load asset '{0}' because :'{1}'.", location, assetInfo.Error);
|
string errorMessage = Utility.Text.Format("Can not load asset '{0}' because :'{1}'.", location, assetInfo.Error);
|
||||||
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
|
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
|
||||||
{
|
{
|
||||||
@ -843,41 +769,23 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
throw new GameFrameworkException(errorMessage);
|
throw new GameFrameworkException(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetHandle handle = GetHandleAsync(location, assetType, packageName: packageName);
|
try
|
||||||
|
|
||||||
if (loadAssetCallbacks.LoadAssetUpdateCallback != null)
|
|
||||||
{
|
{
|
||||||
InvokeProgress(location, handle, loadAssetCallbacks.LoadAssetUpdateCallback, userData).Forget();
|
var asset = await GetOrLoadAssetAsync(location, assetType, packageName, assetObjectKey, NormalizePriority(priority), default,
|
||||||
|
handle => StartProgressTask(location, handle, loadAssetCallbacks.LoadAssetUpdateCallback, userData));
|
||||||
|
loadAssetCallbacks.LoadAssetSuccessCallback?.Invoke(location, asset, Time.time - duration, userData);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
await handle.ToUniTask();
|
|
||||||
|
|
||||||
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);
|
||||||
|
Log.Error($"{errorMessage} {ex}");
|
||||||
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
|
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
|
||||||
{
|
{
|
||||||
loadAssetCallbacks.LoadAssetFailureCallback(location, LoadResourceStatus.NotReady, errorMessage, userData);
|
loadAssetCallbacks.LoadAssetFailureCallback(location, LoadResourceStatus.NotReady, errorMessage, userData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new GameFrameworkException(errorMessage);
|
throw;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle, this);
|
|
||||||
_assetPool.Register(assetObject, true);
|
|
||||||
|
|
||||||
_assetLoadingList.Remove(assetObjectKey);
|
|
||||||
|
|
||||||
if (loadAssetCallbacks.LoadAssetSuccessCallback != null)
|
|
||||||
{
|
|
||||||
duration = Time.time - duration;
|
|
||||||
|
|
||||||
loadAssetCallbacks.LoadAssetSuccessCallback(location, handle.AssetObject, duration, userData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -915,26 +823,12 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
string assetObjectKey = GetCacheKey(location, packageName);
|
string assetObjectKey = GetCacheKey(location, packageName);
|
||||||
|
|
||||||
await TryWaitingLoading(assetObjectKey);
|
|
||||||
|
|
||||||
float duration = Time.time;
|
float duration = Time.time;
|
||||||
|
|
||||||
AssetObject assetObject = _assetPool.Spawn(assetObjectKey);
|
|
||||||
if (assetObject != null)
|
|
||||||
{
|
|
||||||
await UniTask.Yield();
|
|
||||||
loadAssetCallbacks.LoadAssetSuccessCallback(location, assetObject.Target, Time.time - duration, userData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_assetLoadingList.Add(assetObjectKey);
|
|
||||||
|
|
||||||
AssetInfo assetInfo = GetAssetInfo(location, packageName);
|
AssetInfo assetInfo = GetAssetInfo(location, packageName);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(assetInfo.Error))
|
if (!string.IsNullOrEmpty(assetInfo.Error))
|
||||||
{
|
{
|
||||||
_assetLoadingList.Remove(assetObjectKey);
|
|
||||||
|
|
||||||
string errorMessage = Utility.Text.Format("Can not load asset '{0}' because :'{1}'.", location, assetInfo.Error);
|
string errorMessage = Utility.Text.Format("Can not load asset '{0}' because :'{1}'.", location, assetInfo.Error);
|
||||||
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
|
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
|
||||||
{
|
{
|
||||||
@ -945,41 +839,23 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
throw new GameFrameworkException(errorMessage);
|
throw new GameFrameworkException(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetHandle handle = GetHandleAsync(location, assetInfo.AssetType, packageName: packageName);
|
try
|
||||||
|
|
||||||
if (loadAssetCallbacks.LoadAssetUpdateCallback != null)
|
|
||||||
{
|
{
|
||||||
InvokeProgress(location, handle, loadAssetCallbacks.LoadAssetUpdateCallback, userData).Forget();
|
var asset = await GetOrLoadAssetAsync(location, assetInfo.AssetType, packageName, assetObjectKey, NormalizePriority(priority), default,
|
||||||
|
handle => StartProgressTask(location, handle, loadAssetCallbacks.LoadAssetUpdateCallback, userData));
|
||||||
|
loadAssetCallbacks.LoadAssetSuccessCallback?.Invoke(location, asset, Time.time - duration, userData);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
await handle.ToUniTask();
|
|
||||||
|
|
||||||
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);
|
||||||
|
Log.Error($"{errorMessage} {ex}");
|
||||||
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
|
if (loadAssetCallbacks.LoadAssetFailureCallback != null)
|
||||||
{
|
{
|
||||||
loadAssetCallbacks.LoadAssetFailureCallback(location, LoadResourceStatus.NotReady, errorMessage, userData);
|
loadAssetCallbacks.LoadAssetFailureCallback(location, LoadResourceStatus.NotReady, errorMessage, userData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new GameFrameworkException(errorMessage);
|
throw;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle, this);
|
|
||||||
_assetPool.Register(assetObject, true);
|
|
||||||
|
|
||||||
_assetLoadingList.Remove(assetObjectKey);
|
|
||||||
|
|
||||||
if (loadAssetCallbacks.LoadAssetSuccessCallback != null)
|
|
||||||
{
|
|
||||||
duration = Time.time - duration;
|
|
||||||
|
|
||||||
loadAssetCallbacks.LoadAssetSuccessCallback(location, handle.AssetObject, duration, userData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -992,11 +868,21 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
if (loadAssetUpdateCallback != null)
|
if (loadAssetUpdateCallback != null)
|
||||||
{
|
{
|
||||||
|
float lastReportedProgress = -1f;
|
||||||
while (assetHandle is { IsValid: true, IsDone: false })
|
while (assetHandle is { IsValid: true, IsDone: false })
|
||||||
{
|
{
|
||||||
await UniTask.Yield();
|
await UniTask.Yield();
|
||||||
|
float progress = assetHandle.Progress;
|
||||||
|
if (lastReportedProgress < 0f || progress - lastReportedProgress >= ProgressCallbackThreshold)
|
||||||
|
{
|
||||||
|
lastReportedProgress = progress;
|
||||||
|
loadAssetUpdateCallback.Invoke(location, progress, userData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loadAssetUpdateCallback.Invoke(location, assetHandle.Progress, userData);
|
if (assetHandle is { IsValid: true } && lastReportedProgress < 1f)
|
||||||
|
{
|
||||||
|
loadAssetUpdateCallback.Invoke(location, 1f, userData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1039,29 +925,114 @@ namespace AlicizaX.Resource.Runtime
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private readonly TimeoutController _timeoutController = new TimeoutController();
|
private async UniTask<UnityEngine.Object> GetOrLoadAssetAsync(string location, Type assetType, string packageName,
|
||||||
|
string assetObjectKey, uint priority = 0, CancellationToken cancellationToken = default, Action<AssetHandle> onHandleCreated = null)
|
||||||
private async UniTask TryWaitingLoading(string assetObjectKey)
|
|
||||||
{
|
{
|
||||||
if (_assetLoadingList.Contains(assetObjectKey))
|
while (true)
|
||||||
{
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
AssetObject cachedAssetObject = _assetPool.Spawn(assetObjectKey);
|
||||||
|
if (cachedAssetObject != null)
|
||||||
|
{
|
||||||
|
return cachedAssetObject.Target as UnityEngine.Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TryBeginLoading(assetObjectKey))
|
||||||
|
{
|
||||||
|
await WaitForLoadingAsync(assetObjectKey, cancellationToken);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetHandle handle = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await UniTask.WaitUntil(() => !_assetLoadingList.Contains(assetObjectKey))
|
handle = GetHandleAsync(location, assetType, packageName: packageName, priority: priority);
|
||||||
#if UNITY_EDITOR
|
onHandleCreated?.Invoke(handle);
|
||||||
.AttachExternalCancellation(_timeoutController.Timeout(TimeSpan.FromSeconds(60)));
|
await handle.ToUniTask();
|
||||||
_timeoutController.Reset();
|
|
||||||
#else
|
if (handle.AssetObject == null || handle.Status == EOperationStatus.Failed)
|
||||||
;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException ex)
|
|
||||||
{
|
|
||||||
if (_timeoutController.IsTimeout())
|
|
||||||
{
|
{
|
||||||
Log.Error($"LoadAssetAsync Waiting {assetObjectKey} timeout. reason:{ex.Message}");
|
throw new GameFrameworkException(Utility.Text.Format("Can not load asset '{0}'.", location));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var assetObject = AssetObject.Create(assetObjectKey, handle.AssetObject, handle, this);
|
||||||
|
_assetPool.Register(assetObject, true);
|
||||||
|
CompleteLoading(assetObjectKey);
|
||||||
|
return handle.AssetObject as UnityEngine.Object;
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
DisposeHandle(handle);
|
||||||
|
FailLoading(assetObjectKey, ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryBeginLoading(string assetObjectKey)
|
||||||
|
{
|
||||||
|
if (_assetLoadingOperations.ContainsKey(assetObjectKey))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_assetLoadingOperations.Add(assetObjectKey, new UniTaskCompletionSource<bool>());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async UniTask WaitForLoadingAsync(string assetObjectKey, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (!_assetLoadingOperations.TryGetValue(assetObjectKey, out var loadingOperation))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cancellationToken.CanBeCanceled)
|
||||||
|
{
|
||||||
|
await loadingOperation.Task.AttachExternalCancellation(cancellationToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await loadingOperation.Task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CompleteLoading(string assetObjectKey)
|
||||||
|
{
|
||||||
|
if (!_assetLoadingOperations.TryGetValue(assetObjectKey, out var loadingOperation))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_assetLoadingOperations.Remove(assetObjectKey);
|
||||||
|
loadingOperation.TrySetResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FailLoading(string assetObjectKey, Exception exception)
|
||||||
|
{
|
||||||
|
if (!_assetLoadingOperations.TryGetValue(assetObjectKey, out var loadingOperation))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_assetLoadingOperations.Remove(assetObjectKey);
|
||||||
|
loadingOperation.TrySetException(exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisposeHandle(AssetHandle handle)
|
||||||
|
{
|
||||||
|
if (handle is { IsValid: true })
|
||||||
|
{
|
||||||
|
handle.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartProgressTask(string location, AssetHandle handle, LoadAssetUpdateCallback loadAssetUpdateCallback, object userData)
|
||||||
|
{
|
||||||
|
if (loadAssetUpdateCallback != null && handle is { IsValid: true, IsDone: false })
|
||||||
|
{
|
||||||
|
InvokeProgress(location, handle, loadAssetUpdateCallback, userData).Forget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user