update resource manager

增加卸载指定资源的方法。
pull/189/head
hevinci 2023-10-19 16:28:30 +08:00
parent 82ef993d83
commit 194afe435a
9 changed files with 208 additions and 37 deletions

View File

@ -45,6 +45,7 @@ namespace YooAsset
public bool IsDestroyed { private set; get; } = false; public bool IsDestroyed { private set; get; } = false;
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);
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; }
@ -59,15 +60,6 @@ namespace YooAsset
Status = EStatus.None; Status = EStatus.None;
} }
/// <summary>
/// 添加附属的资源提供者
/// </summary>
public void AddProvider(ProviderBase provider)
{
if (_providers.Contains(provider) == false)
_providers.Add(provider);
}
/// <summary> /// <summary>
/// 引用(引用计数递加) /// 引用(引用计数递加)
/// </summary> /// </summary>
@ -100,40 +92,51 @@ namespace YooAsset
if (IsDone() == false) if (IsDone() == false)
return false; return false;
if (RefCount > 0) return RefCount <= 0;
return false;
return true;
} }
/// <summary> /// <summary>
/// 在满足条件的前提下,销毁所有资源提供者 /// 添加附属的资源提供者
/// </summary> /// </summary>
public void TryDestroyAllProviders() public void AddProvider(ProviderBase provider)
{ {
if (_providers.Contains(provider) == false)
_providers.Add(provider);
}
/// <summary>
/// 尝试销毁资源提供者
/// </summary>
public void TryDestroyProviders()
{
// TODO 不用等待资源包加载完成
/*
if (IsDone() == false) if (IsDone() == false)
return; return;
*/
// 条件1必须等待所有Provider可以销毁 _removeList.Clear();
// 获取移除列表
foreach (var provider in _providers) foreach (var provider in _providers)
{ {
if (provider.CanDestroy() == false) if (provider.CanDestroy())
return;
}
// 条件2除了自己没有其它引用
if (RefCount > _providers.Count)
return;
// 销毁所有Providers
{
foreach (var provider in _providers)
{ {
provider.Destroy(); _removeList.Add(provider);
} }
Impl.RemoveBundleProviders(_providers);
_providers.Clear();
} }
// 销毁资源提供者
foreach (var provider in _removeList)
{
_providers.Remove(provider);
provider.Destroy();
}
// 移除资源提供者
Impl.RemoveBundleProviders(_removeList);
_removeList.Clear();
} }

View File

