From 460ea091bd1518f4c4c7f663d44a8a7434f1a7df Mon Sep 17 00:00:00 2001 From: hevinci Date: Thu, 26 Oct 2023 17:11:56 +0800 Subject: [PATCH] fix #185 --- .../ResourceManager/Handle/SceneHandle.cs | 17 +++- .../Operation/UnloadSceneOperation.cs | 81 +++++++++++-------- .../Provider/BundledAllAssetsProvider.cs | 2 +- .../Provider/BundledAssetProvider.cs | 2 +- .../Provider/BundledRawFileProvider.cs | 2 +- .../Provider/BundledSceneProvider.cs | 7 +- .../Provider/BundledSubAssetsProvider.cs | 2 +- .../Provider/DatabaseAllAssetsProvider.cs | 2 +- .../Provider/DatabaseAssetProvider.cs | 2 +- .../Provider/DatabaseRawFileProvider.cs | 2 +- .../Provider/DatabaseSceneProvider.cs | 8 +- .../Provider/DatabaseSubAssetsProvider.cs | 2 +- .../ResourceManager/Provider/ProviderBase.cs | 32 ++++---- .../ResourceManager/ResourceManager.cs | 27 +++++-- 14 files changed, 115 insertions(+), 73 deletions(-) diff --git a/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs b/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs index 7b95dcc..d057034 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Handle/SceneHandle.cs @@ -37,6 +37,19 @@ namespace YooAsset } } + /// + /// 场景名称 + /// + public string SceneName + { + get + { + if (IsValidWithWarning == false) + return string.Empty; + return Provider.SceneName; + } + } + /// /// 场景对象 /// @@ -152,10 +165,8 @@ namespace YooAsset } // 卸载子场景 - Scene sceneObject = SceneObject; - Provider.Impl.UnloadSubScene(Provider); { - var operation = new UnloadSceneOperation(sceneObject); + var operation = new UnloadSceneOperation(Provider); OperationSystem.StartOperation(packageName, operation); return operation; } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs index b312ea8..803c37c 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadSceneOperation.cs @@ -8,68 +8,81 @@ namespace YooAsset /// public sealed class UnloadSceneOperation : AsyncOperationBase { - private enum EFlag - { - Normal, - Error, - } private enum ESteps { None, - UnLoad, + CheckError, + PrepareDone, + UnLoadScene, Checking, Done, } - private readonly EFlag _flag; private ESteps _steps = ESteps.None; - private Scene _scene; + private readonly string _error; + private readonly ProviderBase _provider; private AsyncOperation _asyncOp; internal UnloadSceneOperation(string error) { - _flag = EFlag.Error; - Error = error; + _error = error; } - internal UnloadSceneOperation(Scene scene) + internal UnloadSceneOperation(ProviderBase provider) { - _flag = EFlag.Normal; - _scene = scene; + _error = null; + _provider = provider; } internal override void InternalOnStart() { - if (_flag == EFlag.Normal) - { - _steps = ESteps.UnLoad; - } - else if (_flag == EFlag.Error) - { - _steps = ESteps.Done; - Status = EOperationStatus.Failed; - } - else - { - throw new System.NotImplementedException(_flag.ToString()); - } + _steps = ESteps.CheckError; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.UnLoad) + if (_steps == ESteps.CheckError) { - if (_scene.IsValid() && _scene.isLoaded) - { - _asyncOp = SceneManager.UnloadSceneAsync(_scene); - _steps = ESteps.Checking; - } - else + if (string.IsNullOrEmpty(_error) == false) { _steps = ESteps.Done; Status = EOperationStatus.Failed; - Error = "Scene is invalid or is not loaded."; + Error = _error; + return; } + + _steps = ESteps.PrepareDone; + } + + if(_steps == ESteps.PrepareDone) + { + if (_provider.IsDone == false) + return; + + if (_provider.SceneObject.IsValid() == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Scene is invalid !"; + return; + } + + if (_provider.SceneObject.isLoaded == false) + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = "Scene is not loaded !"; + return; + } + + _steps = ESteps.UnLoadScene; + } + + if (_steps == ESteps.UnLoadScene) + { + _asyncOp = SceneManager.UnloadSceneAsync(_provider.SceneObject); + _provider.ResourceMgr.UnloadSubScene(_provider.SceneName); + _steps = ESteps.Checking; } if (_steps == ESteps.Checking) diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs index 3bb1c09..6491bed 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAllAssetsProvider.cs @@ -8,7 +8,7 @@ namespace YooAsset { private AssetBundleRequest _cacheRequest; - public BundledAllAssetsProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(impl, providerGUID, providerPriority, assetInfo) + public BundledAllAssetsProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(manager, providerGUID, providerPriority, assetInfo) { } public override void Update() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs index a202c1a..25be93d 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledAssetProvider.cs @@ -8,7 +8,7 @@ namespace YooAsset { private AssetBundleRequest _cacheRequest; - public BundledAssetProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(impl, providerGUID, providerPriority, assetInfo) + public BundledAssetProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(manager, providerGUID, providerPriority, assetInfo) { } public override void Update() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs index 788a04e..90d1f35 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledRawFileProvider.cs @@ -3,7 +3,7 @@ namespace YooAsset { internal class BundledRawFileProvider : ProviderBase { - public BundledRawFileProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(impl, providerGUID, providerPriority, assetInfo) + public BundledRawFileProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(manager, providerGUID, providerPriority, assetInfo) { } public override void Update() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs index abaf96e..4c2e67c 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSceneProvider.cs @@ -9,14 +9,13 @@ namespace YooAsset internal sealed class BundledSceneProvider : ProviderBase { public readonly LoadSceneMode SceneMode; - private readonly string _sceneName; private readonly bool _suspendLoad; private AsyncOperation _asyncOperation; - public BundledSceneProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad) : base(impl, providerGUID, providerPriority, assetInfo) + public BundledSceneProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad) : base(manager, providerGUID, providerPriority, assetInfo) { SceneMode = sceneMode; - _sceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); + SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); _suspendLoad = suspendLoad; } public override void Update() @@ -73,7 +72,7 @@ namespace YooAsset else { Status = EStatus.Failed; - LastError = $"Failed to load scene : {_sceneName}"; + LastError = $"Failed to load scene : {MainAssetInfo.AssetPath}"; YooLogger.Error(LastError); InvokeCompletion(); } diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs index 02b6261..496f8fa 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/BundledSubAssetsProvider.cs @@ -8,7 +8,7 @@ namespace YooAsset { private AssetBundleRequest _cacheRequest; - public BundledSubAssetsProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(impl, providerGUID, providerPriority, assetInfo) + public BundledSubAssetsProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(manager, providerGUID, providerPriority, assetInfo) { } public override void Update() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs index c0f49ca..4dd1c48 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAllAssetsProvider.cs @@ -6,7 +6,7 @@ namespace YooAsset { internal sealed class DatabaseAllAssetsProvider : ProviderBase { - public DatabaseAllAssetsProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(impl, providerGUID, providerPriority, assetInfo) + public DatabaseAllAssetsProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(manager, providerGUID, providerPriority, assetInfo) { } public override void Update() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAssetProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAssetProvider.cs index 3974213..89b526c 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAssetProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseAssetProvider.cs @@ -6,7 +6,7 @@ namespace YooAsset { internal sealed class DatabaseAssetProvider : ProviderBase { - public DatabaseAssetProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(impl, providerGUID, providerPriority, assetInfo) + public DatabaseAssetProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(manager, providerGUID, providerPriority, assetInfo) { } public override void Update() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseRawFileProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseRawFileProvider.cs index c9cd24d..3d9de80 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseRawFileProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseRawFileProvider.cs @@ -3,7 +3,7 @@ namespace YooAsset { internal class DatabaseRawFileProvider : ProviderBase { - public DatabaseRawFileProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(impl, providerGUID, providerPriority, assetInfo) + public DatabaseRawFileProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(manager, providerGUID, providerPriority, assetInfo) { } public override void Update() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSceneProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSceneProvider.cs index 17223da..2619f94 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSceneProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSceneProvider.cs @@ -1,4 +1,7 @@ -using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using UnityEngine; using UnityEngine.SceneManagement; namespace YooAsset @@ -9,9 +12,10 @@ namespace YooAsset private readonly bool _suspendLoad; private AsyncOperation _asyncOperation; - public DatabaseSceneProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad) : base(impl, providerGUID, providerPriority, assetInfo) + public DatabaseSceneProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad) : base(manager, providerGUID, providerPriority, assetInfo) { SceneMode = sceneMode; + SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); _suspendLoad = suspendLoad; } public override void Update() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSubAssetsProvider.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSubAssetsProvider.cs index a6cf1b3..6c1e2a0 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSubAssetsProvider.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/DatabaseSubAssetsProvider.cs @@ -6,7 +6,7 @@ namespace YooAsset { internal sealed class DatabaseSubAssetsProvider : ProviderBase { - public DatabaseSubAssetsProvider(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(impl, providerGUID, providerPriority, assetInfo) + public DatabaseSubAssetsProvider(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo) : base(manager, providerGUID, providerPriority, assetInfo) { } public override void Update() diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderBase.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderBase.cs index 0f29e81..0364ad3 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderBase.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderBase.cs @@ -31,7 +31,7 @@ namespace YooAsset /// /// 所属资源系统 /// - public ResourceManager Impl { private set; get; } + public ResourceManager ResourceMgr { private set; get; } /// /// 资源信息 @@ -53,6 +53,11 @@ namespace YooAsset /// public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; } + /// + /// 加载的场景名称 + /// + public string SceneName { protected set; get; } + /// /// 原生文件路径 /// @@ -103,21 +108,21 @@ namespace YooAsset private readonly List _handles = new List(); - public ProviderBase(ResourceManager impl, string providerGUID, uint providerPriority, AssetInfo assetInfo) + public ProviderBase(ResourceManager manager, string providerGUID, uint providerPriority, AssetInfo assetInfo) { - Impl = impl; + ResourceMgr = manager; ProviderGUID = providerGUID; ProviderPriority = providerPriority; MainAssetInfo = assetInfo; // 创建资源包加载器 - if (impl != null) + if (manager != null) { - OwnerBundle = impl.CreateOwnerAssetBundleLoader(assetInfo); + OwnerBundle = manager.CreateOwnerAssetBundleLoader(assetInfo); OwnerBundle.Reference(); OwnerBundle.AddProvider(this); - var dependList = impl.CreateDependAssetBundleLoaders(assetInfo); + var dependList = manager.CreateDependAssetBundleLoaders(assetInfo); DependBundles = new DependAssetBundles(dependList); DependBundles.Reference(); } @@ -128,14 +133,6 @@ namespace YooAsset /// public abstract void Update(); - /// - /// 排序接口实现方法 - /// - public int CompareTo(ProviderBase other) - { - return other.ProviderPriority.CompareTo(this.ProviderPriority); - } - /// /// 销毁资源提供者 /// @@ -281,6 +278,13 @@ namespace YooAsset } } + #region 排序接口实现 + public int CompareTo(ProviderBase other) + { + return other.ProviderPriority.CompareTo(this.ProviderPriority); + } + #endregion + #region 异步编程相关 private TaskCompletionSource _taskCompletionSource; protected void InvokeCompletion() diff --git a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs index 0e76617..f83dfa9 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs @@ -218,7 +218,9 @@ namespace YooAsset } /// - /// 加载场景 + /// 加载场景对象 + /// 注意:返回的场景句柄是唯一的,每个场景句柄对应自己的场景提供者对象。 + /// 注意:业务逻辑层应该避免同时加载一个子场景。 /// public SceneHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad, uint priority) { @@ -387,15 +389,24 @@ namespace YooAsset return provider.CreateHandle(); } - internal void UnloadSubScene(ProviderBase provider) + internal void UnloadSubScene(string sceneName) { - string providerGUID = provider.ProviderGUID; - if (_sceneHandles.ContainsKey(providerGUID) == false) - throw new Exception("Should never get here !"); + List removeKeys = new List(); + foreach (var valuePair in _sceneHandles) + { + var sceneHandle = valuePair.Value; + if (sceneHandle.SceneName == sceneName) + { + // 释放子场景句柄 + sceneHandle.ReleaseInternal(); + removeKeys.Add(valuePair.Key); + } + } - // 释放子场景句柄 - _sceneHandles[providerGUID].ReleaseInternal(); - _sceneHandles.Remove(providerGUID); + foreach (string key in removeKeys) + { + _sceneHandles.Remove(key); + } } private void UnloadAllScene() {