修复多个场景打进一个AB包时,卸载子场景时抛出异常。
pull/28/head
hevinci 2022-07-20 15:05:28 +08:00
parent d5a4b3365f
commit d64b31f6ce
12 changed files with 36 additions and 47 deletions

View File

@ -11,6 +11,7 @@ namespace YooAsset
private static readonly List<AssetBundleLoaderBase> _loaders = new List<AssetBundleLoaderBase>(1000); private static readonly List<AssetBundleLoaderBase> _loaders = new List<AssetBundleLoaderBase>(1000);
private static readonly List<ProviderBase> _providers = new List<ProviderBase>(1000); private static readonly List<ProviderBase> _providers = new List<ProviderBase>(1000);
private static readonly Dictionary<string, SceneOperationHandle> _sceneHandles = new Dictionary<string, SceneOperationHandle>(100); private static readonly Dictionary<string, SceneOperationHandle> _sceneHandles = new Dictionary<string, SceneOperationHandle>(100);
private static long _sceneCreateCount = 0;
private static bool _simulationOnEditor; private static bool _simulationOnEditor;
private static int _loadingMaxNumber; private static int _loadingMaxNumber;
@ -144,24 +145,20 @@ namespace YooAsset
return completedProvider.CreateHandle<SceneOperationHandle>(); return completedProvider.CreateHandle<SceneOperationHandle>();
} }
// 注意:场景句柄永远保持唯一
string providerGUID = assetInfo.ProviderGUID;
if (_sceneHandles.ContainsKey(providerGUID))
return _sceneHandles[providerGUID];
// 如果加载的是主场景,则卸载所有缓存的场景 // 如果加载的是主场景,则卸载所有缓存的场景
if (sceneMode == LoadSceneMode.Single) if (sceneMode == LoadSceneMode.Single)
{ {
UnloadAllScene(); UnloadAllScene();
} }
ProviderBase provider = TryGetProvider(providerGUID); // 注意同一个场景的ProviderGUID每次加载都会变化
if (provider == null) string providerGUID = $"{assetInfo.GUID}-{++_sceneCreateCount}";
ProviderBase provider;
{ {
if (_simulationOnEditor) if (_simulationOnEditor)
provider = new DatabaseSceneProvider(assetInfo, sceneMode, activateOnLoad, priority); provider = new DatabaseSceneProvider(providerGUID, assetInfo, sceneMode, activateOnLoad, priority);
else else
provider = new BundledSceneProvider(assetInfo, sceneMode, activateOnLoad, priority); provider = new BundledSceneProvider(providerGUID, assetInfo, sceneMode, activateOnLoad, priority);
provider.InitSpawnDebugInfo(); provider.InitSpawnDebugInfo();
_providers.Add(provider); _providers.Add(provider);
} }
@ -183,13 +180,14 @@ namespace YooAsset
return completedProvider.CreateHandle<AssetOperationHandle>(); return completedProvider.CreateHandle<AssetOperationHandle>();
} }
ProviderBase provider = TryGetProvider(assetInfo.ProviderGUID); string providerGUID = assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null) if (provider == null)
{ {
if (_simulationOnEditor) if (_simulationOnEditor)
provider = new DatabaseAssetProvider(assetInfo); provider = new DatabaseAssetProvider(providerGUID, assetInfo);
else else
provider = new BundledAssetProvider(assetInfo); provider = new BundledAssetProvider(providerGUID, assetInfo);
provider.InitSpawnDebugInfo(); provider.InitSpawnDebugInfo();
_providers.Add(provider); _providers.Add(provider);
} }
@ -208,13 +206,14 @@ namespace YooAsset
return completedProvider.CreateHandle<SubAssetsOperationHandle>(); return completedProvider.CreateHandle<SubAssetsOperationHandle>();
} }
ProviderBase provider = TryGetProvider(assetInfo.ProviderGUID); string providerGUID = assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null) if (provider == null)
{ {
if (_simulationOnEditor) if (_simulationOnEditor)
provider = new DatabaseSubAssetsProvider(assetInfo); provider = new DatabaseSubAssetsProvider(providerGUID, assetInfo);
else else
provider = new BundledSubAssetsProvider(assetInfo); provider = new BundledSubAssetsProvider(providerGUID, assetInfo);
provider.InitSpawnDebugInfo(); provider.InitSpawnDebugInfo();
_providers.Add(provider); _providers.Add(provider);
} }
@ -223,7 +222,7 @@ namespace YooAsset
internal static void UnloadSubScene(ProviderBase provider) internal static void UnloadSubScene(ProviderBase provider)
{ {
string providerGUID = provider.MainAssetInfo.ProviderGUID; string providerGUID = provider.ProviderGUID;
if (_sceneHandles.ContainsKey(providerGUID) == false) if (_sceneHandles.ContainsKey(providerGUID) == false)
throw new Exception("Should never get here !"); throw new Exception("Should never get here !");
@ -233,12 +232,6 @@ namespace YooAsset
// 卸载未被使用的资源(包括场景) // 卸载未被使用的资源(包括场景)
AssetSystem.UnloadUnusedAssets(); AssetSystem.UnloadUnusedAssets();
// 检验子场景是否销毁
if (provider.IsDestroyed == false)
{
throw new Exception("Should never get here !");
}
} }
internal static void UnloadAllScene() internal static void UnloadAllScene()
{ {
@ -251,16 +244,6 @@ namespace YooAsset
// 卸载未被使用的资源(包括场景) // 卸载未被使用的资源(包括场景)
AssetSystem.UnloadUnusedAssets(); AssetSystem.UnloadUnusedAssets();
// 检验所有场景是否销毁
foreach (var provider in _providers)
{
if (provider.IsSceneProvider())
{
if (provider.IsDestroyed == false)
throw new Exception("Should never get here !");
}
}
} }
internal static AssetBundleLoaderBase CreateOwnerAssetBundleLoader(AssetInfo assetInfo) internal static AssetBundleLoaderBase CreateOwnerAssetBundleLoader(AssetInfo assetInfo)
@ -324,7 +307,7 @@ namespace YooAsset
for (int i = 0; i < _providers.Count; i++) for (int i = 0; i < _providers.Count; i++)
{ {
ProviderBase temp = _providers[i]; ProviderBase temp = _providers[i];
if (temp.MainAssetInfo.ProviderGUID.Equals(providerGUID)) if (temp.ProviderGUID.Equals(providerGUID))
{ {
provider = temp; provider = temp;
break; break;

View File

@ -130,14 +130,14 @@ namespace YooAsset
if (IsDone() == false) if (IsDone() == false)
return; return;
// 注意必须等待所有Provider可以销毁的时候才可以释放Bundle文件。 // 条件1必须等待所有Provider可以销毁
foreach (var provider in _providers) foreach (var provider in _providers)
{ {
if (provider.CanDestroy() == false) if (provider.CanDestroy() == false)
return; return;
} }
// 除了自己没有其它引用 // 条件2除了自己没有其它引用
if (RefCount > _providers.Count) if (RefCount > _providers.Count)
return; return;

View File

@ -17,7 +17,7 @@ namespace YooAsset
} }
} }
public BundledAssetProvider(AssetInfo assetInfo) : base(assetInfo) public BundledAssetProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
{ {
} }
public override void Update() public override void Update()

