update resource manager

优化ForceUnloadAllAssets方法逻辑
pull/189/head
hevinci 2023-10-19 19:39:14 +08:00
parent 194afe435a
commit d30a8aefa4
9 changed files with 82 additions and 32 deletions

View File

@ -191,7 +191,7 @@ namespace YooAsset
{ {
if (_createRequest != null) if (_createRequest != null)
{ {
if (_isWaitForAsyncComplete) if (_isWaitForAsyncComplete || IsForceDestroyComplete)
{ {
// 强制挂起主线程(注意:该操作会很耗时) // 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity bundle."); YooLogger.Warning("Suspend the main thread to load unity bundle.");

View File

@ -46,6 +46,7 @@ namespace YooAsset
private readonly List<ProviderBase> _providers = new List<ProviderBase>(100); private readonly List<ProviderBase> _providers = new List<ProviderBase>(100);
private readonly List<ProviderBase> _removeList = new List<ProviderBase>(100); private readonly List<ProviderBase> _removeList = new List<ProviderBase>(100);
protected bool IsForceDestroyComplete { private set; get; } = false;
internal AssetBundle CacheBundle { set; get; } internal AssetBundle CacheBundle { set; get; }
internal string FileLoadPath { set; get; } internal string FileLoadPath { set; get; }
internal float DownloadProgress { set; get; } internal float DownloadProgress { set; get; }
@ -165,6 +166,18 @@ namespace YooAsset
} }
} }
/// <summary>
/// 强制销毁资源提供者
/// </summary>
public void ForceDestroyComplete()
{
IsForceDestroyComplete = true;
// 注意:主动轮询更新完成同步加载
// 说明:如果正在下载或解压也可以放心销毁。
Update();
}
/// <summary> /// <summary>
/// 主线程等待异步操作完毕 /// 主线程等待异步操作完毕
/// </summary> /// </summary>

View File

@ -66,9 +66,9 @@ namespace YooAsset
} }
else else
{ {
Error = "Scene is invalid or is not loaded.";
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
Error = "Scene is invalid or is not loaded.";
} }
} }

View File

