From dafab0e95ace23e39f10287e09734e4c67409d80 Mon Sep 17 00:00:00 2001 From: godzzz Date: Sat, 18 May 2024 02:32:04 +0400 Subject: [PATCH] [v0.1.18] Dependency updated; Test new scene activation --- .../Activation/CompositeSceneActivation.cs | 30 +++++++++ .../CompositeSceneActivation.cs.meta | 3 + Runtime/Activation/EmptySceneActivation.cs | 2 - Runtime/Activation/ExternalSceneActivation.cs | 48 ++++++++++++++ .../ExternalSceneActivation.cs.meta | 3 + Runtime/Activation/ISceneActivation.cs | 2 - .../Activation/PercentageSceneActivation.cs | 2 - Runtime/Operations/SceneChangeOperation.cs | 16 ++--- Runtime/Operations/SceneLoadOperation.cs | 65 ++++++++----------- Runtime/Operations/SceneReloadOperation.cs | 18 +++-- Runtime/Operations/SceneUnloadOperation.cs | 11 ++-- package.json | 4 +- 12 files changed, 138 insertions(+), 66 deletions(-) create mode 100644 Runtime/Activation/CompositeSceneActivation.cs create mode 100644 Runtime/Activation/CompositeSceneActivation.cs.meta create mode 100644 Runtime/Activation/ExternalSceneActivation.cs create mode 100644 Runtime/Activation/ExternalSceneActivation.cs.meta diff --git a/Runtime/Activation/CompositeSceneActivation.cs b/Runtime/Activation/CompositeSceneActivation.cs new file mode 100644 index 0000000..e930eef --- /dev/null +++ b/Runtime/Activation/CompositeSceneActivation.cs @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 +// © 2023-2024 Nikolay Melnikov + +using UnityEngine; + +namespace Depra.Scenes.Activation +{ + public sealed class CompositeSceneActivation : ISceneActivation + { + private readonly ISceneActivation[] _activations; + + public CompositeSceneActivation(params ISceneActivation[] activations) => _activations = activations; + + void ISceneActivation.BeforeLoading(AsyncOperation operation) + { + foreach (var activation in _activations) + { + activation.BeforeLoading(operation); + } + } + + void ISceneActivation.OnProgress(AsyncOperation operation) + { + foreach (var activation in _activations) + { + activation.OnProgress(operation); + } + } + } +} \ No newline at end of file diff --git a/Runtime/Activation/CompositeSceneActivation.cs.meta b/Runtime/Activation/CompositeSceneActivation.cs.meta new file mode 100644 index 0000000..575d40e --- /dev/null +++ b/Runtime/Activation/CompositeSceneActivation.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8a3d31c96ff24d0e8b9a104caede238a +timeCreated: 1715979896 \ No newline at end of file diff --git a/Runtime/Activation/EmptySceneActivation.cs b/Runtime/Activation/EmptySceneActivation.cs index 9ee1279..684f57e 100644 --- a/Runtime/Activation/EmptySceneActivation.cs +++ b/Runtime/Activation/EmptySceneActivation.cs @@ -10,7 +10,5 @@ public sealed class EmptySceneActivation : ISceneActivation void ISceneActivation.BeforeLoading(AsyncOperation operation) { } void ISceneActivation.OnProgress(AsyncOperation operation) { } - - void ISceneActivation.AfterLoading() { } } } \ No newline at end of file diff --git a/Runtime/Activation/ExternalSceneActivation.cs b/Runtime/Activation/ExternalSceneActivation.cs new file mode 100644 index 0000000..df25e2f --- /dev/null +++ b/Runtime/Activation/ExternalSceneActivation.cs @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Apache-2.0 +// © 2023-2024 Nikolay Melnikov + +using Depra.Expectation; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace Depra.Scenes.Activation +{ + public sealed class ExternalSceneActivation : ISceneActivation + { + private readonly IExpectant _externalExpectant; + + private Scene _loadedScene; + private Expectant _loadingExpectant; + + public ExternalSceneActivation(IExpectant expectant) => _externalExpectant = expectant; + + private void Activate() + { + SceneManager.SetActiveScene(_loadedScene); + _loadingExpectant?.Dispose(); + _externalExpectant?.Dispose(); + } + + private void OnSceneLoaded(Scene scene, LoadSceneMode mode) + { + _loadedScene = scene; + SceneManager.sceneLoaded -= OnSceneLoaded; + if (_loadedScene.IsValid()) + { + _loadingExpectant?.SetReady(); + } + } + + void ISceneActivation.BeforeLoading(AsyncOperation operation) + { + SceneManager.sceneLoaded += OnSceneLoaded; + new GroupExpectant.And() + .With(_externalExpectant) + .With(_loadingExpectant = new Expectant()) + .Build() + .Subscribe(Activate); + } + + void ISceneActivation.OnProgress(AsyncOperation operation) { } + } +} \ No newline at end of file diff --git a/Runtime/Activation/ExternalSceneActivation.cs.meta b/Runtime/Activation/ExternalSceneActivation.cs.meta new file mode 100644 index 0000000..995450f --- /dev/null +++ b/Runtime/Activation/ExternalSceneActivation.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 14f733c06cd8459f9dd63e9a3972cadb +timeCreated: 1715978366 \ No newline at end of file diff --git a/Runtime/Activation/ISceneActivation.cs b/Runtime/Activation/ISceneActivation.cs index e082979..4f45552 100644 --- a/Runtime/Activation/ISceneActivation.cs +++ b/Runtime/Activation/ISceneActivation.cs @@ -10,7 +10,5 @@ public interface ISceneActivation void BeforeLoading(AsyncOperation operation); void OnProgress(AsyncOperation operation); - - void AfterLoading(); } } \ No newline at end of file diff --git a/Runtime/Activation/PercentageSceneActivation.cs b/Runtime/Activation/PercentageSceneActivation.cs index 488cbbb..9d969f1 100644 --- a/Runtime/Activation/PercentageSceneActivation.cs +++ b/Runtime/Activation/PercentageSceneActivation.cs @@ -22,7 +22,5 @@ void ISceneActivation.OnProgress(AsyncOperation operation) operation.allowSceneActivation = true; } } - - void ISceneActivation.AfterLoading() { } } } \ No newline at end of file diff --git a/Runtime/Operations/SceneChangeOperation.cs b/Runtime/Operations/SceneChangeOperation.cs index f89de9f..b34420f 100644 --- a/Runtime/Operations/SceneChangeOperation.cs +++ b/Runtime/Operations/SceneChangeOperation.cs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // © 2023-2024 Nikolay Melnikov +using System; using System.Threading; using System.Threading.Tasks; using Depra.Expectation; @@ -13,36 +14,35 @@ namespace Depra.Scenes.Operations { public sealed class SceneChangeOperation : ILoadingOperation { + private readonly IExpectant _finishExpectant; private readonly ISceneActivation _activation; private readonly SceneDefinition _desiredScene; private readonly SceneDefinition _previousScene; - private readonly IExpectant _loadedSceneActivationExpectant; private readonly OperationDescription _description; public SceneChangeOperation(SceneDefinition from, SceneDefinition to, - OperationDescription description, ISceneActivation activation, - IExpectant loadedSceneActivationExpectant = null) + OperationDescription description, ISceneActivation activation, IExpectant finishExpectant = null) { _desiredScene = to; _previousScene = from; _activation = activation; _description = description; - _loadedSceneActivationExpectant = loadedSceneActivationExpectant; + _finishExpectant = finishExpectant; } OperationDescription ILoadingOperation.Description => _description; - public async Task Load(ProgressCallback onProgress, CancellationToken token) + public async Task Load(IProgress progress, CancellationToken token) { if (_desiredScene.IsActive()) { throw new UnexpectedSceneSwitch(_desiredScene.DisplayName); } - await new SceneLoadOperation(_desiredScene, _description, _activation, _loadedSceneActivationExpectant) - .Load(onProgress, token); + await new SceneLoadOperation(_desiredScene, _description, _activation, _finishExpectant) + .Load(progress, token); await new SceneUnloadOperation(_previousScene, _description) - .Load(onProgress, token); + .Load(progress, token); } } } \ No newline at end of file diff --git a/Runtime/Operations/SceneLoadOperation.cs b/Runtime/Operations/SceneLoadOperation.cs index f79d967..1235746 100644 --- a/Runtime/Operations/SceneLoadOperation.cs +++ b/Runtime/Operations/SceneLoadOperation.cs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // © 2023-2024 Nikolay Melnikov +using System; using System.Threading; using System.Threading.Tasks; using Depra.Expectation; @@ -13,81 +14,67 @@ namespace Depra.Scenes.Operations { public sealed class SceneLoadOperation : ILoadingOperation { + private readonly IExpectant _finishExpectant; private readonly ISceneActivation _activation; private readonly SceneDefinition _desiredScene; - private readonly IExpectant _activationExpectant; private readonly OperationDescription _description; - private Expectant _loadingExpectant; - public SceneLoadOperation(SceneDefinition desiredScene, OperationDescription description, - ISceneActivation activation, IExpectant activationExpectant = null) + ISceneActivation activation, IExpectant finishExpectant = null) { - _activation = activation; _description = description; _desiredScene = desiredScene; - _activationExpectant = activationExpectant; + _finishExpectant = finishExpectant; + _activation = desiredScene.ActivateOnLoad ? activation : new EmptySceneActivation(); } OperationDescription ILoadingOperation.Description => _description; - public async Task Load(ProgressCallback onProgress, CancellationToken token) + public async Task Load(IProgress progress, CancellationToken token) { - onProgress?.Invoke(0); - if (_desiredScene.ActivateOnLoad) - { - SetupActivation(); - } - + progress.Report(0); var operation = SceneManager.LoadSceneAsync(_desiredScene.DisplayName, _desiredScene.LoadMode); if (operation == null) { - onProgress?.Invoke(1); + progress.Report(1); return; } _activation.BeforeLoading(operation); while (operation.isDone == false) { - onProgress?.Invoke(operation.progress); + progress.Report(operation.progress); _activation.OnProgress(operation); await Task.Yield(); } - onProgress?.Invoke(1); + progress.Report(1); + await AfterLoading(); } - private void SetupActivation() + private async Task AfterLoading() { - SceneManager.sceneLoaded += OnSceneLoaded; - new GroupExpectant.And() - .With(_loadingExpectant = new Expectant()) - .With(_activationExpectant) - .Build() - .Subscribe(Activate); - } - - private void OnSceneLoaded(Scene scene, LoadSceneMode mode) - { - SceneManager.sceneLoaded -= OnSceneLoaded; - if (scene.IsValid()) + if (_finishExpectant == null) { - _loadingExpectant?.SetReady(); + return; } - } - private void Activate() - { - var scene = SceneManager.GetSceneByName(_desiredScene.DisplayName); - SceneManager.SetActiveScene(scene); - Dispose(); + await _finishExpectant.AsTask(); + if (_desiredScene.ActivateOnLoad) + { + await Task.Yield(); + ActivateScene(); + } } - private void Dispose() + private void ActivateScene() { - _loadingExpectant?.Dispose(); - _activationExpectant?.Dispose(); + var loadedScene = SceneManager.GetSceneByName(_desiredScene.DisplayName); + if (loadedScene.IsValid()) + { + SceneManager.SetActiveScene(loadedScene); + } } } } \ No newline at end of file diff --git a/Runtime/Operations/SceneReloadOperation.cs b/Runtime/Operations/SceneReloadOperation.cs index e4575e5..54be51a 100644 --- a/Runtime/Operations/SceneReloadOperation.cs +++ b/Runtime/Operations/SceneReloadOperation.cs @@ -1,8 +1,10 @@ // SPDX-License-Identifier: Apache-2.0 // © 2023-2024 Nikolay Melnikov +using System; using System.Threading; using System.Threading.Tasks; +using Depra.Expectation; using Depra.Loading.Operations; using Depra.Scenes.Activation; using Depra.Scenes.Definitions; @@ -12,23 +14,27 @@ namespace Depra.Scenes.Change { public sealed class SceneReloadOperation : ILoadingOperation { + private readonly IExpectant _finishExpectant; + private readonly ISceneActivation _activation; private readonly SceneDefinition _activeScene; private readonly OperationDescription _description; - private readonly ISceneActivation _activation; - public SceneReloadOperation(SceneDatabase scenes, ISceneActivation activation) + public SceneReloadOperation(SceneDatabase scenes, ISceneActivation activation, IExpectant finishExpectant = null) { - _activeScene = scenes.Active; _activation = activation; + _activeScene = scenes.Active; + _finishExpectant = finishExpectant; _description = OperationDescription.Default(_activeScene.DisplayName); } OperationDescription ILoadingOperation.Description => _description; - public async Task Load(ProgressCallback onProgress, CancellationToken token) + public async Task Load(IProgress progress, CancellationToken token) { - await new SceneUnloadOperation(_activeScene, _description).Load(onProgress, token); - await new SceneLoadOperation(_activeScene, _description, _activation).Load(onProgress, token); + await new SceneUnloadOperation(_activeScene, _description) + .Load(progress, token); + await new SceneLoadOperation(_activeScene, _description, _activation, _finishExpectant) + .Load(progress, token); } } } \ No newline at end of file diff --git a/Runtime/Operations/SceneUnloadOperation.cs b/Runtime/Operations/SceneUnloadOperation.cs index 5f91c55..7d13e37 100644 --- a/Runtime/Operations/SceneUnloadOperation.cs +++ b/Runtime/Operations/SceneUnloadOperation.cs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // © 2023-2024 Nikolay Melnikov +using System; using System.Threading; using System.Threading.Tasks; using Depra.Loading.Operations; @@ -22,28 +23,28 @@ public SceneUnloadOperation(SceneDefinition scene, OperationDescription descript OperationDescription ILoadingOperation.Description => _description; - public async Task Load(ProgressCallback onProgress, CancellationToken token) + public async Task Load(IProgress progress, CancellationToken token) { if (_scene.CanBeUnloaded == false) { return; } - onProgress?.Invoke(0); + progress.Report(0); var operation = SceneManager.UnloadSceneAsync(_scene.DisplayName); if (operation == null) { - onProgress?.Invoke(1); + progress.Report(1); return; } while (operation.isDone == false) { - onProgress?.Invoke(operation.progress); + progress.Report(operation.progress); await Task.Yield(); } - onProgress?.Invoke(1); + progress.Report(1); } } } \ No newline at end of file diff --git a/package.json b/package.json index 7b25682..d146a01 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "com.depra.scenes", - "version": "0.1.17", + "version": "0.1.18", "displayName": "Depra.Scenes", "description": "", "unity": "2022.3", "license": "Apache-2.0", "dependencies": { - "com.depra.loading.unity": "0.0.7", + "com.depra.loading.unity": "0.1.7", "com.depra.inspector.unity": "0.0.5" }, "keywords": [