From 69c001a65b08eb76597dbaee658168f5ace861f1 Mon Sep 17 00:00:00 2001 From: Haruki Yano Date: Fri, 2 May 2025 16:34:12 +0900 Subject: [PATCH 1/7] PageTransitionHandler --- .../Runtime/Core/Page/PageContainer.cs | 100 ++---------------- .../Core/Page/PageTransitionHandler.cs | 92 ++++++++++++++++ .../Core/Page/PageTransitionHandler.cs.meta | 3 + 3 files changed, 105 insertions(+), 90 deletions(-) create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs.meta diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs index cd37a841..d41eba95 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs @@ -1,13 +1,10 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using UnityEngine; using UnityEngine.Assertions; using UnityEngine.UI; -using UnityScreenNavigator.Runtime.Core.Modal; using UnityScreenNavigator.Runtime.Core.Shared; -using UnityScreenNavigator.Runtime.Core.Sheet; using UnityScreenNavigator.Runtime.Foundation; using UnityScreenNavigator.Runtime.Foundation.AssetLoader; using UnityScreenNavigator.Runtime.Foundation.Coroutine; @@ -45,6 +42,8 @@ private readonly Dictionary> _assetLoadHandl private bool _isActivePageStacked; public static List Instances { get; } = new List(); + private PageTransitionHandler _transitionHandler; + /// /// By default, in is used. /// If this property is set, it is used instead. @@ -58,7 +57,7 @@ public IAssetLoader AssetLoader /// /// True if in transition. /// - public bool IsInTransition { get; private set; } + public bool IsInTransition => _transitionHandler.IsInTransition; /// /// List of PageIds sorted in the order they are stacked. @@ -84,6 +83,7 @@ private void Awake() if (!string.IsNullOrWhiteSpace(_name)) InstanceCacheByName.Add(_name, this); _canvasGroup = gameObject.GetOrAddComponent(); + _transitionHandler = new PageTransitionHandler(this); } private void OnDestroy() @@ -275,24 +275,7 @@ private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnim throw new InvalidOperationException( "Cannot transition because the screen is already in transition."); - IsInTransition = true; - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - foreach (var pageContainer in Instances) - pageContainer.Interactable = false; - foreach (var modalContainer in ModalContainer.Instances) - modalContainer.Interactable = false; - foreach (var sheetContainer in SheetContainer.Instances) - sheetContainer.Interactable = false; - } - else - { - Interactable = false; - } - } + _transitionHandler.Begin(); // Setup var assetLoadHandle = loadAsync @@ -350,7 +333,8 @@ private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnim _pages.Add(pageId, enterPage); _orderedPageIds.Add(pageId); - IsInTransition = false; + + _transitionHandler.End(); // Postprocess if (exitPage != null) @@ -375,30 +359,6 @@ private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnim } _isActivePageStacked = stack; - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // If there's a container in transition, it should restore Interactive to true when the transition is finished. - // So, do nothing here if there's a transitioning container. - if (Instances.All(x => !x.IsInTransition) - && ModalContainer.Instances.All(x => !x.IsInTransition) - && SheetContainer.Instances.All(x => !x.IsInTransition)) - { - foreach (var pageContainer in Instances) - pageContainer.Interactable = true; - foreach (var modalContainer in ModalContainer.Instances) - modalContainer.Interactable = true; - foreach (var sheetContainer in SheetContainer.Instances) - sheetContainer.Interactable = true; - } - } - else - { - Interactable = true; - } - } } private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) @@ -413,24 +373,7 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) throw new InvalidOperationException( "Cannot transition because the screen is already in transition."); - IsInTransition = true; - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - foreach (var pageContainer in Instances) - pageContainer.Interactable = false; - foreach (var modalContainer in ModalContainer.Instances) - modalContainer.Interactable = false; - foreach (var sheetContainer in SheetContainer.Instances) - sheetContainer.Interactable = false; - } - else - { - Interactable = false; - } - } + _transitionHandler.Begin(); var exitPageId = _orderedPageIds[_orderedPageIds.Count - 1]; var exitPage = _pages[exitPageId]; @@ -479,7 +422,8 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) _pages.Remove(unusedPageId); _orderedPageIds.RemoveAt(_orderedPageIds.Count - 1); } - IsInTransition = false; + + _transitionHandler.End(); // Postprocess exitPage.AfterExit(false, enterPage); @@ -502,30 +446,6 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) } _isActivePageStacked = true; - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // If there's a container in transition, it should restore Interactive to true when the transition is finished. - // So, do nothing here if there's a transitioning container. - if (Instances.All(x => !x.IsInTransition) - && ModalContainer.Instances.All(x => !x.IsInTransition) - && SheetContainer.Instances.All(x => !x.IsInTransition)) - { - foreach (var pageContainer in Instances) - pageContainer.Interactable = true; - foreach (var modalContainer in ModalContainer.Instances) - modalContainer.Interactable = true; - foreach (var sheetContainer in SheetContainer.Instances) - sheetContainer.Interactable = true; - } - } - else - { - Interactable = true; - } - } } public AsyncProcessHandle Preload(string resourceKey, bool loadAsync = true) diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs new file mode 100644 index 00000000..0afdc605 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs @@ -0,0 +1,92 @@ +using System; +using System.Linq; +using UnityEngine.Assertions; +using UnityScreenNavigator.Runtime.Core.Modal; +using UnityScreenNavigator.Runtime.Core.Shared; +using UnityScreenNavigator.Runtime.Core.Sheet; + +namespace UnityScreenNavigator.Runtime.Core.Page +{ + public sealed class PageTransitionHandler + { + private readonly PageContainer _container; + + public PageTransitionHandler(PageContainer container) + { + Assert.IsNotNull(container); + _container = container; + } + + public bool IsInTransition { get; private set; } + + public void Begin() + { + if (IsInTransition) + throw new InvalidOperationException("Transition already in progress."); + + IsInTransition = true; + + if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) + return; + + if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) + { + // 他のコンテナがトランジション中の場合は、すでにそのコンテナの開始処理でSetAllContainersInteractableが実行されているので、ここでは何もしない + if (!AllContainersFinishedTransition()) + return; + + SetAllContainersInteractable(false); + } + else + { + SetSelfContainersInteractable(false); + } + } + + public void End() + { + if (!IsInTransition) + throw new InvalidOperationException("Transition has not started."); + + IsInTransition = false; + + if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) + return; + + if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) + { + // 他のコンテナがトランジション中の場合は、そのコンテナの終了処理でSetAllContainersInteractableが実行されるので、ここでは何もしない + if (!AllContainersFinishedTransition()) + return; + + SetAllContainersInteractable(true); + } + else + { + SetSelfContainersInteractable(true); + } + } + + private bool AllContainersFinishedTransition() + { + return PageContainer.Instances.All(x => !x.IsInTransition) + && ModalContainer.Instances.All(x => !x.IsInTransition) + && SheetContainer.Instances.All(x => !x.IsInTransition); + } + + private void SetAllContainersInteractable(bool value) + { + foreach (var container in PageContainer.Instances) + container.Interactable = value; + foreach (var container in ModalContainer.Instances) + container.Interactable = value; + foreach (var container in SheetContainer.Instances) + container.Interactable = value; + } + + private void SetSelfContainersInteractable(bool value) + { + _container.Interactable = value; + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs.meta new file mode 100644 index 00000000..031e6b81 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 509cdc07b6c4413a89f0eba34c6ae185 +timeCreated: 1746165015 \ No newline at end of file From 3d927f82c688cbac7dc9366af0fa1b2eecc02a42 Mon Sep 17 00:00:00 2001 From: Haruki Yano Date: Fri, 2 May 2025 16:41:45 +0900 Subject: [PATCH 2/7] =?UTF-8?q?ModalTransitionHandler=E3=81=A8SheetTransit?= =?UTF-8?q?ionHandler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/Core/Modal/ModalContainer.cs | 94 ++---------------- .../Core/Modal/ModalTransitionHandler.cs | 92 ++++++++++++++++++ .../Core/Modal/ModalTransitionHandler.cs.meta | 11 +++ .../Runtime/Core/Sheet/SheetContainer.cs | 95 ++----------------- .../Core/Sheet/SheetTransitionHandler.cs | 92 ++++++++++++++++++ .../Core/Sheet/SheetTransitionHandler.cs.meta | 11 +++ 6 files changed, 221 insertions(+), 174 deletions(-) create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs.meta diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs index c8190fdf..ad09992d 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs @@ -49,6 +49,7 @@ private readonly Dictionary> _assetLoadHandl public static List Instances { get; } = new List(); private IModalBackdropHandler _backdropHandler; + private ModalTransitionHandler _transitionHandler; /// /// By default, in is used. @@ -63,7 +64,7 @@ public IAssetLoader AssetLoader /// /// True if in transition. /// - public bool IsInTransition { get; private set; } + public bool IsInTransition => _transitionHandler.IsInTransition; /// /// List of ModalIds sorted in the order they are stacked. @@ -94,6 +95,7 @@ private void Awake() _canvasGroup = gameObject.GetOrAddComponent(); _backdropHandler = ModalBackdropHandlerFactory.Create(_backdropStrategy, _backdropPrefab); + _transitionHandler = new ModalTransitionHandler(this); } private void OnDestroy() @@ -281,24 +283,7 @@ private IEnumerator PushRoutine(Type modalType, string resourceKey, bool playAni throw new InvalidOperationException( "Cannot transition because the screen is already in transition."); - IsInTransition = true; - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - foreach (var pageContainer in PageContainer.Instances) - pageContainer.Interactable = false; - foreach (var modalContainer in Instances) - modalContainer.Interactable = false; - foreach (var sheetContainer in SheetContainer.Instances) - sheetContainer.Interactable = false; - } - else - { - Interactable = false; - } - } + _transitionHandler.Begin(); var assetLoadHandle = loadAsync ? AssetLoader.LoadAsync(resourceKey) @@ -353,7 +338,7 @@ private IEnumerator PushRoutine(Type modalType, string resourceKey, bool playAni // End Transition _modals.Add(modalId, enterModal); _orderedModalIds.Add(modalId); - IsInTransition = false; + _transitionHandler.End(); // Postprocess if (exitModal != null) exitModal.AfterExit(true, enterModal); @@ -361,30 +346,6 @@ private IEnumerator PushRoutine(Type modalType, string resourceKey, bool playAni enterModal.AfterEnter(true, exitModal); foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.AfterPush(enterModal, exitModal); - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // If there's a container in transition, it should restore Interactive to true when the transition is finished. - // So, do nothing here if there's a transitioning container. - if (PageContainer.Instances.All(x => !x.IsInTransition) - && Instances.All(x => !x.IsInTransition) - && SheetContainer.Instances.All(x => !x.IsInTransition)) - { - foreach (var pageContainer in PageContainer.Instances) - pageContainer.Interactable = true; - foreach (var modalContainer in Instances) - modalContainer.Interactable = true; - foreach (var sheetContainer in SheetContainer.Instances) - sheetContainer.Interactable = true; - } - } - else - { - Interactable = true; - } - } } private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) @@ -399,24 +360,7 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) throw new InvalidOperationException( "Cannot transition because the screen is already in transition."); - IsInTransition = true; - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - foreach (var pageContainer in PageContainer.Instances) - pageContainer.Interactable = false; - foreach (var modalContainer in Instances) - modalContainer.Interactable = false; - foreach (var sheetContainer in SheetContainer.Instances) - sheetContainer.Interactable = false; - } - else - { - Interactable = false; - } - } + _transitionHandler.Begin(); var exitModalId = _orderedModalIds[_orderedModalIds.Count - 1]; var exitModal = _modals[exitModalId]; @@ -475,7 +419,7 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) _modals.Remove(unusedModalId); _orderedModalIds.RemoveAt(_orderedModalIds.Count - 1); } - IsInTransition = false; + _transitionHandler.End(); // Postprocess exitModal.AfterExit(false, enterModal); @@ -498,30 +442,6 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) _assetLoadHandles.Remove(unusedModalId); _backdropHandler.AfterModalExit(exitModal, unusedModalIndex, playAnimation); } - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // If there's a container in transition, it should restore Interactive to true when the transition is finished. - // So, do nothing here if there's a transitioning container. - if (PageContainer.Instances.All(x => !x.IsInTransition) - && Instances.All(x => !x.IsInTransition) - && SheetContainer.Instances.All(x => !x.IsInTransition)) - { - foreach (var pageContainer in PageContainer.Instances) - pageContainer.Interactable = true; - foreach (var modalContainer in Instances) - modalContainer.Interactable = true; - foreach (var sheetContainer in SheetContainer.Instances) - sheetContainer.Interactable = true; - } - } - else - { - Interactable = true; - } - } } public AsyncProcessHandle Preload(string resourceKey, bool loadAsync = true) diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs new file mode 100644 index 00000000..ed9bf907 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs @@ -0,0 +1,92 @@ +using System; +using System.Linq; +using UnityEngine.Assertions; +using UnityScreenNavigator.Runtime.Core.Page; +using UnityScreenNavigator.Runtime.Core.Shared; +using UnityScreenNavigator.Runtime.Core.Sheet; + +namespace UnityScreenNavigator.Runtime.Core.Modal +{ + public sealed class ModalTransitionHandler + { + private readonly ModalContainer _container; + + public ModalTransitionHandler(ModalContainer container) + { + Assert.IsNotNull(container); + _container = container; + } + + public bool IsInTransition { get; private set; } + + public void Begin() + { + if (IsInTransition) + throw new InvalidOperationException("Transition already in progress."); + + IsInTransition = true; + + if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) + return; + + if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) + { + // 他のコンテナがトランジション中の場合は、すでにそのコンテナの開始処理でSetAllContainersInteractableが実行されているので、ここでは何もしない + if (!AllContainersFinishedTransition()) + return; + + SetAllContainersInteractable(false); + } + else + { + SetSelfContainersInteractable(false); + } + } + + public void End() + { + if (!IsInTransition) + throw new InvalidOperationException("Transition has not started."); + + IsInTransition = false; + + if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) + return; + + if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) + { + // 他のコンテナがトランジション中の場合は、そのコンテナの終了処理でSetAllContainersInteractableが実行されるので、ここでは何もしない + if (!AllContainersFinishedTransition()) + return; + + SetAllContainersInteractable(true); + } + else + { + SetSelfContainersInteractable(true); + } + } + + private bool AllContainersFinishedTransition() + { + return PageContainer.Instances.All(x => !x.IsInTransition) + && ModalContainer.Instances.All(x => !x.IsInTransition) + && SheetContainer.Instances.All(x => !x.IsInTransition); + } + + private void SetAllContainersInteractable(bool value) + { + foreach (var container in PageContainer.Instances) + container.Interactable = value; + foreach (var container in ModalContainer.Instances) + container.Interactable = value; + foreach (var container in SheetContainer.Instances) + container.Interactable = value; + } + + private void SetSelfContainersInteractable(bool value) + { + _container.Interactable = value; + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs.meta new file mode 100644 index 00000000..d5a588c7 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f564c54127b994bdbbe5c073152b360b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs index 994e4962..46f5bae1 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs @@ -37,6 +37,8 @@ private readonly Dictionary> _assetLoadHandl private CanvasGroup _canvasGroup; public static List Instances { get; } = new List(); + private SheetTransitionHandler _transitionHandler; + /// /// By default, in is used. /// If this property is set, it is used instead. @@ -63,7 +65,7 @@ public Sheet ActiveSheet /// /// True if in transition. /// - public bool IsInTransition { get; private set; } + public bool IsInTransition => _transitionHandler.IsInTransition; /// /// Registered sheets. @@ -84,6 +86,7 @@ private void Awake() if (!string.IsNullOrWhiteSpace(_name)) InstanceCacheByName.Add(_name, this); _canvasGroup = gameObject.GetOrAddComponent(); + _transitionHandler = new SheetTransitionHandler(this); } private void OnDestroy() @@ -289,24 +292,7 @@ private IEnumerator ShowRoutine(string sheetId, bool playAnimation) throw new InvalidOperationException( "Cannot transition because the sheet is already active."); - IsInTransition = true; - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - foreach (var pageContainer in PageContainer.Instances) - pageContainer.Interactable = false; - foreach (var modalContainer in ModalContainer.Instances) - modalContainer.Interactable = false; - foreach (var sheetContainer in Instances) - sheetContainer.Interactable = false; - } - else - { - Interactable = false; - } - } + _transitionHandler.Begin(); var enterSheet = _sheets[sheetId]; var exitSheet = ActiveSheetId != null ? _sheets[ActiveSheetId] : null; @@ -334,7 +320,7 @@ private IEnumerator ShowRoutine(string sheetId, bool playAnimation) // End Transition ActiveSheetId = sheetId; - IsInTransition = false; + _transitionHandler.End(); // Postprocess if (exitSheet != null) exitSheet.AfterExit(enterSheet); @@ -342,30 +328,6 @@ private IEnumerator ShowRoutine(string sheetId, bool playAnimation) enterSheet.AfterEnter(exitSheet); foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.AfterShow(enterSheet, exitSheet); - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // If there's a container in transition, it should restore Interactive to true when the transition is finished. - // So, do nothing here if there's a transitioning container. - if (PageContainer.Instances.All(x => !x.IsInTransition) - && ModalContainer.Instances.All(x => !x.IsInTransition) - && Instances.All(x => !x.IsInTransition)) - { - foreach (var pageContainer in PageContainer.Instances) - pageContainer.Interactable = true; - foreach (var modalContainer in ModalContainer.Instances) - modalContainer.Interactable = true; - foreach (var sheetContainer in Instances) - sheetContainer.Interactable = true; - } - } - else - { - Interactable = true; - } - } } private IEnumerator HideRoutine(bool playAnimation) @@ -378,24 +340,7 @@ private IEnumerator HideRoutine(bool playAnimation) throw new InvalidOperationException( "Cannot transition because there is no active sheets."); - IsInTransition = true; - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - foreach (var pageContainer in PageContainer.Instances) - pageContainer.Interactable = false; - foreach (var modalContainer in ModalContainer.Instances) - modalContainer.Interactable = false; - foreach (var sheetContainer in Instances) - sheetContainer.Interactable = false; - } - else - { - Interactable = false; - } - } + _transitionHandler.Begin(); var exitSheet = _sheets[ActiveSheetId]; @@ -411,35 +356,11 @@ private IEnumerator HideRoutine(bool playAnimation) // End Transition ActiveSheetId = null; - IsInTransition = false; + _transitionHandler.End(); // Postprocess exitSheet.AfterExit(null); foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.AfterHide(exitSheet); - - if (!UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - { - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // If there's a container in transition, it should restore Interactive to true when the transition is finished. - // So, do nothing here if there's a transitioning container. - if (PageContainer.Instances.All(x => !x.IsInTransition) - && ModalContainer.Instances.All(x => !x.IsInTransition) - && Instances.All(x => !x.IsInTransition)) - { - foreach (var pageContainer in PageContainer.Instances) - pageContainer.Interactable = true; - foreach (var modalContainer in ModalContainer.Instances) - modalContainer.Interactable = true; - foreach (var sheetContainer in Instances) - sheetContainer.Interactable = true; - } - } - else - { - Interactable = true; - } - } } /// diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs new file mode 100644 index 00000000..51b37046 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs @@ -0,0 +1,92 @@ +using System; +using System.Linq; +using UnityEngine.Assertions; +using UnityScreenNavigator.Runtime.Core.Modal; +using UnityScreenNavigator.Runtime.Core.Page; +using UnityScreenNavigator.Runtime.Core.Shared; + +namespace UnityScreenNavigator.Runtime.Core.Sheet +{ + public sealed class SheetTransitionHandler + { + private readonly SheetContainer _container; + + public SheetTransitionHandler(SheetContainer container) + { + Assert.IsNotNull(container); + _container = container; + } + + public bool IsInTransition { get; private set; } + + public void Begin() + { + if (IsInTransition) + throw new InvalidOperationException("Transition already in progress."); + + IsInTransition = true; + + if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) + return; + + if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) + { + // 他のコンテナがトランジション中の場合は、すでにそのコンテナの開始処理でSetAllContainersInteractableが実行されているので、ここでは何もしない + if (!AllContainersFinishedTransition()) + return; + + SetAllContainersInteractable(false); + } + else + { + SetSelfContainersInteractable(false); + } + } + + public void End() + { + if (!IsInTransition) + throw new InvalidOperationException("Transition has not started."); + + IsInTransition = false; + + if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) + return; + + if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) + { + // 他のコンテナがトランジション中の場合は、そのコンテナの終了処理でSetAllContainersInteractableが実行されるので、ここでは何もしない + if (!AllContainersFinishedTransition()) + return; + + SetAllContainersInteractable(true); + } + else + { + SetSelfContainersInteractable(true); + } + } + + private bool AllContainersFinishedTransition() + { + return PageContainer.Instances.All(x => !x.IsInTransition) + && ModalContainer.Instances.All(x => !x.IsInTransition) + && SheetContainer.Instances.All(x => !x.IsInTransition); + } + + private void SetAllContainersInteractable(bool value) + { + foreach (var container in PageContainer.Instances) + container.Interactable = value; + foreach (var container in ModalContainer.Instances) + container.Interactable = value; + foreach (var container in SheetContainer.Instances) + container.Interactable = value; + } + + private void SetSelfContainersInteractable(bool value) + { + _container.Interactable = value; + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs.meta new file mode 100644 index 00000000..5fb39ebb --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b02b34d173d094bddab8627ccd1788bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 1c44318d636926a3c5857bfc7cd15b747a691bab Mon Sep 17 00:00:00 2001 From: Haruki Yano Date: Fri, 2 May 2025 16:43:28 +0900 Subject: [PATCH 3/7] =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E3=81=8C=E3=81=8A?= =?UTF-8?q?=E3=81=8B=E3=81=97=E3=81=8B=E3=81=A3=E3=81=9F=E9=83=A8=E5=88=86?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Demo/Core/DemoEntryPoint.unity | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Demo/Core/DemoEntryPoint.unity b/Assets/Demo/Core/DemoEntryPoint.unity index cca0d450..3c836e32 100644 --- a/Assets/Demo/Core/DemoEntryPoint.unity +++ b/Assets/Demo/Core/DemoEntryPoint.unity @@ -368,7 +368,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: _name: MainModalContainer - _backdropStrategy: 1 + _backdropStrategy: 0 _overrideBackdropPrefab: {fileID: 4672728316167856403, guid: 30228440436e2a248b41c61d678f615e, type: 3} --- !u!114 &779631005 From 154fb57a0db0ca13a558890fdbe43d92569a2fb8 Mon Sep 17 00:00:00 2001 From: Haruki Yano Date: Sat, 3 May 2025 23:29:56 +0900 Subject: [PATCH 4/7] =?UTF-8?q?Container=E3=81=AB=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=83=BC=E3=83=95=E3=82=A7=E3=83=BC=E3=82=B9=E3=82=92?= =?UTF-8?q?=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/Core/Modal/ModalContainer.cs | 9 +- .../Core/Modal/ModalTransitionHandler.cs | 92 ------------------- .../Runtime/Core/Page/PageContainer.cs | 6 +- .../Core/Page/PageTransitionHandler.cs.meta | 3 - .../Runtime/Core/Shared/IScreenContainer.cs | 9 ++ .../IScreenContainer.cs.meta} | 2 +- .../ScreenContainerTransitionHandler.cs} | 26 ++---- .../ScreenContainerTransitionHandler.cs.meta} | 2 +- .../Runtime/Core/Sheet/SheetContainer.cs | 9 +- .../Core/Sheet/SheetTransitionHandler.cs | 92 ------------------- 10 files changed, 28 insertions(+), 222 deletions(-) delete mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs delete mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Shared/IScreenContainer.cs rename Assets/UnityScreenNavigator/Runtime/Core/{Sheet/SheetTransitionHandler.cs.meta => Shared/IScreenContainer.cs.meta} (83%) rename Assets/UnityScreenNavigator/Runtime/Core/{Page/PageTransitionHandler.cs => Shared/ScreenContainerTransitionHandler.cs} (69%) rename Assets/UnityScreenNavigator/Runtime/Core/{Modal/ModalTransitionHandler.cs.meta => Shared/ScreenContainerTransitionHandler.cs.meta} (83%) delete mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs index ad09992d..b0c47010 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs @@ -1,13 +1,10 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using UnityEngine; using UnityEngine.Assertions; using UnityEngine.UI; -using UnityScreenNavigator.Runtime.Core.Page; using UnityScreenNavigator.Runtime.Core.Shared; -using UnityScreenNavigator.Runtime.Core.Sheet; using UnityScreenNavigator.Runtime.Foundation; using UnityScreenNavigator.Runtime.Foundation.AssetLoader; using UnityScreenNavigator.Runtime.Foundation.Coroutine; @@ -15,7 +12,7 @@ namespace UnityScreenNavigator.Runtime.Core.Modal { [RequireComponent(typeof(RectMask2D))] - public sealed class ModalContainer : MonoBehaviour + public sealed class ModalContainer : MonoBehaviour, IScreenContainer { private static readonly Dictionary InstanceCacheByTransform = new Dictionary(); @@ -49,7 +46,7 @@ private readonly Dictionary> _assetLoadHandl public static List Instances { get; } = new List(); private IModalBackdropHandler _backdropHandler; - private ModalTransitionHandler _transitionHandler; + private ScreenContainerTransitionHandler _transitionHandler; /// /// By default, in is used. @@ -95,7 +92,7 @@ private void Awake() _canvasGroup = gameObject.GetOrAddComponent(); _backdropHandler = ModalBackdropHandlerFactory.Create(_backdropStrategy, _backdropPrefab); - _transitionHandler = new ModalTransitionHandler(this); + _transitionHandler = new ScreenContainerTransitionHandler(this); } private void OnDestroy() diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs deleted file mode 100644 index ed9bf907..00000000 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Linq; -using UnityEngine.Assertions; -using UnityScreenNavigator.Runtime.Core.Page; -using UnityScreenNavigator.Runtime.Core.Shared; -using UnityScreenNavigator.Runtime.Core.Sheet; - -namespace UnityScreenNavigator.Runtime.Core.Modal -{ - public sealed class ModalTransitionHandler - { - private readonly ModalContainer _container; - - public ModalTransitionHandler(ModalContainer container) - { - Assert.IsNotNull(container); - _container = container; - } - - public bool IsInTransition { get; private set; } - - public void Begin() - { - if (IsInTransition) - throw new InvalidOperationException("Transition already in progress."); - - IsInTransition = true; - - if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - return; - - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // 他のコンテナがトランジション中の場合は、すでにそのコンテナの開始処理でSetAllContainersInteractableが実行されているので、ここでは何もしない - if (!AllContainersFinishedTransition()) - return; - - SetAllContainersInteractable(false); - } - else - { - SetSelfContainersInteractable(false); - } - } - - public void End() - { - if (!IsInTransition) - throw new InvalidOperationException("Transition has not started."); - - IsInTransition = false; - - if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - return; - - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // 他のコンテナがトランジション中の場合は、そのコンテナの終了処理でSetAllContainersInteractableが実行されるので、ここでは何もしない - if (!AllContainersFinishedTransition()) - return; - - SetAllContainersInteractable(true); - } - else - { - SetSelfContainersInteractable(true); - } - } - - private bool AllContainersFinishedTransition() - { - return PageContainer.Instances.All(x => !x.IsInTransition) - && ModalContainer.Instances.All(x => !x.IsInTransition) - && SheetContainer.Instances.All(x => !x.IsInTransition); - } - - private void SetAllContainersInteractable(bool value) - { - foreach (var container in PageContainer.Instances) - container.Interactable = value; - foreach (var container in ModalContainer.Instances) - container.Interactable = value; - foreach (var container in SheetContainer.Instances) - container.Interactable = value; - } - - private void SetSelfContainersInteractable(bool value) - { - _container.Interactable = value; - } - } -} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs index d41eba95..e5e34816 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs @@ -12,7 +12,7 @@ namespace UnityScreenNavigator.Runtime.Core.Page { [RequireComponent(typeof(RectMask2D))] - public sealed class PageContainer : MonoBehaviour + public sealed class PageContainer : MonoBehaviour, IScreenContainer { private static readonly Dictionary InstanceCacheByTransform = new Dictionary(); @@ -42,7 +42,7 @@ private readonly Dictionary> _assetLoadHandl private bool _isActivePageStacked; public static List Instances { get; } = new List(); - private PageTransitionHandler _transitionHandler; + private ScreenContainerTransitionHandler _transitionHandler; /// /// By default, in is used. @@ -83,7 +83,7 @@ private void Awake() if (!string.IsNullOrWhiteSpace(_name)) InstanceCacheByName.Add(_name, this); _canvasGroup = gameObject.GetOrAddComponent(); - _transitionHandler = new PageTransitionHandler(this); + _transitionHandler = new ScreenContainerTransitionHandler(this); } private void OnDestroy() diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs.meta deleted file mode 100644 index 031e6b81..00000000 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 509cdc07b6c4413a89f0eba34c6ae185 -timeCreated: 1746165015 \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Shared/IScreenContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Shared/IScreenContainer.cs new file mode 100644 index 00000000..3a8b83da --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Shared/IScreenContainer.cs @@ -0,0 +1,9 @@ +namespace UnityScreenNavigator.Runtime.Core.Shared +{ + public interface IScreenContainer + { + bool IsInTransition { get; } + + bool Interactable { get; set; } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Shared/IScreenContainer.cs.meta similarity index 83% rename from Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs.meta rename to Assets/UnityScreenNavigator/Runtime/Core/Shared/IScreenContainer.cs.meta index 5fb39ebb..5c5e5b69 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs.meta +++ b/Assets/UnityScreenNavigator/Runtime/Core/Shared/IScreenContainer.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b02b34d173d094bddab8627ccd1788bf +guid: 036e8d8e1309e472b8c9fea94a6cb545 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Shared/ScreenContainerTransitionHandler.cs similarity index 69% rename from Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs rename to Assets/UnityScreenNavigator/Runtime/Core/Shared/ScreenContainerTransitionHandler.cs index 0afdc605..cb639edb 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageTransitionHandler.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Shared/ScreenContainerTransitionHandler.cs @@ -1,24 +1,21 @@ using System; using System.Linq; -using UnityEngine.Assertions; using UnityScreenNavigator.Runtime.Core.Modal; -using UnityScreenNavigator.Runtime.Core.Shared; +using UnityScreenNavigator.Runtime.Core.Page; using UnityScreenNavigator.Runtime.Core.Sheet; -namespace UnityScreenNavigator.Runtime.Core.Page +namespace UnityScreenNavigator.Runtime.Core.Shared { - public sealed class PageTransitionHandler + public sealed class ScreenContainerTransitionHandler { - private readonly PageContainer _container; + private readonly IScreenContainer _container; + public bool IsInTransition { get; private set; } - public PageTransitionHandler(PageContainer container) + public ScreenContainerTransitionHandler(IScreenContainer container) { - Assert.IsNotNull(container); _container = container; } - public bool IsInTransition { get; private set; } - public void Begin() { if (IsInTransition) @@ -31,7 +28,6 @@ public void Begin() if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) { - // 他のコンテナがトランジション中の場合は、すでにそのコンテナの開始処理でSetAllContainersInteractableが実行されているので、ここでは何もしない if (!AllContainersFinishedTransition()) return; @@ -39,7 +35,7 @@ public void Begin() } else { - SetSelfContainersInteractable(false); + _container.Interactable = false; } } @@ -55,7 +51,6 @@ public void End() if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) { - // 他のコンテナがトランジション中の場合は、そのコンテナの終了処理でSetAllContainersInteractableが実行されるので、ここでは何もしない if (!AllContainersFinishedTransition()) return; @@ -63,7 +58,7 @@ public void End() } else { - SetSelfContainersInteractable(true); + _container.Interactable = true; } } @@ -83,10 +78,5 @@ private void SetAllContainersInteractable(bool value) foreach (var container in SheetContainer.Instances) container.Interactable = value; } - - private void SetSelfContainersInteractable(bool value) - { - _container.Interactable = value; - } } } \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Shared/ScreenContainerTransitionHandler.cs.meta similarity index 83% rename from Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs.meta rename to Assets/UnityScreenNavigator/Runtime/Core/Shared/ScreenContainerTransitionHandler.cs.meta index d5a588c7..b036e38d 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalTransitionHandler.cs.meta +++ b/Assets/UnityScreenNavigator/Runtime/Core/Shared/ScreenContainerTransitionHandler.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f564c54127b994bdbbe5c073152b360b +guid: b51f185da636d47268b1438b9f9a4f2c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs index 46f5bae1..7626d613 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs @@ -1,11 +1,8 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using UnityEngine; using UnityEngine.UI; -using UnityScreenNavigator.Runtime.Core.Modal; -using UnityScreenNavigator.Runtime.Core.Page; using UnityScreenNavigator.Runtime.Core.Shared; using UnityScreenNavigator.Runtime.Foundation; using UnityScreenNavigator.Runtime.Foundation.AssetLoader; @@ -14,7 +11,7 @@ namespace UnityScreenNavigator.Runtime.Core.Sheet { [RequireComponent(typeof(RectMask2D))] - public sealed class SheetContainer : MonoBehaviour + public sealed class SheetContainer : MonoBehaviour, IScreenContainer { private static readonly Dictionary InstanceCacheByTransform = new Dictionary(); @@ -37,7 +34,7 @@ private readonly Dictionary> _assetLoadHandl private CanvasGroup _canvasGroup; public static List Instances { get; } = new List(); - private SheetTransitionHandler _transitionHandler; + private ScreenContainerTransitionHandler _transitionHandler; /// /// By default, in is used. @@ -86,7 +83,7 @@ private void Awake() if (!string.IsNullOrWhiteSpace(_name)) InstanceCacheByName.Add(_name, this); _canvasGroup = gameObject.GetOrAddComponent(); - _transitionHandler = new SheetTransitionHandler(this); + _transitionHandler = new ScreenContainerTransitionHandler(this); } private void OnDestroy() diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs deleted file mode 100644 index 51b37046..00000000 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetTransitionHandler.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Linq; -using UnityEngine.Assertions; -using UnityScreenNavigator.Runtime.Core.Modal; -using UnityScreenNavigator.Runtime.Core.Page; -using UnityScreenNavigator.Runtime.Core.Shared; - -namespace UnityScreenNavigator.Runtime.Core.Sheet -{ - public sealed class SheetTransitionHandler - { - private readonly SheetContainer _container; - - public SheetTransitionHandler(SheetContainer container) - { - Assert.IsNotNull(container); - _container = container; - } - - public bool IsInTransition { get; private set; } - - public void Begin() - { - if (IsInTransition) - throw new InvalidOperationException("Transition already in progress."); - - IsInTransition = true; - - if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - return; - - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // 他のコンテナがトランジション中の場合は、すでにそのコンテナの開始処理でSetAllContainersInteractableが実行されているので、ここでは何もしない - if (!AllContainersFinishedTransition()) - return; - - SetAllContainersInteractable(false); - } - else - { - SetSelfContainersInteractable(false); - } - } - - public void End() - { - if (!IsInTransition) - throw new InvalidOperationException("Transition has not started."); - - IsInTransition = false; - - if (UnityScreenNavigatorSettings.Instance.EnableInteractionInTransition) - return; - - if (UnityScreenNavigatorSettings.Instance.ControlInteractionsOfAllContainers) - { - // 他のコンテナがトランジション中の場合は、そのコンテナの終了処理でSetAllContainersInteractableが実行されるので、ここでは何もしない - if (!AllContainersFinishedTransition()) - return; - - SetAllContainersInteractable(true); - } - else - { - SetSelfContainersInteractable(true); - } - } - - private bool AllContainersFinishedTransition() - { - return PageContainer.Instances.All(x => !x.IsInTransition) - && ModalContainer.Instances.All(x => !x.IsInTransition) - && SheetContainer.Instances.All(x => !x.IsInTransition); - } - - private void SetAllContainersInteractable(bool value) - { - foreach (var container in PageContainer.Instances) - container.Interactable = value; - foreach (var container in ModalContainer.Instances) - container.Interactable = value; - foreach (var container in SheetContainer.Instances) - container.Interactable = value; - } - - private void SetSelfContainersInteractable(bool value) - { - _container.Interactable = value; - } - } -} \ No newline at end of file From 4049acc8aa899be51eba4284d709e055175c99b9 Mon Sep 17 00:00:00 2001 From: Haruki Yano Date: Sun, 4 May 2025 00:27:14 +0900 Subject: [PATCH 5/7] =?UTF-8?q?TransitionContext=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/Core/Modal/ModalContainer.cs | 112 ++++++++---------- .../Runtime/Core/Modal/ModalPopContext.cs | 56 +++++++++ .../Core/Modal/ModalPopContext.cs.meta | 3 + .../Runtime/Core/Modal/ModalPushContext.cs | 49 ++++++++ .../Core/Modal/ModalPushContext.cs.meta | 3 + .../Runtime/Core/Page/PageContainer.cs | 85 ++++++------- .../Runtime/Core/Page/PagePopContext.cs | 59 +++++++++ .../Runtime/Core/Page/PagePopContext.cs.meta | 3 + .../Runtime/Core/Page/PagePushContext.cs | 43 +++++++ .../Runtime/Core/Page/PagePushContext.cs.meta | 3 + .../Runtime/Core/Sheet/SheetContainer.cs | 64 ++++++---- .../Runtime/Core/Sheet/SheetHideContext.cs | 19 +++ .../Core/Sheet/SheetHideContext.cs.meta | 11 ++ .../Core/Sheet/SheetRegisterContext.cs | 32 +++++ .../Core/Sheet/SheetRegisterContext.cs.meta | 11 ++ .../Runtime/Core/Sheet/SheetShowContext.cs | 34 ++++++ .../Core/Sheet/SheetShowContext.cs.meta | 3 + 17 files changed, 453 insertions(+), 137 deletions(-) create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetShowContext.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetShowContext.cs.meta diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs index b0c47010..bac14668 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs @@ -292,57 +292,57 @@ private IEnumerator PushRoutine(Type modalType, string resourceKey, bool playAni var instance = Instantiate(assetLoadHandle.Result); if (!instance.TryGetComponent(modalType, out var c)) c = instance.AddComponent(modalType); - var enterModal = (Modal)c; - if (modalId == null) - modalId = Guid.NewGuid().ToString(); - _assetLoadHandles.Add(modalId, assetLoadHandle); - onLoad?.Invoke((modalId, enterModal)); - var afterLoadHandle = enterModal.AfterLoad((RectTransform)transform); + var context = ModalPushContext.Create(modalId, (Modal)c, _orderedModalIds, _modals); + + _assetLoadHandles.Add(context.ModalId, assetLoadHandle); + onLoad?.Invoke((context.ModalId, context.EnterModal)); + var afterLoadHandle = context.EnterModal.AfterLoad((RectTransform)transform); while (!afterLoadHandle.IsTerminated) yield return null; - var exitModalId = _orderedModalIds.Count == 0 ? null : _orderedModalIds[_orderedModalIds.Count - 1]; - var exitModal = exitModalId == null ? null : _modals[exitModalId]; - // Preprocess - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.BeforePush(enterModal, exitModal); + foreach (var callbackReceiver in _callbackReceivers) + callbackReceiver.BeforePush(context.EnterModal, context.ExitModal); var preprocessHandles = new List(); - if (exitModal != null) preprocessHandles.Add(exitModal.BeforeExit(true, enterModal)); + if (context.ExitModal != null) + preprocessHandles.Add(context.ExitModal.BeforeExit(true, context.EnterModal)); - preprocessHandles.Add(enterModal.BeforeEnter(true, exitModal)); + preprocessHandles.Add(context.EnterModal.BeforeEnter(true, context.ExitModal)); foreach (var coroutineHandle in preprocessHandles) while (!coroutineHandle.IsTerminated) yield return coroutineHandle; // Play Animation - var enterModalIndex = _modals.Count; var animationHandles = new List(); - animationHandles.Add(_backdropHandler.BeforeModalEnter(enterModal, enterModalIndex, playAnimation)); + animationHandles.Add( + _backdropHandler.BeforeModalEnter(context.EnterModal, context.EnterModalIndex, playAnimation)); - if (exitModal != null) animationHandles.Add(exitModal.Exit(true, playAnimation, enterModal)); + if (context.ExitModal != null) + animationHandles.Add(context.ExitModal.Exit(true, playAnimation, context.EnterModal)); - animationHandles.Add(enterModal.Enter(true, playAnimation, exitModal)); + animationHandles.Add(context.EnterModal.Enter(true, playAnimation, context.ExitModal)); foreach (var coroutineHandle in animationHandles) while (!coroutineHandle.IsTerminated) yield return coroutineHandle; - _backdropHandler.AfterModalEnter(enterModal, enterModalIndex, true); + _backdropHandler.AfterModalEnter(context.EnterModal, context.EnterModalIndex, true); // End Transition - _modals.Add(modalId, enterModal); - _orderedModalIds.Add(modalId); + _modals.Add(context.ModalId, context.EnterModal); + _orderedModalIds.Add(context.ModalId); _transitionHandler.End(); // Postprocess - if (exitModal != null) exitModal.AfterExit(true, enterModal); + if (context.ExitModal != null) context.ExitModal.AfterExit(true, context.EnterModal); - enterModal.AfterEnter(true, exitModal); + context.EnterModal.AfterEnter(true, context.ExitModal); - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.AfterPush(enterModal, exitModal); + foreach (var callbackReceiver in _callbackReceivers) + callbackReceiver.AfterPush(context.EnterModal, context.ExitModal); } private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) @@ -357,34 +357,20 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) throw new InvalidOperationException( "Cannot transition because the screen is already in transition."); + var context = ModalPopContext.Create(_orderedModalIds, _modals, popCount); + _transitionHandler.Begin(); - var exitModalId = _orderedModalIds[_orderedModalIds.Count - 1]; - var exitModal = _modals[exitModalId]; - - var unusedModalIds = new List(); - var unusedModals = new List(); - var unusedModalIndices = new List(); - for (var i = _orderedModalIds.Count - 1; i >= _orderedModalIds.Count - popCount; i--) - { - var unusedModalId = _orderedModalIds[i]; - unusedModalIds.Add(unusedModalId); - unusedModals.Add(_modals[unusedModalId]); - unusedModalIndices.Add(i); - } - - var enterModalIndex = _orderedModalIds.Count - popCount - 1; - var enterModalId = enterModalIndex < 0 ? null : _orderedModalIds[enterModalIndex]; - var enterModal = enterModalId == null ? null : _modals[enterModalId]; - // Preprocess - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.BeforePop(enterModal, exitModal); + foreach (var callbackReceiver in _callbackReceivers) + callbackReceiver.BeforePop(context.EnterModal, context.FirstExitModal); var preprocessHandles = new List { - exitModal.BeforeExit(false, enterModal) + context.FirstExitModal.BeforeExit(false, context.EnterModal) }; - if (enterModal != null) preprocessHandles.Add(enterModal.BeforeEnter(false, exitModal)); + if (context.EnterModal != null) + preprocessHandles.Add(context.EnterModal.BeforeEnter(false, context.FirstExitModal)); foreach (var coroutineHandle in preprocessHandles) while (!coroutineHandle.IsTerminated) @@ -392,52 +378,54 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) // Play Animation var animationHandles = new List(); - for (var i = unusedModalIds.Count - 1; i >= 0; i--) + for (var i = context.ExitModalIds.Count - 1; i >= 0; i--) { - var unusedModalId = unusedModalIds[i]; - var unusedModal = _modals[unusedModalId]; - var unusedModalIndex = unusedModalIndices[i]; - var partnerModalId = i == 0 ? enterModalId : unusedModalIds[i - 1]; + var exitModalId = context.ExitModalIds[i]; + var exitModal = _modals[exitModalId]; + var exitModalIndex = context.ExitModalIndices[i]; + var partnerModalId = i == 0 ? context.EnterModalId : context.ExitModalIds[i - 1]; var partnerModal = partnerModalId == null ? null : _modals[partnerModalId]; - animationHandles.Add(_backdropHandler.BeforeModalExit(unusedModal, unusedModalIndex, playAnimation)); - animationHandles.Add(unusedModal.Exit(false, playAnimation, partnerModal)); + animationHandles.Add(_backdropHandler.BeforeModalExit(exitModal, exitModalIndex, playAnimation)); + animationHandles.Add(exitModal.Exit(false, playAnimation, partnerModal)); } - if (enterModal != null) animationHandles.Add(enterModal.Enter(false, playAnimation, exitModal)); + if (context.EnterModal != null) + animationHandles.Add(context.EnterModal.Enter(false, playAnimation, context.FirstExitModal)); foreach (var coroutineHandle in animationHandles) while (!coroutineHandle.IsTerminated) yield return coroutineHandle; // End Transition - for (var i = 0; i < unusedModalIds.Count; i++) + for (var i = 0; i < context.ExitModalIds.Count; i++) { - var unusedModalId = unusedModalIds[i]; + var unusedModalId = context.ExitModalIds[i]; _modals.Remove(unusedModalId); _orderedModalIds.RemoveAt(_orderedModalIds.Count - 1); } _transitionHandler.End(); // Postprocess - exitModal.AfterExit(false, enterModal); - if (enterModal != null) enterModal.AfterEnter(false, exitModal); + context.FirstExitModal.AfterExit(false, context.EnterModal); + if (context.EnterModal != null) context.EnterModal.AfterEnter(false, context.FirstExitModal); - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.AfterPop(enterModal, exitModal); + foreach (var callbackReceiver in _callbackReceivers) + callbackReceiver.AfterPop(context.EnterModal, context.FirstExitModal); // Unload Unused Page - var beforeReleaseHandle = exitModal.BeforeRelease(); + var beforeReleaseHandle = context.FirstExitModal.BeforeRelease(); while (!beforeReleaseHandle.IsTerminated) yield return null; - for (var i = 0; i < unusedModalIds.Count; i++) + for (var i = 0; i < context.ExitModalIds.Count; i++) { - var unusedModalId = unusedModalIds[i]; - var unusedModal = unusedModals[i]; - var unusedModalIndex = unusedModalIndices[i]; + var unusedModalId = context.ExitModalIds[i]; + var unusedModal = context.ExitModals[i]; + var unusedModalIndex = context.ExitModalIndices[i]; var loadHandle = _assetLoadHandles[unusedModalId]; Destroy(unusedModal.gameObject); AssetLoader.Release(loadHandle); _assetLoadHandles.Remove(unusedModalId); - _backdropHandler.AfterModalExit(exitModal, unusedModalIndex, playAnimation); + _backdropHandler.AfterModalExit(context.FirstExitModal, unusedModalIndex, playAnimation); } } diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs new file mode 100644 index 00000000..695f6a2e --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; + +namespace UnityScreenNavigator.Runtime.Core.Modal +{ + internal readonly struct ModalPopContext + { + public IReadOnlyList ExitModalIds { get; } + public IReadOnlyList ExitModals { get; } + public IReadOnlyList ExitModalIndices { get; } + + public string EnterModalId { get; } + public Modal EnterModal { get; } + + public Modal FirstExitModal => ExitModals[0]; + + private ModalPopContext( + List exitModalIds, + List exitModals, + List exitModalIndices, + string enterModalId, + Modal enterModal + ) + { + ExitModalIds = exitModalIds; + ExitModals = exitModals; + ExitModalIndices = exitModalIndices; + EnterModalId = enterModalId; + EnterModal = enterModal; + } + + public static ModalPopContext Create( + List orderedModalIds, + Dictionary modals, + int popCount + ) + { + var exitIds = new List(); + var exitModals = new List(); + var indices = new List(); + + for (var i = orderedModalIds.Count - 1; i >= orderedModalIds.Count - popCount; i--) + { + var id = orderedModalIds[i]; + exitIds.Add(id); + exitModals.Add(modals[id]); + indices.Add(i); + } + + var enterIndex = orderedModalIds.Count - popCount - 1; + var enterId = enterIndex >= 0 ? orderedModalIds[enterIndex] : null; + var enterModal = enterId != null ? modals[enterId] : null; + + return new ModalPopContext(exitIds, exitModals, indices, enterId, enterModal); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs.meta new file mode 100644 index 00000000..2c8a7aaf --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 25267d6e7e9d415780116b79a30acb74 +timeCreated: 1746284749 \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs new file mode 100644 index 00000000..579a35f7 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; + +namespace UnityScreenNavigator.Runtime.Core.Modal +{ + internal readonly struct ModalPushContext + { + public string ModalId { get; } + public Modal EnterModal { get; } + + public string ExitModalId { get; } + public Modal ExitModal { get; } + + public int EnterModalIndex { get; } + + private ModalPushContext( + string modalId, + Modal enterModal, + string exitModalId, + Modal exitModal, + int enterModalIndex + ) + { + ModalId = modalId; + EnterModal = enterModal; + ExitModalId = exitModalId; + ExitModal = exitModal; + EnterModalIndex = enterModalIndex; + } + + public static ModalPushContext Create( + string modalId, + Modal enterModal, + List orderedModalIds, + Dictionary modals + ) + { + var resolvedModalId = modalId ?? Guid.NewGuid().ToString(); + + var hasExit = orderedModalIds.Count > 0; + var exitId = hasExit ? orderedModalIds[orderedModalIds.Count - 1] : null; + var exitModal = hasExit ? modals[exitId] : null; + + var enterIndex = modals.Count; + + return new ModalPushContext(resolvedModalId, enterModal, exitId, exitModal, enterIndex); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs.meta new file mode 100644 index 00000000..e7432af0 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 97863090c46a4f62954f7f4dba934c3f +timeCreated: 1746284400 \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs index e5e34816..83394126 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs @@ -274,7 +274,7 @@ private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnim if (IsInTransition) throw new InvalidOperationException( "Cannot transition because the screen is already in transition."); - + _transitionHandler.Begin(); // Setup @@ -288,26 +288,23 @@ private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnim var instance = Instantiate(assetLoadHandle.Result); if (!instance.TryGetComponent(pageType, out var c)) c = instance.AddComponent(pageType); - var enterPage = (Page)c; - if (pageId == null) - pageId = Guid.NewGuid().ToString(); - _assetLoadHandles.Add(pageId, assetLoadHandle); - onLoad?.Invoke((pageId, enterPage)); - var afterLoadHandle = enterPage.AfterLoad((RectTransform)transform); + var context = PagePushContext.Create(pageId, (Page)c, _orderedPageIds, _pages, stack); + + _assetLoadHandles.Add(context.EnterPageId, assetLoadHandle); + onLoad?.Invoke((context.EnterPageId, context.EnterPage)); + var afterLoadHandle = context.EnterPage.AfterLoad((RectTransform)transform); while (!afterLoadHandle.IsTerminated) yield return null; - var exitPageId = _orderedPageIds.Count == 0 ? null : _orderedPageIds[_pages.Count - 1]; - var exitPage = exitPageId == null ? null : _pages[exitPageId]; - // Preprocess - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.BeforePush(enterPage, exitPage); + foreach (var callbackReceiver in _callbackReceivers) + callbackReceiver.BeforePush(context.EnterPage, context.ExitPage); var preprocessHandles = new List(); - if (exitPage != null) preprocessHandles.Add(exitPage.BeforeExit(true, enterPage)); + if (context.ExitPage != null) preprocessHandles.Add(context.ExitPage.BeforeExit(true, context.EnterPage)); - preprocessHandles.Add(enterPage.BeforeEnter(true, exitPage)); + preprocessHandles.Add(context.EnterPage.BeforeEnter(true, context.ExitPage)); foreach (var coroutineHandle in preprocessHandles) while (!coroutineHandle.IsTerminated) @@ -315,47 +312,47 @@ private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnim // Play Animations var animationHandles = new List(); - if (exitPage != null) - animationHandles.Add(exitPage.Exit(true, playAnimation, enterPage)); + if (context.ExitPage != null) + animationHandles.Add(context.ExitPage.Exit(true, playAnimation, context.EnterPage)); - animationHandles.Add(enterPage.Enter(true, playAnimation, exitPage)); + animationHandles.Add(context.EnterPage.Enter(true, playAnimation, context.ExitPage)); foreach (var coroutineHandle in animationHandles) while (!coroutineHandle.IsTerminated) yield return coroutineHandle; // End Transition - if (!_isActivePageStacked && exitPage != null) + if (!_isActivePageStacked && context.ExitPage != null) { - _pages.Remove(exitPageId); - _orderedPageIds.Remove(exitPageId); + _pages.Remove(context.ExitPageId); + _orderedPageIds.Remove(context.ExitPageId); } - _pages.Add(pageId, enterPage); - _orderedPageIds.Add(pageId); + _pages.Add(context.EnterPageId, context.EnterPage); + _orderedPageIds.Add(context.EnterPageId); _transitionHandler.End(); // Postprocess - if (exitPage != null) - exitPage.AfterExit(true, enterPage); + if (context.ExitPage != null) + context.ExitPage.AfterExit(true, context.EnterPage); - enterPage.AfterEnter(true, exitPage); + context.EnterPage.AfterEnter(true, context.ExitPage); foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.AfterPush(enterPage, exitPage); + callbackReceiver.AfterPush(context.EnterPage, context.ExitPage); // Unload Unused Page - if (!_isActivePageStacked && exitPage != null) + if (!_isActivePageStacked && context.ExitPage != null) { - var beforeReleaseHandle = exitPage.BeforeRelease(); + var beforeReleaseHandle = context.ExitPage.BeforeRelease(); while (!beforeReleaseHandle.IsTerminated) yield return null; - var handle = _assetLoadHandles[exitPageId]; + var handle = _assetLoadHandles[context.ExitPageId]; AssetLoader.Release(handle); - Destroy(exitPage.gameObject); - _assetLoadHandles.Remove(exitPageId); + Destroy(context.ExitPage.gameObject); + _assetLoadHandles.Remove(context.ExitPageId); } _isActivePageStacked = stack; @@ -375,21 +372,9 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) _transitionHandler.Begin(); - var exitPageId = _orderedPageIds[_orderedPageIds.Count - 1]; - var exitPage = _pages[exitPageId]; - - var unusedPageIds = new List(); - var unusedPages = new List(); - for (var i = _orderedPageIds.Count - 1; i >= _orderedPageIds.Count - popCount; i--) - { - var unusedPageId = _orderedPageIds[i]; - unusedPageIds.Add(unusedPageId); - unusedPages.Add(_pages[unusedPageId]); - } - - var enterPageIndex = _orderedPageIds.Count - popCount - 1; - var enterPageId = enterPageIndex < 0 ? null : _orderedPageIds[enterPageIndex]; - var enterPage = enterPageId == null ? null : _pages[enterPageId]; + var context = PagePopContext.Create(_orderedPageIds, _pages, popCount); + var exitPage = context.ExitPage; + var enterPage = context.EnterPage; // Preprocess foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.BeforePop(enterPage, exitPage); @@ -416,9 +401,9 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) yield return coroutineHandle; // End Transition - for (var i = 0; i < unusedPageIds.Count; i++) + for (var i = 0; i < context.ExitPageIds.Count; i++) { - var unusedPageId = unusedPageIds[i]; + var unusedPageId = context.ExitPageIds[i]; _pages.Remove(unusedPageId); _orderedPageIds.RemoveAt(_orderedPageIds.Count - 1); } @@ -435,10 +420,10 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) var beforeReleaseHandle = exitPage.BeforeRelease(); while (!beforeReleaseHandle.IsTerminated) yield return null; - for (var i = 0; i < unusedPageIds.Count; i++) + for (var i = 0; i < context.ExitPageIds.Count; i++) { - var unusedPageId = unusedPageIds[i]; - var unusedPage = unusedPages[i]; + var unusedPageId = context.ExitPageIds[i]; + var unusedPage = context.ExitPages[i]; var loadHandle = _assetLoadHandles[unusedPageId]; Destroy(unusedPage.gameObject); AssetLoader.Release(loadHandle); diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs new file mode 100644 index 00000000..109ea22d --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; + +namespace UnityScreenNavigator.Runtime.Core.Page +{ + internal readonly struct PagePopContext + { + public IReadOnlyList OrderedPageIds { get; } + public IReadOnlyDictionary Pages { get; } + + public IReadOnlyList ExitPageIds { get; } + public IReadOnlyList ExitPages { get; } + + public string ExitPageId => ExitPageIds[0]; + public Page ExitPage => ExitPages[0]; + + public string EnterPageId { get; } + public Page EnterPage { get; } + + private PagePopContext( + IReadOnlyList orderedPageIds, + IReadOnlyDictionary pages, + IReadOnlyList exitPageIds, + IReadOnlyList exitPages, + string enterPageId, + Page enterPage + ) + { + OrderedPageIds = orderedPageIds; + Pages = pages; + ExitPageIds = exitPageIds; + ExitPages = exitPages; + EnterPageId = enterPageId; + EnterPage = enterPage; + } + + public static PagePopContext Create( + IReadOnlyList orderedPageIds, + IReadOnlyDictionary pages, + int popCount + ) + { + var unusedIds = new List(); + var unusedPages = new List(); + + for (var i = orderedPageIds.Count - 1; i >= orderedPageIds.Count - popCount; i--) + { + var id = orderedPageIds[i]; + unusedIds.Add(id); + unusedPages.Add(pages[id]); + } + + var enterIndex = orderedPageIds.Count - popCount - 1; + var enterId = enterIndex >= 0 ? orderedPageIds[enterIndex] : null; + var enter = enterId != null ? pages[enterId] : null; + + return new PagePopContext(orderedPageIds, pages, unusedIds, unusedPages, enterId, enter); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs.meta new file mode 100644 index 00000000..85263dd3 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6f71bc70776544b5adac863185df7e0e +timeCreated: 1746283660 \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs new file mode 100644 index 00000000..a7ada8a7 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +namespace UnityScreenNavigator.Runtime.Core.Page +{ + internal readonly struct PagePushContext + { + public string EnterPageId { get; } + public Page EnterPage { get; } + + public string ExitPageId { get; } + public Page ExitPage { get; } + + public bool IsStacked { get; } + + private PagePushContext(string enterPageId, Page enterPage, string exitPageId, Page exitPage, bool isStacked) + { + EnterPageId = enterPageId; + EnterPage = enterPage; + ExitPageId = exitPageId; + ExitPage = exitPage; + IsStacked = isStacked; + } + + public static PagePushContext Create( + string pageId, + Page enterPage, + List orderedPageIds, + Dictionary pages, + bool isStacked + ) + { + var hasExit = orderedPageIds.Count > 0; + var exitPageId = hasExit ? orderedPageIds[orderedPageIds.Count - 1] : null; + + var exitPage = hasExit ? pages[exitPageId] : null; + + var resolvedPageId = pageId ?? Guid.NewGuid().ToString(); + + return new PagePushContext(resolvedPageId, enterPage, exitPageId, exitPage, isStacked); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs.meta new file mode 100644 index 00000000..c546e93b --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4fc775663e3d45aa885f09c7e9554718 +timeCreated: 1746284083 \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs index 7626d613..32568d4b 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs @@ -249,28 +249,35 @@ private IEnumerator RegisterRoutine(Type sheetType, string resourceKey, { if (resourceKey == null) throw new ArgumentNullException(nameof(resourceKey)); + var context = new SheetRegisterContext(sheetType, resourceKey, sheetId); + + // アセットのロード var assetLoadHandle = loadAsync ? AssetLoader.LoadAsync(resourceKey) : AssetLoader.Load(resourceKey); + context.SetAssetLoadHandle(assetLoadHandle); while (!assetLoadHandle.IsDone) yield return null; if (assetLoadHandle.Status == AssetLoadStatus.Failed) throw assetLoadHandle.OperationException; + // シートのインスタンス化と初期化 var instance = Instantiate(assetLoadHandle.Result); if (!instance.TryGetComponent(sheetType, out var c)) c = instance.AddComponent(sheetType); var sheet = (Sheet)c; + context.SetSheet(sheet); + + // シートの登録 + _sheets.Add(context.SheetId, sheet); + _sheetNameToId[resourceKey] = context.SheetId; + _assetLoadHandles.Add(context.SheetId, assetLoadHandle); + onLoad?.Invoke((context.SheetId, sheet)); - if (sheetId == null) - sheetId = Guid.NewGuid().ToString(); - _sheets.Add(sheetId, sheet); - _sheetNameToId[resourceKey] = sheetId; - _assetLoadHandles.Add(sheetId, assetLoadHandle); - onLoad?.Invoke((sheetId, sheet)); + // シートの後処理 var afterLoadHandle = sheet.AfterLoad((RectTransform)transform); while (!afterLoadHandle.IsTerminated) yield return null; - yield return sheetId; + yield return context.SheetId; } private IEnumerator ShowByResourceKeyRoutine(string resourceKey, bool playAnimation) @@ -289,27 +296,29 @@ private IEnumerator ShowRoutine(string sheetId, bool playAnimation) throw new InvalidOperationException( "Cannot transition because the sheet is already active."); + var context = SheetShowContext.Create(sheetId, ActiveSheetId, _sheets); + _transitionHandler.Begin(); - var enterSheet = _sheets[sheetId]; - var exitSheet = ActiveSheetId != null ? _sheets[ActiveSheetId] : null; // Preprocess - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.BeforeShow(enterSheet, exitSheet); + foreach (var callbackReceiver in _callbackReceivers) + callbackReceiver.BeforeShow(context.EnterSheet, context.ExitSheet); var preprocessHandles = new List(); - if (exitSheet != null) preprocessHandles.Add(exitSheet.BeforeExit(enterSheet)); + if (context.ExitSheet != null) preprocessHandles.Add(context.ExitSheet.BeforeExit(context.EnterSheet)); - preprocessHandles.Add(enterSheet.BeforeEnter(exitSheet)); + preprocessHandles.Add(context.EnterSheet.BeforeEnter(context.ExitSheet)); foreach (var coroutineHandle in preprocessHandles) while (!coroutineHandle.IsTerminated) yield return null; // Play Animation var animationHandles = new List(); - if (exitSheet != null) animationHandles.Add(exitSheet.Exit(playAnimation, enterSheet)); + if (context.ExitSheet != null) + animationHandles.Add(context.ExitSheet.Exit(playAnimation, context.EnterSheet)); - animationHandles.Add(enterSheet.Enter(playAnimation, exitSheet)); + animationHandles.Add(context.EnterSheet.Enter(playAnimation, context.ExitSheet)); foreach (var handle in animationHandles) while (!handle.IsTerminated) @@ -320,11 +329,12 @@ private IEnumerator ShowRoutine(string sheetId, bool playAnimation) _transitionHandler.End(); // Postprocess - if (exitSheet != null) exitSheet.AfterExit(enterSheet); + if (context.ExitSheet != null) context.ExitSheet.AfterExit(context.EnterSheet); - enterSheet.AfterEnter(exitSheet); + context.EnterSheet.AfterEnter(context.ExitSheet); - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.AfterShow(enterSheet, exitSheet); + foreach (var callbackReceiver in _callbackReceivers) + callbackReceiver.AfterShow(context.EnterSheet, context.ExitSheet); } private IEnumerator HideRoutine(bool playAnimation) @@ -339,25 +349,29 @@ private IEnumerator HideRoutine(bool playAnimation) _transitionHandler.Begin(); - var exitSheet = _sheets[ActiveSheetId]; + var context = SheetHideContext.Create(_sheets[ActiveSheetId], playAnimation); // Preprocess - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.BeforeHide(exitSheet); + foreach (var callbackReceiver in _callbackReceivers) + callbackReceiver.BeforeHide(context.ExitSheet); - var preprocessHandle = exitSheet.BeforeExit(null); - while (!preprocessHandle.IsTerminated) yield return preprocessHandle; + var preprocessHandle = context.ExitSheet.BeforeExit(null); + while (!preprocessHandle.IsTerminated) + yield return preprocessHandle; // Play Animation - var animationHandle = exitSheet.Exit(playAnimation, null); - while (!animationHandle.IsTerminated) yield return null; + var animationHandle = context.ExitSheet.Exit(context.PlayAnimation, null); + while (!animationHandle.IsTerminated) + yield return null; // End Transition ActiveSheetId = null; _transitionHandler.End(); // Postprocess - exitSheet.AfterExit(null); - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.AfterHide(exitSheet); + context.ExitSheet.AfterExit(null); + foreach (var callbackReceiver in _callbackReceivers) + callbackReceiver.AfterHide(context.ExitSheet); } /// diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs new file mode 100644 index 00000000..0fcb6781 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs @@ -0,0 +1,19 @@ +namespace UnityScreenNavigator.Runtime.Core.Sheet +{ + public sealed class SheetHideContext + { + private SheetHideContext(Sheet exitSheet, bool playAnimation) + { + ExitSheet = exitSheet; + PlayAnimation = playAnimation; + } + + public Sheet ExitSheet { get; } + public bool PlayAnimation { get; } + + public static SheetHideContext Create(Sheet exitSheet, bool playAnimation) + { + return new SheetHideContext(exitSheet, playAnimation); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs.meta new file mode 100644 index 00000000..e5aaf1e6 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b3993e7639afe4e9e9de1f5c62ef11e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs new file mode 100644 index 00000000..c39eb89e --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs @@ -0,0 +1,32 @@ +using System; +using UnityEngine; +using UnityScreenNavigator.Runtime.Foundation.AssetLoader; + +namespace UnityScreenNavigator.Runtime.Core.Sheet +{ + public sealed class SheetRegisterContext + { + public Type SheetType { get; } + public string ResourceKey { get; } + public string SheetId { get; } + public Sheet Sheet { get; private set; } + public AssetLoadHandle AssetLoadHandle { get; private set; } + + public SheetRegisterContext(Type sheetType, string resourceKey, string sheetId = null) + { + SheetType = sheetType; + ResourceKey = resourceKey; + SheetId = sheetId ?? Guid.NewGuid().ToString(); + } + + public void SetSheet(Sheet sheet) + { + Sheet = sheet; + } + + public void SetAssetLoadHandle(AssetLoadHandle handle) + { + AssetLoadHandle = handle; + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs.meta new file mode 100644 index 00000000..17e4e7d1 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 51566455142bf44b8b0b656bd6660211 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetShowContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetShowContext.cs new file mode 100644 index 00000000..a16bb01f --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetShowContext.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; + +namespace UnityScreenNavigator.Runtime.Core.Sheet +{ + internal readonly struct SheetShowContext + { + public string SheetId { get; } + public Sheet EnterSheet { get; } + + public string ExitSheetId { get; } + public Sheet ExitSheet { get; } + + private SheetShowContext(string sheetId, Sheet enterSheet, string exitSheetId, Sheet exitSheet) + { + SheetId = sheetId; + EnterSheet = enterSheet; + ExitSheetId = exitSheetId; + ExitSheet = exitSheet; + } + + public static SheetShowContext Create( + string sheetId, + string currentSheetId, + Dictionary sheets + ) + { + var enterSheet = sheets[sheetId]; + var exitSheetId = currentSheetId; + var exitSheet = exitSheetId != null ? sheets[exitSheetId] : null; + + return new SheetShowContext(sheetId, enterSheet, exitSheetId, exitSheet); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetShowContext.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetShowContext.cs.meta new file mode 100644 index 00000000..7e2f0208 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetShowContext.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4e2b9c8ecf5441cb9e6fcf3a065bfde6 +timeCreated: 1746286045 \ No newline at end of file From 8b1d5f9e46b354e3f98871df517ed7c7725d2247 Mon Sep 17 00:00:00 2001 From: Haruki Yano Date: Sun, 4 May 2025 20:39:46 +0900 Subject: [PATCH 6/7] =?UTF-8?q?LifecycleHandler=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/Core/Modal/ModalContainer.cs | 39 +++-------- .../Core/Modal/ModalLifecycleHandler.cs | 66 +++++++++++++++++++ .../Core/Modal/ModalLifecycleHandler.cs.meta | 3 + .../Runtime/Core/Page/PageContainer.cs | 42 +++--------- .../Runtime/Core/Page/PageLifecycleHandler.cs | 66 +++++++++++++++++++ .../Core/Page/PageLifecycleHandler.cs.meta | 11 ++++ .../Runtime/Core/Sheet/SheetContainer.cs | 32 +++------ .../Core/Sheet/SheetLifecycleHandler.cs | 61 +++++++++++++++++ .../Core/Sheet/SheetLifecycleHandler.cs.meta | 11 ++++ 9 files changed, 245 insertions(+), 86 deletions(-) create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs.meta create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs.meta diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs index bac14668..65857b29 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs @@ -294,6 +294,7 @@ private IEnumerator PushRoutine(Type modalType, string resourceKey, bool playAni c = instance.AddComponent(modalType); var context = ModalPushContext.Create(modalId, (Modal)c, _orderedModalIds, _modals); + var lifecycleHandler = new ModalLifecycleHandler(_callbackReceivers); _assetLoadHandles.Add(context.ModalId, assetLoadHandle); onLoad?.Invoke((context.ModalId, context.EnterModal)); @@ -302,15 +303,7 @@ private IEnumerator PushRoutine(Type modalType, string resourceKey, bool playAni yield return null; // Preprocess - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.BeforePush(context.EnterModal, context.ExitModal); - - var preprocessHandles = new List(); - if (context.ExitModal != null) - preprocessHandles.Add(context.ExitModal.BeforeExit(true, context.EnterModal)); - - preprocessHandles.Add(context.EnterModal.BeforeEnter(true, context.ExitModal)); - + var preprocessHandles = lifecycleHandler.BeforePush(context); foreach (var coroutineHandle in preprocessHandles) while (!coroutineHandle.IsTerminated) yield return coroutineHandle; @@ -337,12 +330,7 @@ private IEnumerator PushRoutine(Type modalType, string resourceKey, bool playAni _transitionHandler.End(); // Postprocess - if (context.ExitModal != null) context.ExitModal.AfterExit(true, context.EnterModal); - - context.EnterModal.AfterEnter(true, context.ExitModal); - - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.AfterPush(context.EnterModal, context.ExitModal); + lifecycleHandler.AfterPush(context); } private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) @@ -358,20 +346,13 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) "Cannot transition because the screen is already in transition."); var context = ModalPopContext.Create(_orderedModalIds, _modals, popCount); + var lifecycleHandler = new ModalLifecycleHandler(_callbackReceivers); _transitionHandler.Begin(); // Preprocess - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.BeforePop(context.EnterModal, context.FirstExitModal); - - var preprocessHandles = new List - { - context.FirstExitModal.BeforeExit(false, context.EnterModal) - }; - if (context.EnterModal != null) - preprocessHandles.Add(context.EnterModal.BeforeEnter(false, context.FirstExitModal)); - + var preprocessHandles = lifecycleHandler.BeforePop(context); + foreach (var coroutineHandle in preprocessHandles) while (!coroutineHandle.IsTerminated) yield return coroutineHandle; @@ -406,12 +387,8 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) _transitionHandler.End(); // Postprocess - context.FirstExitModal.AfterExit(false, context.EnterModal); - if (context.EnterModal != null) context.EnterModal.AfterEnter(false, context.FirstExitModal); - - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.AfterPop(context.EnterModal, context.FirstExitModal); - + lifecycleHandler.AfterPop(context); + // Unload Unused Page var beforeReleaseHandle = context.FirstExitModal.BeforeRelease(); while (!beforeReleaseHandle.IsTerminated) yield return null; diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs new file mode 100644 index 00000000..02ab96e8 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs @@ -0,0 +1,66 @@ +using System.Collections.Generic; +using UnityScreenNavigator.Runtime.Foundation.Coroutine; + +namespace UnityScreenNavigator.Runtime.Core.Modal +{ + internal sealed class ModalLifecycleHandler + { + private readonly IEnumerable _callbackReceivers; + + public ModalLifecycleHandler(IEnumerable callbackReceivers) + { + _callbackReceivers = callbackReceivers; + } + + public IEnumerable BeforePush(ModalPushContext context) + { + foreach (var receiver in _callbackReceivers) + receiver.BeforePush(context.EnterModal, context.ExitModal); + + var handles = new List(); + if (context.ExitModal != null) + handles.Add(context.ExitModal.BeforeExit(true, context.EnterModal)); + + handles.Add(context.EnterModal.BeforeEnter(true, context.ExitModal)); + + return handles; + } + + public void AfterPush(ModalPushContext context) + { + if (context.ExitModal != null) + context.ExitModal.AfterExit(true, context.EnterModal); + + context.EnterModal.AfterEnter(true, context.ExitModal); + + foreach (var receiver in _callbackReceivers) + receiver.AfterPush(context.EnterModal, context.ExitModal); + } + + public IEnumerable BeforePop(ModalPopContext context) + { + foreach (var receiver in _callbackReceivers) + receiver.BeforePop(context.EnterModal, context.FirstExitModal); + + var handles = new List + { + context.FirstExitModal.BeforeExit(false, context.EnterModal) + }; + + if (context.EnterModal != null) + handles.Add(context.EnterModal.BeforeEnter(false, context.FirstExitModal)); + + return handles; + } + + public void AfterPop(ModalPopContext context) + { + context.FirstExitModal.AfterExit(false, context.EnterModal); + if (context.EnterModal != null) + context.EnterModal.AfterEnter(false, context.FirstExitModal); + + foreach (var receiver in _callbackReceivers) + receiver.AfterPop(context.EnterModal, context.FirstExitModal); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs.meta new file mode 100644 index 00000000..20544955 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ab757eca3efd460cb6a7e876c8b5fd69 +timeCreated: 1746287127 \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs index 83394126..e1057616 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs @@ -290,6 +290,7 @@ private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnim c = instance.AddComponent(pageType); var context = PagePushContext.Create(pageId, (Page)c, _orderedPageIds, _pages, stack); + var lifecycleHandler = new PageLifecycleHandler(_callbackReceivers); _assetLoadHandles.Add(context.EnterPageId, assetLoadHandle); onLoad?.Invoke((context.EnterPageId, context.EnterPage)); @@ -298,14 +299,7 @@ private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnim yield return null; // Preprocess - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.BeforePush(context.EnterPage, context.ExitPage); - - var preprocessHandles = new List(); - if (context.ExitPage != null) preprocessHandles.Add(context.ExitPage.BeforeExit(true, context.EnterPage)); - - preprocessHandles.Add(context.EnterPage.BeforeEnter(true, context.ExitPage)); - + var preprocessHandles = lifecycleHandler.BeforePush(context); foreach (var coroutineHandle in preprocessHandles) while (!coroutineHandle.IsTerminated) yield return coroutineHandle; @@ -334,13 +328,7 @@ private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnim _transitionHandler.End(); // Postprocess - if (context.ExitPage != null) - context.ExitPage.AfterExit(true, context.EnterPage); - - context.EnterPage.AfterEnter(true, context.ExitPage); - - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.AfterPush(context.EnterPage, context.ExitPage); + lifecycleHandler.AfterPush(context); // Unload Unused Page if (!_isActivePageStacked && context.ExitPage != null) @@ -373,18 +361,11 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) _transitionHandler.Begin(); var context = PagePopContext.Create(_orderedPageIds, _pages, popCount); - var exitPage = context.ExitPage; - var enterPage = context.EnterPage; + var lifecycleHandler = new PageLifecycleHandler(_callbackReceivers); // Preprocess - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.BeforePop(enterPage, exitPage); - - var preprocessHandles = new List - { - exitPage.BeforeExit(false, enterPage) - }; - if (enterPage != null) preprocessHandles.Add(enterPage.BeforeEnter(false, exitPage)); - + var preprocessHandles = lifecycleHandler.BeforePop(context); + foreach (var coroutineHandle in preprocessHandles) while (!coroutineHandle.IsTerminated) yield return coroutineHandle; @@ -392,9 +373,9 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) // Play Animations var animationHandles = new List { - exitPage.Exit(false, playAnimation, enterPage) + context.ExitPage.Exit(false, playAnimation, context.EnterPage) }; - if (enterPage != null) animationHandles.Add(enterPage.Enter(false, playAnimation, exitPage)); + if (context.EnterPage != null) animationHandles.Add(context.EnterPage.Enter(false, playAnimation, context.ExitPage)); foreach (var coroutineHandle in animationHandles) while (!coroutineHandle.IsTerminated) @@ -411,13 +392,10 @@ private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) _transitionHandler.End(); // Postprocess - exitPage.AfterExit(false, enterPage); - if (enterPage != null) enterPage.AfterEnter(false, exitPage); - - foreach (var callbackReceiver in _callbackReceivers) callbackReceiver.AfterPop(enterPage, exitPage); + lifecycleHandler.AfterPop(context); // Unload Unused Page - var beforeReleaseHandle = exitPage.BeforeRelease(); + var beforeReleaseHandle = context.ExitPage.BeforeRelease(); while (!beforeReleaseHandle.IsTerminated) yield return null; for (var i = 0; i < context.ExitPageIds.Count; i++) diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs new file mode 100644 index 00000000..3a1d010c --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs @@ -0,0 +1,66 @@ +using System.Collections.Generic; +using UnityScreenNavigator.Runtime.Foundation.Coroutine; + +namespace UnityScreenNavigator.Runtime.Core.Page +{ + internal sealed class PageLifecycleHandler + { + private readonly IEnumerable _callbackReceivers; + + public PageLifecycleHandler(IEnumerable callbackReceivers) + { + _callbackReceivers = callbackReceivers; + } + + public IEnumerable BeforePush(PagePushContext context) + { + foreach (var receiver in _callbackReceivers) + receiver.BeforePush(context.EnterPage, context.ExitPage); + + var handles = new List(); + if (context.ExitPage != null) + handles.Add(context.ExitPage.BeforeExit(true, context.EnterPage)); + + handles.Add(context.EnterPage.BeforeEnter(true, context.ExitPage)); + + return handles; + } + + public void AfterPush(PagePushContext context) + { + if (context.ExitPage != null) + context.ExitPage.AfterExit(true, context.EnterPage); + + context.EnterPage.AfterEnter(true, context.ExitPage); + + foreach (var receiver in _callbackReceivers) + receiver.AfterPush(context.EnterPage, context.ExitPage); + } + + public IEnumerable BeforePop(PagePopContext context) + { + foreach (var receiver in _callbackReceivers) + receiver.BeforePop(context.EnterPage, context.ExitPage); + + var handles = new List + { + context.ExitPage.BeforeExit(false, context.EnterPage) + }; + + if (context.EnterPage != null) + handles.Add(context.EnterPage.BeforeEnter(false, context.ExitPage)); + + return handles; + } + + public void AfterPop(PagePopContext context) + { + context.ExitPage.AfterExit(false, context.EnterPage); + if (context.EnterPage != null) + context.EnterPage.AfterEnter(false, context.ExitPage); + + foreach (var receiver in _callbackReceivers) + receiver.AfterPop(context.EnterPage, context.ExitPage); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs.meta new file mode 100644 index 00000000..cf6b06af --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16b0520c7143940679200c4983b85097 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs index 32568d4b..bfb6cbfd 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs @@ -297,18 +297,12 @@ private IEnumerator ShowRoutine(string sheetId, bool playAnimation) "Cannot transition because the sheet is already active."); var context = SheetShowContext.Create(sheetId, ActiveSheetId, _sheets); + var lifecycleHandler = new SheetLifecycleHandler(_callbackReceivers); _transitionHandler.Begin(); - // Preprocess - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.BeforeShow(context.EnterSheet, context.ExitSheet); - - var preprocessHandles = new List(); - if (context.ExitSheet != null) preprocessHandles.Add(context.ExitSheet.BeforeExit(context.EnterSheet)); - - preprocessHandles.Add(context.EnterSheet.BeforeEnter(context.ExitSheet)); + var preprocessHandles = lifecycleHandler.BeforeShow(context); foreach (var coroutineHandle in preprocessHandles) while (!coroutineHandle.IsTerminated) yield return null; @@ -329,12 +323,7 @@ private IEnumerator ShowRoutine(string sheetId, bool playAnimation) _transitionHandler.End(); // Postprocess - if (context.ExitSheet != null) context.ExitSheet.AfterExit(context.EnterSheet); - - context.EnterSheet.AfterEnter(context.ExitSheet); - - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.AfterShow(context.EnterSheet, context.ExitSheet); + lifecycleHandler.AfterShow(context); } private IEnumerator HideRoutine(bool playAnimation) @@ -350,14 +339,13 @@ private IEnumerator HideRoutine(bool playAnimation) _transitionHandler.Begin(); var context = SheetHideContext.Create(_sheets[ActiveSheetId], playAnimation); + var lifecycleHandler = new SheetLifecycleHandler(_callbackReceivers); // Preprocess - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.BeforeHide(context.ExitSheet); - - var preprocessHandle = context.ExitSheet.BeforeExit(null); - while (!preprocessHandle.IsTerminated) - yield return preprocessHandle; + var preprocessHandles = lifecycleHandler.BeforeHide(context); + foreach (var coroutineHandle in preprocessHandles) + while (!coroutineHandle.IsTerminated) + yield return coroutineHandle; // Play Animation var animationHandle = context.ExitSheet.Exit(context.PlayAnimation, null); @@ -369,9 +357,7 @@ private IEnumerator HideRoutine(bool playAnimation) _transitionHandler.End(); // Postprocess - context.ExitSheet.AfterExit(null); - foreach (var callbackReceiver in _callbackReceivers) - callbackReceiver.AfterHide(context.ExitSheet); + lifecycleHandler.AfterHide(context); } /// diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs new file mode 100644 index 00000000..978a3fbd --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using UnityScreenNavigator.Runtime.Foundation.Coroutine; + +namespace UnityScreenNavigator.Runtime.Core.Sheet +{ + internal sealed class SheetLifecycleHandler + { + private readonly IEnumerable _callbackReceivers; + + public SheetLifecycleHandler(IEnumerable callbackReceivers) + { + _callbackReceivers = callbackReceivers; + } + + public IEnumerable BeforeShow(SheetShowContext context) + { + foreach (var receiver in _callbackReceivers) + receiver.BeforeShow(context.EnterSheet, context.ExitSheet); + + var handles = new List(); + if (context.ExitSheet != null) + handles.Add(context.ExitSheet.BeforeExit(context.EnterSheet)); + + handles.Add(context.EnterSheet.BeforeEnter(context.ExitSheet)); + + return handles; + } + + public void AfterShow(SheetShowContext context) + { + if (context.ExitSheet != null) + context.ExitSheet.AfterExit(context.EnterSheet); + + context.EnterSheet.AfterEnter(context.ExitSheet); + + foreach (var receiver in _callbackReceivers) + receiver.AfterShow(context.EnterSheet, context.ExitSheet); + } + + public IEnumerable BeforeHide(SheetHideContext context) + { + foreach (var receiver in _callbackReceivers) + receiver.BeforeHide(context.ExitSheet); + + var handles = new List + { + context.ExitSheet.BeforeExit(null) + }; + + return handles; + } + + public void AfterHide(SheetHideContext context) + { + context.ExitSheet.AfterExit(null); + + foreach (var receiver in _callbackReceivers) + receiver.AfterHide(context.ExitSheet); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs.meta new file mode 100644 index 00000000..8524d092 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e04331e9ae77471ebee0ac96e27654a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From b36f9d10d1e096205162dbb78532d4c324ade6c4 Mon Sep 17 00:00:00 2001 From: Haruki Yano Date: Sun, 4 May 2025 22:05:32 +0900 Subject: [PATCH 7/7] =?UTF-8?q?Push=20/=20Pop=20=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=82=92LifecycleHandler=E3=81=AB=E5=88=87=E3=82=8A=E5=87=BA?= =?UTF-8?q?=E3=81=99=E5=AF=BE=E5=BF=9C=E3=80=81=E3=81=9D=E3=81=AE=E4=BB=96?= =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF=E3=83=AA=E3=83=B3?= =?UTF-8?q?=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Loading/LoadingPagePresenter.cs | 7 + .../Runtime/Core/Modal/ModalContainer.cs | 290 +++++++++--------- .../Core/Modal/ModalLifecycleHandler.cs | 90 +++++- .../Runtime/Core/Modal/ModalPopContext.cs | 2 + .../Runtime/Core/Modal/ModalPushContext.cs | 5 +- .../Runtime/Core/Page/PageContainer.cs | 283 +++++++++-------- .../Runtime/Core/Page/PageLifecycleHandler.cs | 87 +++++- .../Runtime/Core/Page/PagePopContext.cs | 10 +- .../Runtime/Core/Page/PagePushContext.cs | 24 +- .../Runtime/Core/Sheet/SheetContainer.cs | 135 ++++---- .../Runtime/Core/Sheet/SheetHideContext.cs | 8 +- .../Core/Sheet/SheetLifecycleHandler.cs | 47 ++- .../Core/Sheet/SheetRegisterContext.cs | 22 +- 13 files changed, 605 insertions(+), 405 deletions(-) diff --git a/Assets/Demo/Core/Scripts/Presentation/Loading/LoadingPagePresenter.cs b/Assets/Demo/Core/Scripts/Presentation/Loading/LoadingPagePresenter.cs index b1b7ebf1..2451ea92 100644 --- a/Assets/Demo/Core/Scripts/Presentation/Loading/LoadingPagePresenter.cs +++ b/Assets/Demo/Core/Scripts/Presentation/Loading/LoadingPagePresenter.cs @@ -1,3 +1,4 @@ +using System.Collections; using Demo.Core.Scripts.Presentation.Shared; using Demo.Core.Scripts.View.Loading; @@ -12,6 +13,12 @@ public LoadingPagePresenter(LoadingPage view, ITransitionService transitionServi protected override void ViewDidPushEnter(LoadingPage view, LoadingViewState viewState) { + view.StartCoroutine(WaitAndCallHomeLoadingPageShown()); + } + + private IEnumerator WaitAndCallHomeLoadingPageShown() + { + yield return null; TransitionService.HomeLoadingPageShown(); } } diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs index 65857b29..225a8050 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalContainer.cs @@ -14,39 +14,35 @@ namespace UnityScreenNavigator.Runtime.Core.Modal [RequireComponent(typeof(RectMask2D))] public sealed class ModalContainer : MonoBehaviour, IScreenContainer { - private static readonly Dictionary InstanceCacheByTransform = - new Dictionary(); + private static readonly Dictionary InstanceCacheByTransform = new(); - private static readonly Dictionary InstanceCacheByName = - new Dictionary(); + private static readonly Dictionary InstanceCacheByName = new(); [SerializeField] private string _name; [SerializeField] private ModalBackdropStrategy _backdropStrategy = ModalBackdropStrategy.GeneratePerModal; - + [SerializeField] private ModalBackdrop _overrideBackdropPrefab; - private readonly Dictionary> _assetLoadHandles - = new Dictionary>(); + private readonly Dictionary> _assetLoadHandles = new(); - private readonly List _callbackReceivers = - new List(); + private readonly List _callbackReceivers = new(); - private readonly Dictionary _modals = new Dictionary(); + private readonly Dictionary _modals = new(); - private readonly List _orderedModalIds = new List(); + private readonly List _orderedModalIds = new(); - private readonly Dictionary> _preloadedResourceHandles = - new Dictionary>(); + private readonly Dictionary> _preloadedResourceHandles = new(); private IAssetLoader _assetLoader; + private IModalBackdropHandler _backdropHandler; + private ModalBackdrop _backdropPrefab; private CanvasGroup _canvasGroup; - public static List Instances { get; } = new List(); - - private IModalBackdropHandler _backdropHandler; + private ModalLifecycleHandler _lifecycleHandler; private ScreenContainerTransitionHandler _transitionHandler; + public static List Instances { get; } = new(); /// /// By default, in is used. @@ -58,11 +54,6 @@ public IAssetLoader AssetLoader set => _assetLoader = value; } - /// - /// True if in transition. - /// - public bool IsInTransition => _transitionHandler.IsInTransition; - /// /// List of ModalIds sorted in the order they are stacked. /// @@ -73,12 +64,6 @@ public IAssetLoader AssetLoader /// public IReadOnlyDictionary Modals => _modals; - public bool Interactable - { - get => _canvasGroup.interactable; - set => _canvasGroup.interactable = value; - } - private void Awake() { Instances.Add(this); @@ -93,6 +78,10 @@ private void Awake() _canvasGroup = gameObject.GetOrAddComponent(); _backdropHandler = ModalBackdropHandlerFactory.Create(_backdropStrategy, _backdropPrefab); _transitionHandler = new ScreenContainerTransitionHandler(this); + _lifecycleHandler = new ModalLifecycleHandler( + (RectTransform)transform, + _callbackReceivers, + _backdropHandler); } private void OnDestroy() @@ -122,6 +111,17 @@ private void OnDestroy() Instances.Remove(this); } + /// + /// True if in transition. + /// + public bool IsInTransition => _transitionHandler.IsInTransition; + + public bool Interactable + { + get => _canvasGroup.interactable; + set => _canvasGroup.interactable = value; + } + /// /// Get the that manages the modal to which belongs. /// @@ -193,11 +193,20 @@ public void RemoveCallbackReceiver(IModalContainerCallbackReceiver callbackRecei /// /// /// - public AsyncProcessHandle Push(string resourceKey, bool playAnimation, string modalId = null, - bool loadAsync = true, Action<(string modalId, Modal modal)> onLoad = null) + public AsyncProcessHandle Push( + string resourceKey, + bool playAnimation, + string modalId = null, + bool loadAsync = true, + Action<(string modalId, Modal modal)> onLoad = null + ) { - return CoroutineManager.Instance.Run(PushRoutine(typeof(Modal), resourceKey, playAnimation, onLoad, - loadAsync, modalId)); + return CoroutineManager.Instance.Run(PushRoutine(typeof(Modal), + resourceKey, + playAnimation, + onLoad, + loadAsync, + modalId)); } /// @@ -210,10 +219,20 @@ public AsyncProcessHandle Push(string resourceKey, bool playAnimation, string mo /// /// /// - public AsyncProcessHandle Push(Type modalType, string resourceKey, bool playAnimation, string modalId = null, - bool loadAsync = true, Action<(string modalId, Modal modal)> onLoad = null) + public AsyncProcessHandle Push( + Type modalType, + string resourceKey, + bool playAnimation, + string modalId = null, + bool loadAsync = true, + Action<(string modalId, Modal modal)> onLoad = null + ) { - return CoroutineManager.Instance.Run(PushRoutine(modalType, resourceKey, playAnimation, onLoad, loadAsync, + return CoroutineManager.Instance.Run(PushRoutine(modalType, + resourceKey, + playAnimation, + onLoad, + loadAsync, modalId)); } @@ -227,12 +246,21 @@ public AsyncProcessHandle Push(Type modalType, string resourceKey, bool playAnim /// /// /// - public AsyncProcessHandle Push(string resourceKey, bool playAnimation, string modalId = null, - bool loadAsync = true, Action<(string modalId, TModal modal)> onLoad = null) + public AsyncProcessHandle Push( + string resourceKey, + bool playAnimation, + string modalId = null, + bool loadAsync = true, + Action<(string modalId, TModal modal)> onLoad = null + ) where TModal : Modal { - return CoroutineManager.Instance.Run(PushRoutine(typeof(TModal), resourceKey, playAnimation, - x => onLoad?.Invoke((x.modalId, (TModal)x.modal)), loadAsync, modalId)); + return CoroutineManager.Instance.Run(PushRoutine(typeof(TModal), + resourceKey, + playAnimation, + x => onLoad?.Invoke((x.modalId, (TModal)x.modal)), + loadAsync, + modalId)); } /// @@ -260,7 +288,7 @@ public AsyncProcessHandle Pop(bool playAnimation, string destinationModalId) var modalId = _orderedModalIds[i]; if (modalId == destinationModalId) break; - + popCount++; } @@ -270,139 +298,100 @@ public AsyncProcessHandle Pop(bool playAnimation, string destinationModalId) return CoroutineManager.Instance.Run(PopRoutine(playAnimation, popCount)); } - private IEnumerator PushRoutine(Type modalType, string resourceKey, bool playAnimation, - Action<(string modalId, Modal modal)> onLoad = null, bool loadAsync = true, string modalId = null) + private IEnumerator PushRoutine( + Type modalType, + string resourceKey, + bool playAnimation, + Action<(string modalId, Modal modal)> onLoad = null, + bool loadAsync = true, + string modalId = null + ) { - if (resourceKey == null) - throw new ArgumentNullException(nameof(resourceKey)); - - if (IsInTransition) - throw new InvalidOperationException( - "Cannot transition because the screen is already in transition."); + Assert.IsNotNull(resourceKey); + Assert.IsFalse(IsInTransition, + "Cannot transition because the screen is already in transition."); _transitionHandler.Begin(); - var assetLoadHandle = loadAsync - ? AssetLoader.LoadAsync(resourceKey) - : AssetLoader.Load(resourceKey); - if (!assetLoadHandle.IsDone) yield return new WaitUntil(() => assetLoadHandle.IsDone); - - if (assetLoadHandle.Status == AssetLoadStatus.Failed) throw assetLoadHandle.OperationException; - - var instance = Instantiate(assetLoadHandle.Result); - if (!instance.TryGetComponent(modalType, out var c)) - c = instance.AddComponent(modalType); - - var context = ModalPushContext.Create(modalId, (Modal)c, _orderedModalIds, _modals); - var lifecycleHandler = new ModalLifecycleHandler(_callbackReceivers); + // If the user explicitly specifies modalId, use it, otherwise generate it + modalId ??= Guid.NewGuid().ToString(); - _assetLoadHandles.Add(context.ModalId, assetLoadHandle); - onLoad?.Invoke((context.ModalId, context.EnterModal)); - var afterLoadHandle = context.EnterModal.AfterLoad((RectTransform)transform); - while (!afterLoadHandle.IsTerminated) - yield return null; + Modal modal = null; + yield return LoadModal(modalType, + resourceKey, + loadAsync, + (m, lh) => + { + modal = m; + _assetLoadHandles.Add(modalId, lh); + onLoad?.Invoke((modalId, m)); + }); - // Preprocess - var preprocessHandles = lifecycleHandler.BeforePush(context); - foreach (var coroutineHandle in preprocessHandles) - while (!coroutineHandle.IsTerminated) - yield return coroutineHandle; + var context = ModalPushContext.Create(modalId, modal, _orderedModalIds, _modals); - // Play Animation - var animationHandles = new List(); - animationHandles.Add( - _backdropHandler.BeforeModalEnter(context.EnterModal, context.EnterModalIndex, playAnimation)); + yield return _lifecycleHandler.AfterLoad(context); - if (context.ExitModal != null) - animationHandles.Add(context.ExitModal.Exit(true, playAnimation, context.EnterModal)); + yield return _lifecycleHandler.BeforePush(context); - animationHandles.Add(context.EnterModal.Enter(true, playAnimation, context.ExitModal)); + yield return _lifecycleHandler.Push(context, playAnimation); - foreach (var coroutineHandle in animationHandles) - while (!coroutineHandle.IsTerminated) - yield return coroutineHandle; + _lifecycleHandler.AfterPush(context); - _backdropHandler.AfterModalEnter(context.EnterModal, context.EnterModalIndex, true); - - // End Transition _modals.Add(context.ModalId, context.EnterModal); _orderedModalIds.Add(context.ModalId); - _transitionHandler.End(); - // Postprocess - lifecycleHandler.AfterPush(context); + _transitionHandler.End(); } private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) { Assert.IsTrue(popCount >= 1); + Assert.IsTrue(_orderedModalIds.Count >= popCount, + "Cannot transition because the modal count is less than the pop count."); + Assert.IsFalse(IsInTransition, + "Cannot transition because the screen is already in transition."); - if (_orderedModalIds.Count < popCount) - throw new InvalidOperationException( - "Cannot transition because the modal count is less than the pop count."); - - if (IsInTransition) - throw new InvalidOperationException( - "Cannot transition because the screen is already in transition."); + _transitionHandler.Begin(); var context = ModalPopContext.Create(_orderedModalIds, _modals, popCount); - var lifecycleHandler = new ModalLifecycleHandler(_callbackReceivers); - - _transitionHandler.Begin(); - // Preprocess - var preprocessHandles = lifecycleHandler.BeforePop(context); - - foreach (var coroutineHandle in preprocessHandles) - while (!coroutineHandle.IsTerminated) - yield return coroutineHandle; + yield return _lifecycleHandler.BeforePop(context); - // Play Animation - var animationHandles = new List(); - for (var i = context.ExitModalIds.Count - 1; i >= 0; i--) - { - var exitModalId = context.ExitModalIds[i]; - var exitModal = _modals[exitModalId]; - var exitModalIndex = context.ExitModalIndices[i]; - var partnerModalId = i == 0 ? context.EnterModalId : context.ExitModalIds[i - 1]; - var partnerModal = partnerModalId == null ? null : _modals[partnerModalId]; - animationHandles.Add(_backdropHandler.BeforeModalExit(exitModal, exitModalIndex, playAnimation)); - animationHandles.Add(exitModal.Exit(false, playAnimation, partnerModal)); - } - - if (context.EnterModal != null) - animationHandles.Add(context.EnterModal.Enter(false, playAnimation, context.FirstExitModal)); + yield return _lifecycleHandler.Pop(context, playAnimation); - foreach (var coroutineHandle in animationHandles) - while (!coroutineHandle.IsTerminated) - yield return coroutineHandle; + _lifecycleHandler.AfterPop(context); - // End Transition for (var i = 0; i < context.ExitModalIds.Count; i++) { - var unusedModalId = context.ExitModalIds[i]; - _modals.Remove(unusedModalId); - _orderedModalIds.RemoveAt(_orderedModalIds.Count - 1); + var exitModal = context.ExitModals[i]; + var exitModalId = context.ExitModalIds[i]; + + exitModal.gameObject.SetActive(false); + _modals.Remove(exitModalId); + _orderedModalIds.Remove(exitModalId); } + _transitionHandler.End(); - // Postprocess - lifecycleHandler.AfterPop(context); - - // Unload Unused Page - var beforeReleaseHandle = context.FirstExitModal.BeforeRelease(); - while (!beforeReleaseHandle.IsTerminated) yield return null; + // Resource cleanup isn't tied to the transition itself, so it should be handled asynchronously in the background. + StartCoroutine(AfterPopRoutine(context)); + } + + private IEnumerator AfterPopRoutine( + ModalPopContext context + ) + { + yield return _lifecycleHandler.AfterPopRoutine(context); for (var i = 0; i < context.ExitModalIds.Count; i++) { - var unusedModalId = context.ExitModalIds[i]; - var unusedModal = context.ExitModals[i]; - var unusedModalIndex = context.ExitModalIndices[i]; - var loadHandle = _assetLoadHandles[unusedModalId]; - Destroy(unusedModal.gameObject); + var exitModalId = context.ExitModalIds[i]; + var exitModal = context.ExitModals[i]; + var loadHandle = _assetLoadHandles[exitModalId]; + + Destroy(exitModal.gameObject); AssetLoader.Release(loadHandle); - _assetLoadHandles.Remove(unusedModalId); - _backdropHandler.AfterModalExit(context.FirstExitModal, unusedModalIndex, playAnimation); + _assetLoadHandles.Remove(exitModalId); } } @@ -447,5 +436,30 @@ public void ReleasePreloaded(string resourceKey) var handle = _preloadedResourceHandles[resourceKey]; AssetLoader.Release(handle); } + + private IEnumerator LoadModal( + Type modalType, + string resourceKey, + bool loadAsync, + Action> onLoaded + ) + { + var assetLoadHandle = loadAsync + ? AssetLoader.LoadAsync(resourceKey) + : AssetLoader.Load(resourceKey); + + if (!assetLoadHandle.IsDone) + yield return new WaitUntil(() => assetLoadHandle.IsDone); + + if (assetLoadHandle.Status == AssetLoadStatus.Failed) + throw assetLoadHandle.OperationException; + + var instance = Instantiate(assetLoadHandle.Result); + if (!instance.TryGetComponent(modalType, out var c)) + c = instance.AddComponent(modalType); + + var modal = (Modal)c; + onLoaded?.Invoke(modal, assetLoadHandle); + } } -} +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs index 02ab96e8..9f604bee 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalLifecycleHandler.cs @@ -1,18 +1,34 @@ +using System.Collections; using System.Collections.Generic; +using System.Linq; +using UnityEngine; using UnityScreenNavigator.Runtime.Foundation.Coroutine; namespace UnityScreenNavigator.Runtime.Core.Modal { internal sealed class ModalLifecycleHandler { + private readonly IModalBackdropHandler _backdropHandler; private readonly IEnumerable _callbackReceivers; + private readonly RectTransform _containerTransform; - public ModalLifecycleHandler(IEnumerable callbackReceivers) + public ModalLifecycleHandler( + RectTransform containerTransform, + IEnumerable callbackReceivers, + IModalBackdropHandler backdropHandler + ) { + _containerTransform = containerTransform; _callbackReceivers = callbackReceivers; + _backdropHandler = backdropHandler; } - public IEnumerable BeforePush(ModalPushContext context) + public IEnumerator AfterLoad(ModalPushContext context) + { + yield return context.EnterModal.AfterLoad(_containerTransform); + } + + public IEnumerator BeforePush(ModalPushContext context) { foreach (var receiver in _callbackReceivers) receiver.BeforePush(context.EnterModal, context.ExitModal); @@ -22,8 +38,27 @@ public IEnumerable BeforePush(ModalPushContext context) handles.Add(context.ExitModal.BeforeExit(true, context.EnterModal)); handles.Add(context.EnterModal.BeforeEnter(true, context.ExitModal)); + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; + } + + public IEnumerator Push(ModalPushContext context, bool playAnimation) + { + var handles = new List + { + _backdropHandler.BeforeModalEnter(context.EnterModal, context.EnterModalIndex, playAnimation) + }; + + if (context.ExitModal != null) + handles.Add(context.ExitModal.Exit(true, playAnimation, context.EnterModal)); + + handles.Add(context.EnterModal.Enter(true, playAnimation, context.ExitModal)); + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; - return handles; + _backdropHandler.AfterModalEnter(context.EnterModal, context.EnterModalIndex, true); } public void AfterPush(ModalPushContext context) @@ -37,30 +72,65 @@ public void AfterPush(ModalPushContext context) receiver.AfterPush(context.EnterModal, context.ExitModal); } - public IEnumerable BeforePop(ModalPopContext context) + public IEnumerator BeforePop(ModalPopContext context) { foreach (var receiver in _callbackReceivers) receiver.BeforePop(context.EnterModal, context.FirstExitModal); - var handles = new List - { - context.FirstExitModal.BeforeExit(false, context.EnterModal) - }; + var handles = new List(); + foreach (var exitModal in context.ExitModals) + handles.Add(exitModal.BeforeExit(false, context.EnterModal)); if (context.EnterModal != null) handles.Add(context.EnterModal.BeforeEnter(false, context.FirstExitModal)); - return handles; + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; + } + + public IEnumerator Pop(ModalPopContext context, bool playAnimation) + { + var handles = new List(); + + for (var i = 0; i < context.ExitModals.Count; i++) + { + var exitModal = context.ExitModals[i]; + var exitModalIndex = context.ExitModalIndices[i]; + var partner = i == context.ExitModals.Count - 1 ? context.EnterModal : context.ExitModals[i + 1]; + + handles.Add(_backdropHandler.BeforeModalExit(exitModal, exitModalIndex, playAnimation)); + handles.Add(exitModal.Exit(false, playAnimation, partner)); + } + + if (context.EnterModal != null) + handles.Add(context.EnterModal.Enter(false, playAnimation, context.FirstExitModal)); + + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; + + _backdropHandler.AfterModalExit(context.FirstExitModal, context.FirstExitModalIndex, playAnimation); } public void AfterPop(ModalPopContext context) { - context.FirstExitModal.AfterExit(false, context.EnterModal); + foreach (var exitModal in context.ExitModals) + exitModal.AfterExit(false, context.EnterModal); if (context.EnterModal != null) context.EnterModal.AfterEnter(false, context.FirstExitModal); foreach (var receiver in _callbackReceivers) receiver.AfterPop(context.EnterModal, context.FirstExitModal); } + + public IEnumerator AfterPopRoutine(ModalPopContext context) + { + var handles = context.ExitModals.Select(exitModal => exitModal.BeforeRelease()); + + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; + } } } \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs index 695f6a2e..c7cad898 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPopContext.cs @@ -13,6 +13,8 @@ internal readonly struct ModalPopContext public Modal FirstExitModal => ExitModals[0]; + public int FirstExitModalIndex => ExitModalIndices[0]; + private ModalPopContext( List exitModalIds, List exitModals, diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs index 579a35f7..cc4d1453 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/ModalPushContext.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; namespace UnityScreenNavigator.Runtime.Core.Modal @@ -35,15 +34,13 @@ public static ModalPushContext Create( Dictionary modals ) { - var resolvedModalId = modalId ?? Guid.NewGuid().ToString(); - var hasExit = orderedModalIds.Count > 0; var exitId = hasExit ? orderedModalIds[orderedModalIds.Count - 1] : null; var exitModal = hasExit ? modals[exitId] : null; var enterIndex = modals.Count; - return new ModalPushContext(resolvedModalId, enterModal, exitId, exitModal, enterIndex); + return new ModalPushContext(modalId, enterModal, exitId, exitModal, enterIndex); } } } \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs index e1057616..700d86a2 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageContainer.cs @@ -14,35 +14,31 @@ namespace UnityScreenNavigator.Runtime.Core.Page [RequireComponent(typeof(RectMask2D))] public sealed class PageContainer : MonoBehaviour, IScreenContainer { - private static readonly Dictionary InstanceCacheByTransform = - new Dictionary(); + private static readonly Dictionary InstanceCacheByTransform = new(); - private static readonly Dictionary InstanceCacheByName = - new Dictionary(); + private static readonly Dictionary InstanceCacheByName = new(); [SerializeField] private string _name; - private readonly Dictionary> _assetLoadHandles - = new Dictionary>(); + private readonly Dictionary> _assetLoadHandles = new(); - private readonly List _callbackReceivers = - new List(); + private readonly List _callbackReceivers = new(); - private readonly List _orderedPageIds = new List(); + private readonly List _orderedPageIds = new(); - private readonly Dictionary _pages = new Dictionary(); + private readonly Dictionary _pages = new(); - private readonly Dictionary> _preloadedResourceHandles = - new Dictionary>(); + private readonly Dictionary> _preloadedResourceHandles = new(); private IAssetLoader _assetLoader; private CanvasGroup _canvasGroup; private bool _isActivePageStacked; - public static List Instances { get; } = new List(); + private PageLifecycleHandler _lifecycleHandler; private ScreenContainerTransitionHandler _transitionHandler; + public static List Instances { get; } = new(); /// /// By default, in is used. @@ -55,12 +51,7 @@ public IAssetLoader AssetLoader } /// - /// True if in transition. - /// - public bool IsInTransition => _transitionHandler.IsInTransition; - - /// - /// List of PageIds sorted in the order they are stacked. + /// List of PageIds sorted in the order they are stacked. /// public IReadOnlyList OrderedPagesIds => _orderedPageIds; @@ -69,12 +60,6 @@ public IAssetLoader AssetLoader /// public IReadOnlyDictionary Pages => _pages; - public bool Interactable - { - get => _canvasGroup.interactable; - set => _canvasGroup.interactable = value; - } - private void Awake() { Instances.Add(this); @@ -84,6 +69,7 @@ private void Awake() _canvasGroup = gameObject.GetOrAddComponent(); _transitionHandler = new ScreenContainerTransitionHandler(this); + _lifecycleHandler = new PageLifecycleHandler((RectTransform)transform, _callbackReceivers); } private void OnDestroy() @@ -114,6 +100,17 @@ private void OnDestroy() Instances.Remove(this); } + /// + /// True if in transition. + /// + public bool IsInTransition => _transitionHandler.IsInTransition; + + public bool Interactable + { + get => _canvasGroup.interactable; + set => _canvasGroup.interactable = value; + } + /// /// Get the that manages the page to which belongs. /// @@ -186,11 +183,22 @@ public void RemoveCallbackReceiver(IPageContainerCallbackReceiver callbackReceiv /// /// /// - public AsyncProcessHandle Push(string resourceKey, bool playAnimation, bool stack = true, string pageId = null, - bool loadAsync = true, Action<(string pageId, Page page)> onLoad = null) + public AsyncProcessHandle Push( + string resourceKey, + bool playAnimation, + bool stack = true, + string pageId = null, + bool loadAsync = true, + Action<(string pageId, Page page)> onLoad = null + ) { - return CoroutineManager.Instance.Run(PushRoutine(typeof(Page), resourceKey, playAnimation, stack, onLoad, - loadAsync, pageId)); + return CoroutineManager.Instance.Run(PushRoutine(typeof(Page), + resourceKey, + playAnimation, + stack, + onLoad, + loadAsync, + pageId)); } /// @@ -204,11 +212,23 @@ public AsyncProcessHandle Push(string resourceKey, bool playAnimation, bool stac /// /// /// - public AsyncProcessHandle Push(Type pageType, string resourceKey, bool playAnimation, bool stack = true, - string pageId = null, bool loadAsync = true, Action<(string pageId, Page page)> onLoad = null) + public AsyncProcessHandle Push( + Type pageType, + string resourceKey, + bool playAnimation, + bool stack = true, + string pageId = null, + bool loadAsync = true, + Action<(string pageId, Page page)> onLoad = null + ) { - return CoroutineManager.Instance.Run(PushRoutine(pageType, resourceKey, playAnimation, stack, onLoad, - loadAsync, pageId)); + return CoroutineManager.Instance.Run(PushRoutine(pageType, + resourceKey, + playAnimation, + stack, + onLoad, + loadAsync, + pageId)); } /// @@ -222,12 +242,23 @@ public AsyncProcessHandle Push(Type pageType, string resourceKey, bool playAnima /// /// /// - public AsyncProcessHandle Push(string resourceKey, bool playAnimation, bool stack = true, - string pageId = null, bool loadAsync = true, Action<(string pageId, TPage page)> onLoad = null) + public AsyncProcessHandle Push( + string resourceKey, + bool playAnimation, + bool stack = true, + string pageId = null, + bool loadAsync = true, + Action<(string pageId, TPage page)> onLoad = null + ) where TPage : Page { - return CoroutineManager.Instance.Run(PushRoutine(typeof(TPage), resourceKey, playAnimation, stack, - x => onLoad?.Invoke((x.pageId, (TPage)x.page)), loadAsync, pageId)); + return CoroutineManager.Instance.Run(PushRoutine(typeof(TPage), + resourceKey, + playAnimation, + stack, + x => onLoad?.Invoke((x.pageId, (TPage)x.page)), + loadAsync, + pageId)); } /// @@ -255,7 +286,7 @@ public AsyncProcessHandle Pop(bool playAnimation, string destinationPageId) var pageId = _orderedPageIds[i]; if (pageId == destinationPageId) break; - + popCount++; } @@ -265,150 +296,123 @@ public AsyncProcessHandle Pop(bool playAnimation, string destinationPageId) return CoroutineManager.Instance.Run(PopRoutine(playAnimation, popCount)); } - private IEnumerator PushRoutine(Type pageType, string resourceKey, bool playAnimation, bool stack = true, - Action<(string pageId, Page page)> onLoad = null, bool loadAsync = true, string pageId = null) + private IEnumerator PushRoutine( + Type pageType, + string resourceKey, + bool playAnimation, + bool stack = true, + Action<(string pageId, Page page)> onLoad = null, + bool loadAsync = true, + string pageId = null + ) { - if (resourceKey == null) - throw new ArgumentNullException(nameof(resourceKey)); + Assert.IsNotNull(resourceKey); + Assert.IsFalse(IsInTransition, + "Cannot transition because the screen is already in transition."); - if (IsInTransition) - throw new InvalidOperationException( - "Cannot transition because the screen is already in transition."); - _transitionHandler.Begin(); - // Setup - var assetLoadHandle = loadAsync - ? AssetLoader.LoadAsync(resourceKey) - : AssetLoader.Load(resourceKey); - if (!assetLoadHandle.IsDone) yield return new WaitUntil(() => assetLoadHandle.IsDone); - - if (assetLoadHandle.Status == AssetLoadStatus.Failed) throw assetLoadHandle.OperationException; + pageId ??= Guid.NewGuid().ToString(); - var instance = Instantiate(assetLoadHandle.Result); - if (!instance.TryGetComponent(pageType, out var c)) - c = instance.AddComponent(pageType); - - var context = PagePushContext.Create(pageId, (Page)c, _orderedPageIds, _pages, stack); - var lifecycleHandler = new PageLifecycleHandler(_callbackReceivers); + Page page = null; + yield return LoadPage(pageType, + resourceKey, + loadAsync, + (p, lh) => + { + page = p; + _assetLoadHandles.Add(pageId, lh); + onLoad?.Invoke((pageId, p)); + }); - _assetLoadHandles.Add(context.EnterPageId, assetLoadHandle); - onLoad?.Invoke((context.EnterPageId, context.EnterPage)); - var afterLoadHandle = context.EnterPage.AfterLoad((RectTransform)transform); - while (!afterLoadHandle.IsTerminated) - yield return null; + var context = PagePushContext.Create(pageId, page, _orderedPageIds, _pages, stack, _isActivePageStacked); - // Preprocess - var preprocessHandles = lifecycleHandler.BeforePush(context); - foreach (var coroutineHandle in preprocessHandles) - while (!coroutineHandle.IsTerminated) - yield return coroutineHandle; + yield return _lifecycleHandler.AfterLoad(context); - // Play Animations - var animationHandles = new List(); - if (context.ExitPage != null) - animationHandles.Add(context.ExitPage.Exit(true, playAnimation, context.EnterPage)); + yield return _lifecycleHandler.BeforePush(context); - animationHandles.Add(context.EnterPage.Enter(true, playAnimation, context.ExitPage)); + yield return _lifecycleHandler.Push(context, playAnimation); - foreach (var coroutineHandle in animationHandles) - while (!coroutineHandle.IsTerminated) - yield return coroutineHandle; + _lifecycleHandler.AfterPush(context); - // End Transition - if (!_isActivePageStacked && context.ExitPage != null) + if (context.ShouldRemoveExitPage) { + context.ExitPage.gameObject.SetActive(false); _pages.Remove(context.ExitPageId); _orderedPageIds.Remove(context.ExitPageId); } _pages.Add(context.EnterPageId, context.EnterPage); _orderedPageIds.Add(context.EnterPageId); + _isActivePageStacked = stack; _transitionHandler.End(); - // Postprocess - lifecycleHandler.AfterPush(context); + // Resource cleanup isn't tied to the transition itself, so it should be handled asynchronously in the background. + StartCoroutine(AfterPushRoutine(context)); + } - // Unload Unused Page - if (!_isActivePageStacked && context.ExitPage != null) + private IEnumerator AfterPushRoutine( + PagePushContext context + ) + { + yield return _lifecycleHandler.AfterPushRoutine(context); + if (context.ShouldRemoveExitPage) { - var beforeReleaseHandle = context.ExitPage.BeforeRelease(); - while (!beforeReleaseHandle.IsTerminated) yield return null; - + Destroy(context.ExitPage.gameObject); var handle = _assetLoadHandles[context.ExitPageId]; AssetLoader.Release(handle); - - Destroy(context.ExitPage.gameObject); _assetLoadHandles.Remove(context.ExitPageId); } - - _isActivePageStacked = stack; } private IEnumerator PopRoutine(bool playAnimation, int popCount = 1) { Assert.IsTrue(popCount >= 1); - - if (_pages.Count < popCount) - throw new InvalidOperationException( - "Cannot transition because the page count is less than the pop count."); - - if (IsInTransition) - throw new InvalidOperationException( - "Cannot transition because the screen is already in transition."); + Assert.IsTrue(_pages.Count >= popCount, + "Cannot transition because the page count is less than the pop count."); + Assert.IsFalse(IsInTransition, + "Cannot transition because the screen is already in transition."); _transitionHandler.Begin(); var context = PagePopContext.Create(_orderedPageIds, _pages, popCount); - var lifecycleHandler = new PageLifecycleHandler(_callbackReceivers); - // Preprocess - var preprocessHandles = lifecycleHandler.BeforePop(context); - - foreach (var coroutineHandle in preprocessHandles) - while (!coroutineHandle.IsTerminated) - yield return coroutineHandle; + yield return _lifecycleHandler.BeforePop(context); - // Play Animations - var animationHandles = new List - { - context.ExitPage.Exit(false, playAnimation, context.EnterPage) - }; - if (context.EnterPage != null) animationHandles.Add(context.EnterPage.Enter(false, playAnimation, context.ExitPage)); + yield return _lifecycleHandler.Pop(context, playAnimation); - foreach (var coroutineHandle in animationHandles) - while (!coroutineHandle.IsTerminated) - yield return coroutineHandle; + _lifecycleHandler.AfterPop(context); - // End Transition for (var i = 0; i < context.ExitPageIds.Count; i++) { - var unusedPageId = context.ExitPageIds[i]; - _pages.Remove(unusedPageId); + var exitPage = context.ExitPages[i]; + var exitPageId = context.ExitPageIds[i]; + exitPage.gameObject.SetActive(false); + _pages.Remove(exitPageId); _orderedPageIds.RemoveAt(_orderedPageIds.Count - 1); } - _transitionHandler.End(); + _isActivePageStacked = true; - // Postprocess - lifecycleHandler.AfterPop(context); + _transitionHandler.End(); - // Unload Unused Page - var beforeReleaseHandle = context.ExitPage.BeforeRelease(); - while (!beforeReleaseHandle.IsTerminated) yield return null; + // Resource cleanup isn't tied to the transition itself, so it should be handled asynchronously in the background. + StartCoroutine(AfterPopRoutine(context)); + } + private IEnumerator AfterPopRoutine(PagePopContext context) + { + yield return _lifecycleHandler.AfterPopRoutine(context); for (var i = 0; i < context.ExitPageIds.Count; i++) { var unusedPageId = context.ExitPageIds[i]; var unusedPage = context.ExitPages[i]; - var loadHandle = _assetLoadHandles[unusedPageId]; Destroy(unusedPage.gameObject); + var loadHandle = _assetLoadHandles[unusedPageId]; AssetLoader.Release(loadHandle); _assetLoadHandles.Remove(unusedPageId); } - - _isActivePageStacked = true; } public AsyncProcessHandle Preload(string resourceKey, bool loadAsync = true) @@ -453,5 +457,30 @@ public void ReleasePreloaded(string resourceKey) _preloadedResourceHandles.Remove(resourceKey); AssetLoader.Release(handle); } + + private IEnumerator LoadPage( + Type pageType, + string resourceKey, + bool loadAsync, + Action> onLoaded + ) + { + var assetLoadHandle = loadAsync + ? AssetLoader.LoadAsync(resourceKey) + : AssetLoader.Load(resourceKey); + + if (!assetLoadHandle.IsDone) + yield return new WaitUntil(() => assetLoadHandle.IsDone); + + if (assetLoadHandle.Status == AssetLoadStatus.Failed) + throw assetLoadHandle.OperationException; + + var instance = Instantiate(assetLoadHandle.Result); + if (!instance.TryGetComponent(pageType, out var c)) + c = instance.AddComponent(pageType); + + var page = (Page)c; + onLoaded?.Invoke(page, assetLoadHandle); + } } -} +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs index 3a1d010c..fea3b945 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PageLifecycleHandler.cs @@ -1,4 +1,7 @@ +using System.Collections; using System.Collections.Generic; +using System.Linq; +using UnityEngine; using UnityScreenNavigator.Runtime.Foundation.Coroutine; namespace UnityScreenNavigator.Runtime.Core.Page @@ -6,13 +9,23 @@ namespace UnityScreenNavigator.Runtime.Core.Page internal sealed class PageLifecycleHandler { private readonly IEnumerable _callbackReceivers; + private readonly RectTransform _containerTransform; - public PageLifecycleHandler(IEnumerable callbackReceivers) + public PageLifecycleHandler( + RectTransform containerTransform, + IEnumerable callbackReceivers + ) { + _containerTransform = containerTransform; _callbackReceivers = callbackReceivers; } - public IEnumerable BeforePush(PagePushContext context) + public IEnumerator AfterLoad(PagePushContext context) + { + yield return context.EnterPage.AfterLoad(_containerTransform); + } + + public IEnumerator BeforePush(PagePushContext context) { foreach (var receiver in _callbackReceivers) receiver.BeforePush(context.EnterPage, context.ExitPage); @@ -23,7 +36,23 @@ public IEnumerable BeforePush(PagePushContext context) handles.Add(context.EnterPage.BeforeEnter(true, context.ExitPage)); - return handles; + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; + } + + public IEnumerator Push(PagePushContext context, bool playAnimation) + { + var handles = new List(); + + if (context.ExitPage != null) + handles.Add(context.ExitPage.Exit(true, playAnimation, context.EnterPage)); + + handles.Add(context.EnterPage.Enter(true, playAnimation, context.ExitPage)); + + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; } public void AfterPush(PagePushContext context) @@ -37,30 +66,68 @@ public void AfterPush(PagePushContext context) receiver.AfterPush(context.EnterPage, context.ExitPage); } - public IEnumerable BeforePop(PagePopContext context) + public IEnumerator AfterPushRoutine(PagePushContext context) + { + if (context.IsExitPageStacked || context.ExitPage == null) + yield break; + + var handle = context.ExitPage.BeforeRelease(); + while (!handle.IsTerminated) + yield return handle; + } + + public IEnumerator BeforePop(PagePopContext context) { foreach (var receiver in _callbackReceivers) receiver.BeforePop(context.EnterPage, context.ExitPage); - + + var handles = new List(); + foreach (var exitModal in context.ExitPages) + handles.Add(exitModal.BeforeExit(false, context.EnterPage)); + + if (context.EnterPage != null) + handles.Add(context.EnterPage.BeforeEnter(false, context.ExitPage)); + + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; + } + + public IEnumerator Pop(PagePopContext context, bool playAnimation) + { + // When popping multiple pages at once, only play the animation for + // the first page exiting (currently visible) and the page that is coming in. var handles = new List { - context.ExitPage.BeforeExit(false, context.EnterPage) + context.ExitPage.Exit(false, playAnimation, context.EnterPage) }; if (context.EnterPage != null) - handles.Add(context.EnterPage.BeforeEnter(false, context.ExitPage)); + handles.Add(context.EnterPage.Enter(false, playAnimation, context.ExitPage)); - return handles; + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; } public void AfterPop(PagePopContext context) { - context.ExitPage.AfterExit(false, context.EnterPage); + foreach (var exitModal in context.ExitPages) + exitModal.AfterExit(false, context.EnterPage); if (context.EnterPage != null) context.EnterPage.AfterEnter(false, context.ExitPage); foreach (var receiver in _callbackReceivers) receiver.AfterPop(context.EnterPage, context.ExitPage); } + + public IEnumerator AfterPopRoutine(PagePopContext context) + { + var handles = context.ExitPages.Select(exitModal => exitModal.BeforeRelease()); + + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; + } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs index 109ea22d..0d033eeb 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePopContext.cs @@ -39,21 +39,21 @@ public static PagePopContext Create( int popCount ) { - var unusedIds = new List(); - var unusedPages = new List(); + var exitPageIds = new List(); + var exitPages = new List(); for (var i = orderedPageIds.Count - 1; i >= orderedPageIds.Count - popCount; i--) { var id = orderedPageIds[i]; - unusedIds.Add(id); - unusedPages.Add(pages[id]); + exitPageIds.Add(id); + exitPages.Add(pages[id]); } var enterIndex = orderedPageIds.Count - popCount - 1; var enterId = enterIndex >= 0 ? orderedPageIds[enterIndex] : null; var enter = enterId != null ? pages[enterId] : null; - return new PagePopContext(orderedPageIds, pages, unusedIds, unusedPages, enterId, enter); + return new PagePopContext(orderedPageIds, pages, exitPageIds, exitPages, enterId, enter); } } } \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs index a7ada8a7..274275db 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/PagePushContext.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; namespace UnityScreenNavigator.Runtime.Core.Page @@ -11,15 +10,25 @@ internal readonly struct PagePushContext public string ExitPageId { get; } public Page ExitPage { get; } - public bool IsStacked { get; } + public bool Stack { get; } + public bool IsExitPageStacked { get; } + public bool ShouldRemoveExitPage => ExitPage != null && !IsExitPageStacked; - private PagePushContext(string enterPageId, Page enterPage, string exitPageId, Page exitPage, bool isStacked) + private PagePushContext( + string enterPageId, + Page enterPage, + string exitPageId, + Page exitPage, + bool stack, + bool isExitPageStacked + ) { EnterPageId = enterPageId; EnterPage = enterPage; ExitPageId = exitPageId; ExitPage = exitPage; - IsStacked = isStacked; + Stack = stack; + IsExitPageStacked = isExitPageStacked; } public static PagePushContext Create( @@ -27,7 +36,8 @@ public static PagePushContext Create( Page enterPage, List orderedPageIds, Dictionary pages, - bool isStacked + bool stack, + bool isExitPageStacked ) { var hasExit = orderedPageIds.Count > 0; @@ -35,9 +45,7 @@ bool isStacked var exitPage = hasExit ? pages[exitPageId] : null; - var resolvedPageId = pageId ?? Guid.NewGuid().ToString(); - - return new PagePushContext(resolvedPageId, enterPage, exitPageId, exitPage, isStacked); + return new PagePushContext(pageId, enterPage, exitPageId, exitPage, stack, isExitPageStacked); } } } \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs index bfb6cbfd..e3f0ba55 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetContainer.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +using UnityEngine.Assertions; using UnityEngine.UI; using UnityScreenNavigator.Runtime.Core.Shared; using UnityScreenNavigator.Runtime.Foundation; @@ -35,6 +36,7 @@ private readonly Dictionary> _assetLoadHandl public static List Instances { get; } = new List(); private ScreenContainerTransitionHandler _transitionHandler; + private SheetLifecycleHandler _lifecycleHandler; /// /// By default, in is used. @@ -84,6 +86,7 @@ private void Awake() if (!string.IsNullOrWhiteSpace(_name)) InstanceCacheByName.Add(_name, this); _canvasGroup = gameObject.GetOrAddComponent(); _transitionHandler = new ScreenContainerTransitionHandler(this); + _lifecycleHandler = new SheetLifecycleHandler((RectTransform)transform, _callbackReceivers); } private void OnDestroy() @@ -247,35 +250,26 @@ public AsyncProcessHandle Register(string resourceKey, private IEnumerator RegisterRoutine(Type sheetType, string resourceKey, Action<(string sheetId, Sheet sheet)> onLoad = null, bool loadAsync = true, string sheetId = null) { - if (resourceKey == null) throw new ArgumentNullException(nameof(resourceKey)); + Assert.IsNotNull(resourceKey); - var context = new SheetRegisterContext(sheetType, resourceKey, sheetId); + sheetId ??= Guid.NewGuid().ToString(); - // アセットのロード - var assetLoadHandle = loadAsync - ? AssetLoader.LoadAsync(resourceKey) - : AssetLoader.Load(resourceKey); - context.SetAssetLoadHandle(assetLoadHandle); - while (!assetLoadHandle.IsDone) yield return null; - - if (assetLoadHandle.Status == AssetLoadStatus.Failed) throw assetLoadHandle.OperationException; + Sheet sheet = null; + yield return LoadSheet(sheetType, + resourceKey, + loadAsync, + (s, lh) => + { + sheet = s; + _sheets.Add(sheetId, sheet); + _sheetNameToId[resourceKey] = sheetId; + _assetLoadHandles.Add(sheetId, lh); + onLoad?.Invoke((sheetId, s)); + }); - // シートのインスタンス化と初期化 - var instance = Instantiate(assetLoadHandle.Result); - if (!instance.TryGetComponent(sheetType, out var c)) - c = instance.AddComponent(sheetType); - var sheet = (Sheet)c; - context.SetSheet(sheet); + var context = new SheetRegisterContext(sheetId, sheet); - // シートの登録 - _sheets.Add(context.SheetId, sheet); - _sheetNameToId[resourceKey] = context.SheetId; - _assetLoadHandles.Add(context.SheetId, assetLoadHandle); - onLoad?.Invoke((context.SheetId, sheet)); - - // シートの後処理 - var afterLoadHandle = sheet.AfterLoad((RectTransform)transform); - while (!afterLoadHandle.IsTerminated) yield return null; + yield return _lifecycleHandler.AfterLoad(context); yield return context.SheetId; } @@ -288,76 +282,46 @@ private IEnumerator ShowByResourceKeyRoutine(string resourceKey, bool playAnimat private IEnumerator ShowRoutine(string sheetId, bool playAnimation) { - if (IsInTransition) - throw new InvalidOperationException( - "Cannot transition because the screen is already in transition."); - - if (ActiveSheetId != null && ActiveSheetId == sheetId) - throw new InvalidOperationException( - "Cannot transition because the sheet is already active."); + Assert.IsFalse(IsInTransition, + "Cannot transition because the screen is already in transition."); + Assert.IsFalse(ActiveSheetId != null && ActiveSheetId == sheetId, + "Cannot transition because the sheet is already active."); var context = SheetShowContext.Create(sheetId, ActiveSheetId, _sheets); - var lifecycleHandler = new SheetLifecycleHandler(_callbackReceivers); _transitionHandler.Begin(); - // Preprocess - var preprocessHandles = lifecycleHandler.BeforeShow(context); - foreach (var coroutineHandle in preprocessHandles) - while (!coroutineHandle.IsTerminated) - yield return null; + yield return _lifecycleHandler.BeforeShow(context); - // Play Animation - var animationHandles = new List(); - if (context.ExitSheet != null) - animationHandles.Add(context.ExitSheet.Exit(playAnimation, context.EnterSheet)); + yield return _lifecycleHandler.Show(context, playAnimation); - animationHandles.Add(context.EnterSheet.Enter(playAnimation, context.ExitSheet)); + _lifecycleHandler.AfterShow(context); - foreach (var handle in animationHandles) - while (!handle.IsTerminated) - yield return null; - - // End Transition ActiveSheetId = sheetId; + _transitionHandler.End(); - - // Postprocess - lifecycleHandler.AfterShow(context); } private IEnumerator HideRoutine(bool playAnimation) { - if (IsInTransition) - throw new InvalidOperationException( - "Cannot transition because the screen is already in transition."); - - if (ActiveSheetId == null) - throw new InvalidOperationException( - "Cannot transition because there is no active sheets."); + Assert.IsFalse(IsInTransition, + "Cannot transition because the screen is already in transition."); + Assert.IsNotNull(ActiveSheetId, + "Cannot transition because there is no active sheets."); _transitionHandler.Begin(); - var context = SheetHideContext.Create(_sheets[ActiveSheetId], playAnimation); - var lifecycleHandler = new SheetLifecycleHandler(_callbackReceivers); + var context = SheetHideContext.Create(_sheets[ActiveSheetId]); + + yield return _lifecycleHandler.BeforeHide(context); - // Preprocess - var preprocessHandles = lifecycleHandler.BeforeHide(context); - foreach (var coroutineHandle in preprocessHandles) - while (!coroutineHandle.IsTerminated) - yield return coroutineHandle; + yield return _lifecycleHandler.Hide(context, playAnimation); - // Play Animation - var animationHandle = context.ExitSheet.Exit(context.PlayAnimation, null); - while (!animationHandle.IsTerminated) - yield return null; + _lifecycleHandler.AfterHide(context); - // End Transition ActiveSheetId = null; + _transitionHandler.End(); - - // Postprocess - lifecycleHandler.AfterHide(context); } /// @@ -377,5 +341,30 @@ public void UnregisterAll() _assetLoadHandles.Clear(); } + + private IEnumerator LoadSheet( + Type sheetType, + string resourceKey, + bool loadAsync, + Action> onLoaded + ) + { + var assetLoadHandle = loadAsync + ? AssetLoader.LoadAsync(resourceKey) + : AssetLoader.Load(resourceKey); + + if (!assetLoadHandle.IsDone) + yield return new WaitUntil(() => assetLoadHandle.IsDone); + + if (assetLoadHandle.Status == AssetLoadStatus.Failed) + throw assetLoadHandle.OperationException; + + var instance = Instantiate(assetLoadHandle.Result); + if (!instance.TryGetComponent(sheetType, out var c)) + c = instance.AddComponent(sheetType); + + var sheet = (Sheet)c; + onLoaded?.Invoke(sheet, assetLoadHandle); + } } } diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs index 0fcb6781..917ec395 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetHideContext.cs @@ -2,18 +2,16 @@ namespace UnityScreenNavigator.Runtime.Core.Sheet { public sealed class SheetHideContext { - private SheetHideContext(Sheet exitSheet, bool playAnimation) + private SheetHideContext(Sheet exitSheet) { ExitSheet = exitSheet; - PlayAnimation = playAnimation; } public Sheet ExitSheet { get; } - public bool PlayAnimation { get; } - public static SheetHideContext Create(Sheet exitSheet, bool playAnimation) + public static SheetHideContext Create(Sheet exitSheet) { - return new SheetHideContext(exitSheet, playAnimation); + return new SheetHideContext(exitSheet); } } } \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs index 978a3fbd..5c61d118 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetLifecycleHandler.cs @@ -1,18 +1,30 @@ +using System.Collections; using System.Collections.Generic; +using UnityEngine; using UnityScreenNavigator.Runtime.Foundation.Coroutine; namespace UnityScreenNavigator.Runtime.Core.Sheet { internal sealed class SheetLifecycleHandler { + private readonly RectTransform _containerTransform; private readonly IEnumerable _callbackReceivers; - public SheetLifecycleHandler(IEnumerable callbackReceivers) + public SheetLifecycleHandler( + RectTransform containerTransform, + IEnumerable callbackReceivers + ) { + _containerTransform = containerTransform; _callbackReceivers = callbackReceivers; } - public IEnumerable BeforeShow(SheetShowContext context) + public IEnumerator AfterLoad(SheetRegisterContext context) + { + yield return context.Sheet.AfterLoad(_containerTransform); + } + + public IEnumerator BeforeShow(SheetShowContext context) { foreach (var receiver in _callbackReceivers) receiver.BeforeShow(context.EnterSheet, context.ExitSheet); @@ -23,9 +35,25 @@ public IEnumerable BeforeShow(SheetShowContext context) handles.Add(context.EnterSheet.BeforeEnter(context.ExitSheet)); - return handles; + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return null; } + public IEnumerator Show(SheetShowContext context, bool playAnimation) + { + var handles = new List(); + + if (context.ExitSheet != null) + handles.Add(context.ExitSheet.Exit(playAnimation, context.EnterSheet)); + + handles.Add(context.EnterSheet.Enter(playAnimation, context.ExitSheet)); + + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; + } + public void AfterShow(SheetShowContext context) { if (context.ExitSheet != null) @@ -37,7 +65,7 @@ public void AfterShow(SheetShowContext context) receiver.AfterShow(context.EnterSheet, context.ExitSheet); } - public IEnumerable BeforeHide(SheetHideContext context) + public IEnumerator BeforeHide(SheetHideContext context) { foreach (var receiver in _callbackReceivers) receiver.BeforeHide(context.ExitSheet); @@ -47,7 +75,16 @@ public IEnumerable BeforeHide(SheetHideContext context) context.ExitSheet.BeforeExit(null) }; - return handles; + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return handle; + } + + public IEnumerator Hide(SheetHideContext context, bool playAnimation) + { + var handle = context.ExitSheet.Exit(playAnimation, null); + while (!handle.IsTerminated) + yield return null; } public void AfterHide(SheetHideContext context) diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs index c39eb89e..852e6291 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/SheetRegisterContext.cs @@ -1,32 +1,14 @@ -using System; -using UnityEngine; -using UnityScreenNavigator.Runtime.Foundation.AssetLoader; - namespace UnityScreenNavigator.Runtime.Core.Sheet { public sealed class SheetRegisterContext { - public Type SheetType { get; } - public string ResourceKey { get; } public string SheetId { get; } public Sheet Sheet { get; private set; } - public AssetLoadHandle AssetLoadHandle { get; private set; } - - public SheetRegisterContext(Type sheetType, string resourceKey, string sheetId = null) - { - SheetType = sheetType; - ResourceKey = resourceKey; - SheetId = sheetId ?? Guid.NewGuid().ToString(); - } - public void SetSheet(Sheet sheet) + public SheetRegisterContext(string sheetId, Sheet sheet) { + SheetId = sheetId; Sheet = sheet; } - - public void SetAssetLoadHandle(AssetLoadHandle handle) - { - AssetLoadHandle = handle; - } } } \ No newline at end of file