@ -145,14 +145,15 @@ namespace YooAsset
/// </summary> /// </summary>
public bool CanDestroy() public bool CanDestroy()
{ {
if (IsDone == false) // 注意:在进行资源加载过程时不可以销毁
if (Status == EStatus.Loading || Status == EStatus.Checking)
return false; return false;
return RefCount <= 0; return RefCount <= 0;
} }
/// <summary> /// <summary>
/// 创建操作句柄 /// 创建资源句柄
/// </summary> /// </summary>
public T CreateHandle<T>() where T : HandleBase public T CreateHandle<T>() where T : HandleBase
{ {
@ -178,12 +179,12 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 释放操作句柄 /// 释放资源句柄
/// </summary> /// </summary>
public void ReleaseHandle(HandleBase handle) public void ReleaseHandle(HandleBase handle)
{ {
if (RefCount <= 0) if (RefCount <= 0)
YooLogger.Warning("Asset provider reference count is already zero. There may be resource leaks !"); throw new System.Exception("Should never get here !");
if (_handles.Remove(handle) == false) if (_handles.Remove(handle) == false)
throw new System.Exception("Should never get here !"); throw new System.Exception("Should never get here !");

View File

@ -105,7 +105,7 @@ namespace YooAsset
for (int i = _loaderList.Count - 1; i >= 0; i--) for (int i = _loaderList.Count - 1; i >= 0; i--)
{ {
BundleLoaderBase loader = _loaderList[i]; BundleLoaderBase loader = _loaderList[i];
loader.TryDestroyAllProviders(); loader.TryDestroyProviders();
} }
for (int i = _loaderList.Count - 1; i >= 0; i--) for (int i = _loaderList.Count - 1; i >= 0; i--)
@ -121,6 +121,50 @@ namespace YooAsset
} }
} }
/// <summary>
/// 尝试卸载指定资源的资源包(包括依赖资源)
/// </summary>
public void TryUnloadUnusedAsset(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to unload asset ! {assetInfo.Error}");
return;
}
// 卸载主资源包加载器
string manBundleName = _bundleQuery.GetMainBundleName(assetInfo);
var mainLoader = TryGetAssetBundleLoader(manBundleName);
if (mainLoader != null)
{
mainLoader.TryDestroyProviders();
if (mainLoader.CanDestroy())
{
string bundleName = mainLoader.MainBundleInfo.Bundle.BundleName;
mainLoader.Destroy();
_loaderList.Remove(mainLoader);
_loaderDic.Remove(bundleName);
}
}
// 卸载依赖资源包加载器
string[] dependBundleNames = _bundleQuery.GetDependBundleNames(assetInfo);
foreach (var dependBundleName in dependBundleNames)
{
var dependLoader = TryGetAssetBundleLoader(dependBundleName);
if (dependLoader != null)
{
if (dependLoader.CanDestroy())
{
string bundleName = dependLoader.MainBundleInfo.Bundle.BundleName;
dependLoader.Destroy();
_loaderList.Remove(dependLoader);
_loaderDic.Remove(bundleName);
}
}
}
}
/// <summary> /// <summary>
/// 强制回收所有资源 /// 强制回收所有资源
/// </summary> /// </summary>
@ -357,9 +401,9 @@ namespace YooAsset
} }
return result; return result;
} }
internal void RemoveBundleProviders(List<ProviderBase> providers) internal void RemoveBundleProviders(List<ProviderBase> removeList)
{ {
foreach (var provider in providers) foreach (var provider in removeList)
{ {
_providerList.Remove(provider); _providerList.Remove(provider);
_providerDic.Remove(provider.ProviderGUID); _providerDic.Remove(provider.ProviderGUID);

View File

@ -13,6 +13,16 @@ namespace YooAsset
/// </summary> /// </summary>
BundleInfo[] GetDependBundleInfos(AssetInfo assetPath); BundleInfo[] GetDependBundleInfos(AssetInfo assetPath);
/// <summary>
/// 获取主资源包名称
/// </summary>
string GetMainBundleName(AssetInfo assetInfo);
/// <summary>
/// 获取依赖的资源包名称集合
/// </summary>
string[] GetDependBundleNames(AssetInfo assetInfo);
/// <summary> /// <summary>
/// 清单是否有效 /// 清单是否有效
/// </summary> /// </summary>

View File

@ -129,6 +129,29 @@ namespace YooAsset
} }
return result.ToArray(); return result.ToArray();
} }
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid() bool IBundleQuery.ManifestValid()
{ {
return _activeManifest != null; return _activeManifest != null;

View File

@ -385,6 +385,29 @@ namespace YooAsset
} }
return result.ToArray(); return result.ToArray();
} }
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid() bool IBundleQuery.ManifestValid()
{ {
return _activeManifest != null; return _activeManifest != null;

View File

@ -214,6 +214,29 @@ namespace YooAsset
} }
return result.ToArray(); return result.ToArray();
} }
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid() bool IBundleQuery.ManifestValid()
{ {
return _activeManifest != null; return _activeManifest != null;

View File

@ -259,6 +259,29 @@ namespace YooAsset
} }
return result.ToArray(); return result.ToArray();
} }
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid() bool IBundleQuery.ManifestValid()
{ {
return _activeManifest != null; return _activeManifest != null;

View File

@ -346,6 +346,7 @@ namespace YooAsset
return _playModeImpl.ActiveManifest.PackageVersion; return _playModeImpl.ActiveManifest.PackageVersion;
} }
#region 资源卸载
/// <summary> /// <summary>
/// 资源回收(卸载引用计数为零的资源) /// 资源回收(卸载引用计数为零的资源)
/// </summary> /// </summary>
@ -355,6 +356,25 @@ namespace YooAsset
_resourceMgr.UnloadUnusedAssets(); _resourceMgr.UnloadUnusedAssets();
} }
/// <summary>
/// 资源回收(尝试卸载指定的资源)
/// </summary>
public void TryUnloadUnusedAsset(string location)
{
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
_resourceMgr.TryUnloadUnusedAsset(assetInfo);
}
/// <summary>
/// 资源回收(尝试卸载指定的资源)
/// </summary>
public void TryUnloadUnusedAsset(AssetInfo assetInfo)
{
DebugCheckInitialize();
_resourceMgr.TryUnloadUnusedAsset(assetInfo);
}
/// <summary> /// <summary>
/// 强制回收所有资源 /// 强制回收所有资源
/// </summary> /// </summary>
@ -363,6 +383,7 @@ namespace YooAsset
DebugCheckInitialize(); DebugCheckInitialize();
_resourceMgr.ForceUnloadAllAssets(); _resourceMgr.ForceUnloadAllAssets();
} }
#endregion
#region 沙盒相关 #region 沙盒相关
/// <summary> /// <summary>