View File

@ -8,7 +8,7 @@ namespace YooAsset
protected AssetBundleLoaderBase OwnerBundle { private set; get; } protected AssetBundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundleGroup DependBundleGroup { private set; get; } protected DependAssetBundleGroup DependBundleGroup { private set; get; }
public BundledProvider(AssetInfo assetInfo) : base(assetInfo) public BundledProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
{ {
OwnerBundle = AssetSystem.CreateOwnerAssetBundleLoader(assetInfo); OwnerBundle = AssetSystem.CreateOwnerAssetBundleLoader(assetInfo);
OwnerBundle.Reference(); OwnerBundle.Reference();

View File

@ -23,7 +23,7 @@ namespace YooAsset
} }
} }
public BundledSceneProvider(AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(assetInfo) public BundledSceneProvider(string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(providerGUID, assetInfo)
{ {
SceneMode = sceneMode; SceneMode = sceneMode;
_sceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); _sceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);

View File

@ -17,7 +17,7 @@ namespace YooAsset
} }
} }
public BundledSubAssetsProvider(AssetInfo assetInfo) : base(assetInfo) public BundledSubAssetsProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
{ {
} }
public override void Update() public override void Update()

View File

@ -14,7 +14,7 @@ namespace YooAsset
} }
} }
public CompletedProvider(AssetInfo assetInfo) : base(assetInfo) public CompletedProvider(AssetInfo assetInfo) : base(string.Empty, assetInfo)
{ {
} }
public override void Update() public override void Update()

View File

@ -17,7 +17,7 @@ namespace YooAsset
} }
} }
public DatabaseAssetProvider(AssetInfo assetInfo) : base(assetInfo) public DatabaseAssetProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
{ {
} }
public override void Update() public override void Update()

View File

@ -19,7 +19,7 @@ namespace YooAsset
} }
} }
public DatabaseSceneProvider(AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(assetInfo) public DatabaseSceneProvider(string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(providerGUID, assetInfo)
{ {
SceneMode = sceneMode; SceneMode = sceneMode;
_activateOnLoad = activateOnLoad; _activateOnLoad = activateOnLoad;

View File

@ -17,7 +17,7 @@ namespace YooAsset
} }
} }
public DatabaseSubAssetsProvider(AssetInfo assetInfo) : base(assetInfo) public DatabaseSubAssetsProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
{ {
} }
public override void Update() public override void Update()

View File

@ -17,6 +17,11 @@ namespace YooAsset
Fail, Fail,
} }
/// <summary>
/// 资源提供者唯一标识符
/// </summary>
public string ProviderGUID { private set; get; }
/// <summary> /// <summary>
/// 资源信息 /// 资源信息
/// </summary> /// </summary>
@ -85,8 +90,9 @@ namespace YooAsset
private readonly List<OperationHandleBase> _handles = new List<OperationHandleBase>(); private readonly List<OperationHandleBase> _handles = new List<OperationHandleBase>();
public ProviderBase(AssetInfo assetInfo) public ProviderBase(string providerGUID, AssetInfo assetInfo)
{ {
ProviderGUID = providerGUID;
MainAssetInfo = assetInfo; MainAssetInfo = assetInfo;
} }

View File

@ -7,9 +7,9 @@ namespace YooAsset
private string _providerGUID; private string _providerGUID;
/// <summary> /// <summary>
/// 资源提供者唯一标识符 /// 唯一标识符
/// </summary> /// </summary>
internal string ProviderGUID internal string GUID
{ {
get get
{ {