@ -65,7 +65,7 @@ namespace YooAsset
// 2. 加载资源对象 // 2. 加载资源对象
if (Status == EStatus.Loading) if (Status == EStatus.Loading)
{ {
if (IsWaitForAsyncComplete) if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{ {
if (MainAssetInfo.AssetType == null) if (MainAssetInfo.AssetType == null)
AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets(); AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets();
@ -87,7 +87,7 @@ namespace YooAsset
{ {
if (_cacheRequest != null) if (_cacheRequest != null)
{ {
if (IsWaitForAsyncComplete) if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{ {
// 强制挂起主线程(注意:该操作会很耗时) // 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset."); YooLogger.Warning("Suspend the main thread to load unity asset.");

View File

@ -65,7 +65,7 @@ namespace YooAsset
// 2. 加载资源对象 // 2. 加载资源对象
if (Status == EStatus.Loading) if (Status == EStatus.Loading)
{ {
if (IsWaitForAsyncComplete) if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{ {
if (MainAssetInfo.AssetType == null) if (MainAssetInfo.AssetType == null)
AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath); AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath);
@ -87,7 +87,7 @@ namespace YooAsset
{ {
if (_cacheRequest != null) if (_cacheRequest != null)
{ {
if (IsWaitForAsyncComplete) if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{ {
// 强制挂起主线程(注意:该操作会很耗时) // 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset."); YooLogger.Warning("Suspend the main thread to load unity asset.");

View File

@ -65,7 +65,7 @@ namespace YooAsset
// 2. 加载资源对象 // 2. 加载资源对象
if (Status == EStatus.Loading) if (Status == EStatus.Loading)
{ {
if (IsWaitForAsyncComplete) if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{ {
if (MainAssetInfo.AssetType == null) if (MainAssetInfo.AssetType == null)
AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath); AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath);
@ -87,7 +87,7 @@ namespace YooAsset
{ {
if (_cacheRequest != null) if (_cacheRequest != null)
{ {
if (IsWaitForAsyncComplete) if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{ {
// 强制挂起主线程(注意:该操作会很耗时) // 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset."); YooLogger.Warning("Suspend the main thread to load unity asset.");

View File

@ -93,6 +93,7 @@ namespace YooAsset
protected BundleLoaderBase OwnerBundle { private set; get; } protected BundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundles DependBundles { private set; get; } protected DependAssetBundles DependBundles { private set; get; }
protected bool IsWaitForAsyncComplete { private set; get; } = false; protected bool IsWaitForAsyncComplete { private set; get; } = false;
protected bool IsForceDestroyComplete { private set; get; } = false;
private readonly List<HandleBase> _handles = new List<HandleBase>(); private readonly List<HandleBase> _handles = new List<HandleBase>();
@ -121,7 +122,7 @@ namespace YooAsset
public abstract void Update(); public abstract void Update();
/// <summary> /// <summary>
/// 销毁资源对象 /// 销毁资源提供者
/// </summary> /// </summary>
public void Destroy() public void Destroy()
{ {
@ -193,6 +194,17 @@ namespace YooAsset
RefCount--; RefCount--;
} }
/// <summary>
/// 释放所有资源句柄
/// </summary>
public void ReleaseAllHandles()
{
foreach (var handle in _handles)
{
handle.ReleaseInternal();
}
}
/// <summary> /// <summary>
/// 等待异步执行完毕 /// 等待异步执行完毕
/// </summary> /// </summary>
@ -206,10 +218,22 @@ namespace YooAsset
// 验证结果 // 验证结果
if (IsDone == false) if (IsDone == false)
{ {
YooLogger.Warning($"WaitForAsyncComplete failed to loading : {MainAssetInfo.AssetPath}"); YooLogger.Warning($"{nameof(WaitForAsyncComplete)} failed to loading : {MainAssetInfo.AssetPath}");
} }
} }
/// <summary>
/// 强制销毁资源提供者
/// </summary>
public void ForceDestroyComplete()
{
IsForceDestroyComplete = true;
// 注意:主动轮询更新完成同步加载
// 说明:如果资源包未准备完毕也可以放心销毁。
Update();
}
/// <summary> /// <summary>
/// 处理特殊异常 /// 处理特殊异常
/// </summary> /// </summary>

View File

@ -167,23 +167,45 @@ namespace YooAsset
/// <summary> /// <summary>
/// 强制回收所有资源 /// 强制回收所有资源
/// 注意:加载器在销毁后关联的下载器还会继续下载!
/// </summary> /// </summary>
public void ForceUnloadAllAssets() public void ForceUnloadAllAssets()
{ {
#if UNITY_WEBGL #if UNITY_WEBGL
throw new Exception($"WebGL not support invoke {nameof(ForceUnloadAllAssets)}"); throw new Exception($"WebGL not support invoke {nameof(ForceUnloadAllAssets)}");
#else #else
// 注意:因为场景无法异步转同步,需要等待所有场景加载完毕!
foreach (var sceneHandlePair in _sceneHandles)
{
var sceneHandle = sceneHandlePair.Value;
if (sceneHandle.PackageName == PackageName)
{
if (sceneHandle.IsDone == false)
throw new Exception($"{nameof(ForceUnloadAllAssets)} cannot be called when loading the scene !");
}
}
// 释放所有资源句柄
foreach (var provider in _providerList) foreach (var provider in _providerList)
{ {
provider.WaitForAsyncComplete(); provider.ReleaseAllHandles();
}
// 强制销毁资源提供者
foreach (var provider in _providerList)
{
provider.ForceDestroyComplete();
provider.Destroy(); provider.Destroy();
} }
// 强制销毁资源加载器
foreach (var loader in _loaderList) foreach (var loader in _loaderList)
{ {
loader.WaitForAsyncComplete(); loader.ForceDestroyComplete();
loader.Destroy(); loader.Destroy();
} }
// 清空数据
_providerList.Clear(); _providerList.Clear();
_providerDic.Clear(); _providerDic.Clear();
_loaderList.Clear(); _loaderList.Clear();
@ -409,6 +431,10 @@ namespace YooAsset
_providerDic.Remove(provider.ProviderGUID); _providerDic.Remove(provider.ProviderGUID);
} }
} }
internal bool HasAnyLoader()
{
return _loaderList.Count > 0;
}
private BundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo) private BundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo)
{ {
@ -476,15 +502,6 @@ namespace YooAsset
} }
return result; return result;
} }
internal List<BundleInfo> GetLoadedBundleInfos()
{
List<BundleInfo> result = new List<BundleInfo>(100);
foreach (var loader in _loaderList)
{
result.Add(loader.MainBundleInfo);
}
return result;
}
#endregion #endregion
} }
} }

View File

@ -300,7 +300,13 @@ namespace YooAsset
public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion = true, int timeout = 60) public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion = true, int timeout = 60)
{ {
DebugCheckInitialize(false); DebugCheckInitialize(false);
DebugCheckUpdateManifest();
// 注意:强烈建议在更新之前保持加载器为空!
if (_resourceMgr.HasAnyLoader())
{
YooLogger.Warning($"Found loaded bundle before update manifest ! Recommended to call the {nameof(ForceUnloadAllAssets)} method to release loaded bundle !");
}
return _playModeImpl.UpdatePackageManifestAsync(packageVersion, autoSaveVersion, timeout); return _playModeImpl.UpdatePackageManifestAsync(packageVersion, autoSaveVersion, timeout);
} }
@ -1128,16 +1134,6 @@ namespace YooAsset
} }
} }
[Conditional("DEBUG")]
private void DebugCheckUpdateManifest()
{
var loadedBundleInfos = _resourceMgr.GetLoadedBundleInfos();
if (loadedBundleInfos.Count > 0)
{
YooLogger.Warning($"Found loaded bundle before update manifest ! Recommended to call the {nameof(ForceUnloadAllAssets)} method to release loaded bundle !");
}
}
[Conditional("DEBUG")] [Conditional("DEBUG")]
private void DebugCheckRawFileLoadMethod(string method) private void DebugCheckRawFileLoadMethod(string method)
{ {