From 7b9cf3db9494bae5a5b3affa0be7ce426926d356 Mon Sep 17 00:00:00 2001 From: Haruki Yano Date: Thu, 25 Jan 2024 15:49:06 +0900 Subject: [PATCH] Fixed an issue where lifecycle events were running in parallel regardless of priority. --- .../UnitShop/prefab_unit_shop_page.prefab | 46 +++- .../Runtime/Core/Modal/Modal.cs | 55 ++-- .../Runtime/Core/Page/Page.cs | 67 ++--- .../Core/Shared/CompositeLifecycleEvent.cs | 92 +++++++ .../Shared/CompositeLifecycleEvent.cs.meta | 3 + .../Runtime/Core/Sheet/Sheet.cs | 40 +-- .../Foundation/PriorityCollection.meta | 8 - .../PriorityCollection/PriorityList.cs | 235 ----------------- .../PriorityCollection/PriorityList.cs.meta | 11 - .../PriorityCollection/PriorityQueue.cs | 240 ------------------ .../PriorityCollection/PriorityQueue.cs.meta | 11 - ProjectSettings/EditorBuildSettings.asset | 2 +- ProjectSettings/ProjectSettings.asset | 160 ++++++------ ProjectSettings/SceneTemplateSettings.json | 167 ++++++++++++ 14 files changed, 449 insertions(+), 688 deletions(-) create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Shared/CompositeLifecycleEvent.cs create mode 100644 Assets/UnityScreenNavigator/Runtime/Core/Shared/CompositeLifecycleEvent.cs.meta delete mode 100644 Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection.meta delete mode 100644 Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityList.cs delete mode 100644 Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityList.cs.meta delete mode 100644 Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityQueue.cs delete mode 100644 Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityQueue.cs.meta create mode 100644 ProjectSettings/SceneTemplateSettings.json diff --git a/Assets/Demo/Core/UI/Prefabs/UnitShop/prefab_unit_shop_page.prefab b/Assets/Demo/Core/UI/Prefabs/UnitShop/prefab_unit_shop_page.prefab index ecbd3ce..aee7824 100644 --- a/Assets/Demo/Core/UI/Prefabs/UnitShop/prefab_unit_shop_page.prefab +++ b/Assets/Demo/Core/UI/Prefabs/UnitShop/prefab_unit_shop_page.prefab @@ -29,6 +29,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 2059416667690313989} m_Father: {fileID: 8450074404203694270} @@ -62,6 +63,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -90,6 +92,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Navigation: m_Mode: 3 + m_WrapAround: 0 m_SelectOnUp: {fileID: 0} m_SelectOnDown: {fileID: 0} m_SelectOnLeft: {fileID: 0} @@ -148,11 +151,11 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 2589045541635396804} - {fileID: 1192139009211831089} - {fileID: 2998522702226043333} - - {fileID: 6760322821518479456} - {fileID: 5878940358006106949} m_Father: {fileID: 0} m_RootOrder: 0 @@ -242,16 +245,17 @@ RectTransform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1307706430403383489} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] - m_Father: {fileID: 6372800624481524282} - m_RootOrder: 3 + m_Father: {fileID: 2998522702226043333} + m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 0, y: 0.5} - m_AnchoredPosition: {x: -90, y: 0} + m_AnchoredPosition: {x: -679, y: 0} m_SizeDelta: {x: 773, y: 1031} m_Pivot: {x: 0, y: 0.5} --- !u!222 &2660123416614449903 @@ -277,6 +281,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -319,6 +324,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5878940358006106949} m_RootOrder: 0 @@ -351,6 +357,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -452,7 +459,9 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: + - {fileID: 6760322821518479456} - {fileID: 8450074404203694270} m_Father: {fileID: 6372800624481524282} m_RootOrder: 2 @@ -485,6 +494,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 0, g: 0, b: 0, a: 0.5019608} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -527,6 +537,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8450074404203694270} m_RootOrder: 0 @@ -591,6 +602,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1808596545503699798} m_RootOrder: 0 @@ -623,6 +635,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -724,6 +737,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6372800624481524282} m_RootOrder: 1 @@ -756,6 +770,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -798,6 +813,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 5878940358006106949} m_RootOrder: 1 @@ -830,6 +846,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 0.10980392, g: 0.10980392, b: 0.10980392, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -873,6 +890,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 6372800624481524282} m_RootOrder: 0 @@ -959,6 +977,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 8304464744858344028} m_RootOrder: 0 @@ -991,6 +1010,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -1093,11 +1113,12 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 3944702612881151298} - {fileID: 7113000009776303329} m_Father: {fileID: 6372800624481524282} - m_RootOrder: 4 + m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1127,6 +1148,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -1155,6 +1177,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Navigation: m_Mode: 3 + m_WrapAround: 0 m_SelectOnUp: {fileID: 0} m_SelectOnDown: {fileID: 0} m_SelectOnLeft: {fileID: 0} @@ -1213,6 +1236,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 637676143738182646} m_Father: {fileID: 8450074404203694270} @@ -1246,6 +1270,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -1274,6 +1299,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Navigation: m_Mode: 3 + m_WrapAround: 0 m_SelectOnUp: {fileID: 0} m_SelectOnDown: {fileID: 0} m_SelectOnLeft: {fileID: 0} @@ -1332,6 +1358,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 2380251157368437729} m_Father: {fileID: 8450074404203694270} @@ -1365,6 +1392,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -1393,6 +1421,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Navigation: m_Mode: 3 + m_WrapAround: 0 m_SelectOnUp: {fileID: 0} m_SelectOnDown: {fileID: 0} m_SelectOnLeft: {fileID: 0} @@ -1449,13 +1478,14 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 7225803148355229542} - {fileID: 3176250877568932684} - {fileID: 8304464744858344028} - {fileID: 1808596545503699798} m_Father: {fileID: 2998522702226043333} - m_RootOrder: 0 + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1511,6 +1541,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3176250877568932684} m_RootOrder: 0 @@ -1543,6 +1574,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Modal/Modal.cs b/Assets/UnityScreenNavigator/Runtime/Core/Modal/Modal.cs index f98fd48..de38a4b 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Modal/Modal.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Modal/Modal.cs @@ -1,12 +1,10 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using UnityEngine; using UnityScreenNavigator.Runtime.Core.Shared; using UnityScreenNavigator.Runtime.Foundation; using UnityScreenNavigator.Runtime.Foundation.Coroutine; -using UnityScreenNavigator.Runtime.Foundation.PriorityCollection; #if USN_USE_ASYNC_METHODS using System.Threading.Tasks; #endif @@ -39,7 +37,7 @@ private Progress TransitionProgressReporter } } - private readonly PriorityList _lifecycleEvents = new PriorityList(); + private readonly CompositeLifecycleEvent _lifecycleEvents = new(); public string Identifier { @@ -157,25 +155,26 @@ public virtual IEnumerator Cleanup() public void AddLifecycleEvent(IModalLifecycleEvent lifecycleEvent, int priority = 0) { - _lifecycleEvents.Add(lifecycleEvent, priority); + _lifecycleEvents.AddItem(lifecycleEvent, priority); } public void RemoveLifecycleEvent(IModalLifecycleEvent lifecycleEvent) { - _lifecycleEvents.Remove(lifecycleEvent); + _lifecycleEvents.RemoveItem(lifecycleEvent); } internal AsyncProcessHandle AfterLoad(RectTransform parentTransform) { _rectTransform = (RectTransform)transform; _canvasGroup = gameObject.GetOrAddComponent(); - _lifecycleEvents.Add(this, 0); + _lifecycleEvents.AddItem(this, 0); _identifier = _usePrefabNameAsIdentifier ? gameObject.name.Replace("(Clone)", string.Empty) : _identifier; _parentTransform = parentTransform; _rectTransform.FillParent(_parentTransform); _canvasGroup.alpha = 0.0f; - return CoroutineManager.Instance.Run(CreateCoroutine(_lifecycleEvents.Select(x => x.Initialize()))); + var lifecycleEventTask = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.Initialize()); + return CoroutineManager.Instance.Run(CreateCoroutine(lifecycleEventTask)); } internal AsyncProcessHandle BeforeEnter(bool push, Modal partnerModal) @@ -196,12 +195,10 @@ private IEnumerator BeforeEnterRoutine(bool push, Modal partnerModal) SetTransitionProgress(0.0f); - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var routines = push - ? _lifecycleEvents.Select(x => x.WillPushEnter()).ToArray() - : _lifecycleEvents.Select(x => x.WillPopEnter()).ToArray(); - var handle = CoroutineManager.Instance.Run(CreateCoroutine(routines)); - + var lifecycleEventTask = push + ? _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillPushEnter()) + : _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillPopEnter()); + var handle = CoroutineManager.Instance.Run(CreateCoroutine(lifecycleEventTask)); while (!handle.IsTerminated) yield return null; } @@ -239,14 +236,10 @@ private IEnumerator EnterRoutine(bool push, bool playAnimation, Modal partnerMod internal void AfterEnter(bool push, Modal partnerModal) { - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var lifecycleEvents = _lifecycleEvents.ToArray(); if (push) - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidPushEnter(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidPushEnter()); else - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidPopEnter(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidPopEnter()); IsTransitioning = false; TransitionAnimationType = null; @@ -269,13 +262,12 @@ private IEnumerator BeforeExitRoutine(bool push, Modal partnerModal) } SetTransitionProgress(0.0f); - - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. + var routines = push - ? _lifecycleEvents.Select(x => x.WillPushExit()).ToArray() - : _lifecycleEvents.Select(x => x.WillPopExit()).ToArray(); - var handle = CoroutineManager.Instance.Run(CreateCoroutine(routines)); + ? _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillPushExit()) + : _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillPopExit()); + var handle = CoroutineManager.Instance.Run(CreateCoroutine(routines)); while (!handle.IsTerminated) yield return null; } @@ -311,14 +303,10 @@ private IEnumerator ExitRoutine(bool push, bool playAnimation, Modal partnerModa internal void AfterExit(bool push, Modal partnerModal) { - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var lifecycleEvents = _lifecycleEvents.ToArray(); if (push) - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidPushExit(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidPushExit()); else - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidPopExit(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidPopExit()); IsTransitioning = false; TransitionAnimationType = null; @@ -326,14 +314,13 @@ internal void AfterExit(bool push, Modal partnerModal) internal void BeforeReleaseAndForget() { - foreach (var lifecycleEvent in _lifecycleEvents) - lifecycleEvent.Cleanup(); + var _ = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.Cleanup()); } internal AsyncProcessHandle BeforeRelease() { - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - return CoroutineManager.Instance.Run(CreateCoroutine(_lifecycleEvents.Select(x => x.Cleanup()).ToArray())); + var lifecycleEventTask = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.Cleanup()); + return CoroutineManager.Instance.Run(CreateCoroutine(lifecycleEventTask)); } #if USN_USE_ASYNC_METHODS diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Page/Page.cs b/Assets/UnityScreenNavigator/Runtime/Core/Page/Page.cs index e48e473..febec84 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Page/Page.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Page/Page.cs @@ -1,12 +1,10 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using UnityEngine; using UnityScreenNavigator.Runtime.Core.Shared; using UnityScreenNavigator.Runtime.Foundation; using UnityScreenNavigator.Runtime.Foundation.Coroutine; -using UnityScreenNavigator.Runtime.Foundation.PriorityCollection; #if USN_USE_ASYNC_METHODS using System.Threading.Tasks; #endif @@ -23,8 +21,7 @@ [SerializeField] [EnabledIf(nameof(_usePrefabNameAsIdentifier), false)] [SerializeField] private int _renderingOrder; - [SerializeField] - private PageTransitionAnimationContainer _animationContainer = new PageTransitionAnimationContainer(); + [SerializeField] private PageTransitionAnimationContainer _animationContainer = new(); private CanvasGroup _canvasGroup; private RectTransform _parentTransform; @@ -41,7 +38,7 @@ private Progress TransitionProgressReporter } } - private readonly PriorityList _lifecycleEvents = new PriorityList(); + private readonly CompositeLifecycleEvent _lifecycleEvents = new(); public string Identifier { @@ -159,19 +156,19 @@ public virtual IEnumerator Cleanup() public void AddLifecycleEvent(IPageLifecycleEvent lifecycleEvent, int priority = 0) { - _lifecycleEvents.Add(lifecycleEvent, priority); + _lifecycleEvents.AddItem(lifecycleEvent, priority); } public void RemoveLifecycleEvent(IPageLifecycleEvent lifecycleEvent) { - _lifecycleEvents.Remove(lifecycleEvent); + _lifecycleEvents.RemoveItem(lifecycleEvent); } internal AsyncProcessHandle AfterLoad(RectTransform parentTransform) { _rectTransform = (RectTransform)transform; _canvasGroup = gameObject.GetOrAddComponent(); - _lifecycleEvents.Add(this, 0); + _lifecycleEvents.AddItem(this, 0); _identifier = _usePrefabNameAsIdentifier ? gameObject.name.Replace("(Clone)", string.Empty) : _identifier; _parentTransform = parentTransform; _rectTransform.FillParent(_parentTransform); @@ -193,9 +190,8 @@ internal AsyncProcessHandle AfterLoad(RectTransform parentTransform) _canvasGroup.alpha = 0.0f; - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var initializeEvents = _lifecycleEvents.Select(x => x.Initialize()).ToArray(); - return CoroutineManager.Instance.Run(CreateCoroutine(initializeEvents)); + var lifecycleEventTask = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.Initialize()); + return CoroutineManager.Instance.Run(CreateCoroutine(lifecycleEventTask)); } @@ -214,11 +210,10 @@ private IEnumerator BeforeEnterRoutine(bool push, Page partnerPage) SetTransitionProgress(0.0f); _canvasGroup.alpha = 0.0f; - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var routines = push - ? _lifecycleEvents.Select(x => x.WillPushEnter()).ToArray() - : _lifecycleEvents.Select(x => x.WillPopEnter()).ToArray(); - var handle = CoroutineManager.Instance.Run(CreateCoroutine(routines)); + var lifecycleEventTask = push + ? _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillPushEnter()) + : _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillPopEnter()); + var handle = CoroutineManager.Instance.Run(CreateCoroutine(lifecycleEventTask)); while (!handle.IsTerminated) yield return null; @@ -253,14 +248,10 @@ private IEnumerator EnterRoutine(bool push, bool playAnimation, Page partnerPage internal void AfterEnter(bool push, Page partnerPage) { - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var lifecycleEvents = _lifecycleEvents.ToArray(); if (push) - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidPushEnter(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidPushEnter()); else - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidPopEnter(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidPopEnter()); IsTransitioning = false; TransitionAnimationType = null; @@ -280,10 +271,9 @@ private IEnumerator BeforeExitRoutine(bool push, Page partnerPage) SetTransitionProgress(0.0f); _canvasGroup.alpha = 1.0f; - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. var routines = push - ? _lifecycleEvents.Select(x => x.WillPushExit()).ToArray() - : _lifecycleEvents.Select(x => x.WillPopExit()).ToArray(); + ? _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillPushExit()) + : _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillPopExit()); var handle = CoroutineManager.Instance.Run(CreateCoroutine(routines)); while (!handle.IsTerminated) @@ -317,31 +307,25 @@ private IEnumerator ExitRoutine(bool push, bool playAnimation, Page partnerPage) internal void AfterExit(bool push, Page partnerPage) { - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var lifecycleEvents = _lifecycleEvents.ToArray(); if (push) - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidPushExit(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidPushExit()); else - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidPopExit(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidPopExit()); gameObject.SetActive(false); IsTransitioning = false; TransitionAnimationType = null; } - + internal void BeforeReleaseAndForget() { - foreach (var lifecycleEvent in _lifecycleEvents) - lifecycleEvent.Cleanup(); + var _ = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.Cleanup()); } internal AsyncProcessHandle BeforeRelease() { - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var cleanupEvents = _lifecycleEvents.Select(x => x.Cleanup()).ToArray(); - return CoroutineManager.Instance.Run(CreateCoroutine(cleanupEvents)); + var lifecycleEventTask = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.Cleanup()); + return CoroutineManager.Instance.Run(CreateCoroutine(lifecycleEventTask)); } #if USN_USE_ASYNC_METHODS @@ -370,12 +354,9 @@ async void WaitTaskAndCallback(Task task, Action callback) await task; callback?.Invoke(); } - + var isCompleted = false; - WaitTaskAndCallback(target, () => - { - isCompleted = true; - }); + WaitTaskAndCallback(target, () => { isCompleted = true; }); return new WaitUntil(() => isCompleted); #else return target; @@ -388,4 +369,4 @@ private void SetTransitionProgress(float progress) TransitionAnimationProgressChanged?.Invoke(progress); } } -} +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Shared/CompositeLifecycleEvent.cs b/Assets/UnityScreenNavigator/Runtime/Core/Shared/CompositeLifecycleEvent.cs new file mode 100644 index 0000000..a0e66f4 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Shared/CompositeLifecycleEvent.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using UnityScreenNavigator.Runtime.Foundation.Coroutine; + +namespace UnityScreenNavigator.Runtime.Core.Shared +{ + public sealed class CompositeLifecycleEvent + { + private readonly Dictionary> _priorityToLifecycleEvent = new(); + + /// + /// Returns the next priority value after the given priority. If the given priority is the highest, it returns null. + /// If the given priority is null, it returns the lowest priority. + /// Throws an exception if the given priority does not exist. + /// + /// The current priority value. If null, the lowest priority is returned. + /// The next priority value after the given priority, or null if the given priority is the highest. + /// Thrown when the given priority does not exist. + public int? FindNextPriority(int? priority) + { + var orderedPriorities = _priorityToLifecycleEvent.Keys.OrderBy(x => x).ToList(); + if (!priority.HasValue) + return orderedPriorities[0]; + var index = orderedPriorities.IndexOf(priority.Value); + if (index == -1) + throw new InvalidOperationException($"The priority {priority} does not exist."); + if (index == orderedPriorities.Count - 1) + return null; + return orderedPriorities[index + 1]; + } + + public IEnumerable GetItems(int priority) + { + if (!_priorityToLifecycleEvent.ContainsKey(priority)) + return Enumerable.Empty(); + return _priorityToLifecycleEvent[priority]; + } + + public void AddItem(TLifecycleEvent item, int priority) + { + if (!_priorityToLifecycleEvent.ContainsKey(priority)) + _priorityToLifecycleEvent[priority] = new List(); + _priorityToLifecycleEvent[priority].Add(item); + } + + public void RemoveItem(TLifecycleEvent item) + { + foreach (var pair in _priorityToLifecycleEvent) + if (pair.Value.Remove(item) && pair.Value.Count == 0) + { + _priorityToLifecycleEvent.Remove(pair.Key); + break; + } + } + + public async Task ExecuteLifecycleEventsSequentially(Func execute) + { + int? currentPriority = null; + while ((currentPriority = FindNextPriority(currentPriority)) != null) + { + // LifecycleEvents with the same Priority are executed in parallel. + var lifecycleEvents = GetItems(currentPriority.Value); + var tasks = lifecycleEvents.Select(execute).ToArray(); + await Task.WhenAll(tasks); + } + } + + public IEnumerator ExecuteLifecycleEventsSequentially(Func execute) + { + int? currentPriority = null; + while ((currentPriority = FindNextPriority(currentPriority)) != null) + { + // LifecycleEvents with the same Priority are executed in parallel. + var lifecycleEvents = GetItems(currentPriority.Value); + var handles = lifecycleEvents.Select(x => CoroutineManager.Instance.Run(execute(x))).ToArray(); + foreach (var handle in handles) + while (!handle.IsTerminated) + yield return null; + } + } + + public void ExecuteLifecycleEventsSequentially(Action execute) + { + foreach (var lifecycleEvent in _priorityToLifecycleEvent.Values) + foreach (var item in lifecycleEvent) + execute(item); + } + } +} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Shared/CompositeLifecycleEvent.cs.meta b/Assets/UnityScreenNavigator/Runtime/Core/Shared/CompositeLifecycleEvent.cs.meta new file mode 100644 index 0000000..3e314d4 --- /dev/null +++ b/Assets/UnityScreenNavigator/Runtime/Core/Shared/CompositeLifecycleEvent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8f03ab6b49044632a541970ea3a1101c +timeCreated: 1706158747 \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/Sheet.cs b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/Sheet.cs index 56d62a8..5ec941b 100644 --- a/Assets/UnityScreenNavigator/Runtime/Core/Sheet/Sheet.cs +++ b/Assets/UnityScreenNavigator/Runtime/Core/Sheet/Sheet.cs @@ -1,12 +1,10 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using UnityEngine; using UnityScreenNavigator.Runtime.Core.Shared; using UnityScreenNavigator.Runtime.Foundation; using UnityScreenNavigator.Runtime.Foundation.Coroutine; -using UnityScreenNavigator.Runtime.Foundation.PriorityCollection; #if USN_USE_ASYNC_METHODS using System.Threading.Tasks; #endif @@ -38,8 +36,8 @@ private Progress TransitionProgressReporter } } - private readonly PriorityList _lifecycleEvents = new PriorityList(); - + private readonly CompositeLifecycleEvent _lifecycleEvents = new(); + public string Identifier { get => _identifier; @@ -124,19 +122,19 @@ public virtual IEnumerator Cleanup() public void AddLifecycleEvent(ISheetLifecycleEvent lifecycleEvent, int priority = 0) { - _lifecycleEvents.Add(lifecycleEvent, priority); + _lifecycleEvents.AddItem(lifecycleEvent, priority); } public void RemoveLifecycleEvent(ISheetLifecycleEvent lifecycleEvent) { - _lifecycleEvents.Remove(lifecycleEvent); + _lifecycleEvents.RemoveItem(lifecycleEvent); } internal AsyncProcessHandle AfterLoad(RectTransform parentTransform) { _rectTransform = (RectTransform)transform; _canvasGroup = gameObject.GetOrAddComponent(); - _lifecycleEvents.Add(this, 0); + _lifecycleEvents.AddItem(this, 0); _parentTransform = parentTransform; _rectTransform.FillParent(_parentTransform); @@ -157,9 +155,8 @@ internal AsyncProcessHandle AfterLoad(RectTransform parentTransform) gameObject.SetActive(false); - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - return CoroutineManager.Instance.Run( - CreateCoroutine(_lifecycleEvents.Select(x => x.Initialize()).ToArray())); + var lifecycleEventTask = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.Initialize()); + return CoroutineManager.Instance.Run(CreateCoroutine(lifecycleEventTask)); } internal AsyncProcessHandle BeforeEnter(Sheet partnerSheet) @@ -177,9 +174,8 @@ private IEnumerator BeforeEnterRoutine(Sheet partnerSheet) _canvasGroup.alpha = 0.0f; - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var handle = - CoroutineManager.Instance.Run(CreateCoroutine(_lifecycleEvents.Select(x => x.WillEnter()).ToArray())); + var lifecycleEventTask = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillEnter()); + var handle = CoroutineManager.Instance.Run(CreateCoroutine(lifecycleEventTask)); while (!handle.IsTerminated) yield return null; } @@ -213,10 +209,7 @@ private IEnumerator EnterRoutine(bool playAnimation, Sheet partnerSheet) internal void AfterEnter(Sheet partnerSheet) { - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var lifecycleEvents = _lifecycleEvents.ToArray(); - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidEnter(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidEnter()); IsTransitioning = false; TransitionAnimationType = null; @@ -237,9 +230,8 @@ private IEnumerator BeforeExitRoutine(Sheet partnerSheet) _canvasGroup.alpha = 1.0f; - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var handle = - CoroutineManager.Instance.Run(CreateCoroutine(_lifecycleEvents.Select(x => x.WillExit()).ToArray())); + var lifecycleEventTask = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.WillExit()); + var handle = CoroutineManager.Instance.Run(CreateCoroutine(lifecycleEventTask)); while (!handle.IsTerminated) yield return null; } @@ -271,10 +263,7 @@ private IEnumerator ExitRoutine(bool playAnimation, Sheet partnerSheet) internal void AfterExit(Sheet partnerSheet) { - // Evaluate here because users may add/remove lifecycle events within the lifecycle events. - var lifecycleEvents = _lifecycleEvents.ToArray(); - foreach (var lifecycleEvent in lifecycleEvents) - lifecycleEvent.DidExit(); + _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.DidExit()); gameObject.SetActive(false); @@ -284,8 +273,7 @@ internal void AfterExit(Sheet partnerSheet) internal void BeforeReleaseAndForget() { - foreach (var lifecycleEvent in _lifecycleEvents) - lifecycleEvent.Cleanup(); + var _ = _lifecycleEvents.ExecuteLifecycleEventsSequentially(x => x.Cleanup()); } #if USN_USE_ASYNC_METHODS diff --git a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection.meta b/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection.meta deleted file mode 100644 index b883ff0..0000000 --- a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 003029a70304c419893e298dd4e75aaa -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityList.cs b/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityList.cs deleted file mode 100644 index e72f9bf..0000000 --- a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityList.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Threading; - -namespace UnityScreenNavigator.Runtime.Foundation.PriorityCollection -{ - /// - /// The list that will sort the items in order of priority. - /// - /// - public class PriorityList : IEnumerable, IEnumerable, ICollection, IReadOnlyCollection - { - private readonly LinkedList _nodes = new LinkedList(); - - public IEnumerator GetEnumerator() - { - foreach (var node in _nodes) - { - yield return node.Item; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public int Count => _nodes.Count; - - /// - /// Add objects based on priority. - /// If the priority is the same, the object added earlier will be placed in front. - /// - /// - /// - public void Add(T item, int priority) - { - var node = _nodes.First; - LinkedListNode beforeNode = null; - if (node == null) - { - _nodes.AddFirst(new Node(item, priority)); - return; - } - while (true) - { - if (node.Value.Priority > priority) - { - if (beforeNode == null) - { - _nodes.AddFirst(new Node(item, priority)); - } - else - { - _nodes.AddAfter(beforeNode, new Node(item, priority)); - } - return; - } - - beforeNode = node; - node = node.Next; - if (node == null) - { - _nodes.AddLast(new Node(item, priority)); - return; - } - } - } - - /// - /// Remove the first appeared one of the specified values. - /// - /// - /// - public bool Remove(T item) - { - var linkedListNode = _nodes.First; - if (linkedListNode == null) - { - return false; - } - var equalityComparer = EqualityComparer.Default; - while (true) - { - if (equalityComparer.Equals(linkedListNode.Value.Item, item)) - { - _nodes.Remove(linkedListNode); - return true; - } - - linkedListNode = linkedListNode.Next; - if (linkedListNode == null) - { - return false; - } - } - } - - /// - /// Clear all objects. - /// - public void Clear() - { - _nodes.Clear(); - } - - void ICollection.CopyTo(Array array, int index) - { - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - - if (array.Rank != 1) - { - throw new ArgumentException($"{nameof(array)} has invalid rank."); - } - - if (index < 0) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } - - if (array.Length - index < Count) - { - throw new ArgumentException($"{nameof(array)} does not have enough space."); - } - - if (array is T[] array1) - { - CopyTo(array1, index); - return; - } - - var elementType = array.GetType().GetElementType(); - var c = typeof(T); - if (!elementType.IsAssignableFrom(c) && !c.IsAssignableFrom(elementType)) - { - throw new ArgumentException($"Type of the {nameof(array)} element is invalid."); - } - - if (!(array is object[] objArray)) - { - throw new ArgumentException($"Type of the {nameof(array)} is invalid."); - } - - var linkedListNode = _nodes.First; - try - { - if (linkedListNode == null) - { - return; - } - - while (true) - { - objArray[index++] = linkedListNode.Value.Item; - linkedListNode = linkedListNode.Next; - if (linkedListNode == null) - { - return; - } - } - } - catch (ArrayTypeMismatchException) - { - throw new ArgumentException($"Type of the {nameof(array)} is invalid."); - } - } - - private void CopyTo(T[] array, int index) - { - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - - if (index < 0 || index > array.Length) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } - - if (array.Length - index < Count) - { - throw new ArgumentException($"{nameof(array)} does not have enough space."); - } - - var linkedListNode = _nodes.First; - if (linkedListNode == null) - { - return; - } - - while (true) - { - array[index++] = linkedListNode.Value.Item; - linkedListNode = linkedListNode.Next; - if (linkedListNode == null) - { - return; - } - } - } - - bool ICollection.IsSynchronized => false; - - private object _syncRoot; - - object ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - { - Interlocked.CompareExchange(ref _syncRoot, new object(), null); - } - - return _syncRoot; - } - } - - private readonly struct Node - { - public Node(T item, int priority) - { - Item = item; - Priority = priority; - } - - public T Item { get; } - public int Priority { get; } - } - } -} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityList.cs.meta b/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityList.cs.meta deleted file mode 100644 index 451552f..0000000 --- a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityList.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 31a457683834542aba6c283f851040f1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityQueue.cs b/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityQueue.cs deleted file mode 100644 index 082f66a..0000000 --- a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityQueue.cs +++ /dev/null @@ -1,240 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Threading; - -namespace UnityScreenNavigator.Runtime.Foundation.PriorityCollection -{ - /// - /// The queue that will sort the items in order of priority. - /// - /// - public class PriorityQueue : IEnumerable, IEnumerable, ICollection, IReadOnlyCollection - { - private readonly LinkedList _nodes = new LinkedList(); - - public IEnumerator GetEnumerator() - { - foreach (var node in _nodes) - { - yield return node.Item; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public int Count => _nodes.Count; - - /// - /// Add objects based on priority. - /// If the priority is the same, the object added earlier will be placed in front. - /// - /// - /// - public void Enqueue(T item, int priority) - { - var node = _nodes.First; - LinkedListNode beforeNode = null; - if (node == null) - { - _nodes.AddFirst(new Node(item, priority)); - return; - } - while (true) - { - if (node.Value.Priority > priority) - { - if (beforeNode == null) - { - _nodes.AddFirst(new Node(item, priority)); - } - else - { - _nodes.AddAfter(beforeNode, new Node(item, priority)); - } - return; - } - - beforeNode = node; - node = node.Next; - if (node == null) - { - _nodes.AddLast(new Node(item, priority)); - return; - } - } - } - - /// - /// Get an object from the front of the queue. - /// - /// - /// - public T Peek() - { - if (_nodes.Count == 0) - { - throw new InvalidOperationException($"{nameof(Peek)} can not be called when the queue is empty."); - } - - var node = _nodes.First(); - return node.Item; - } - - /// - /// Get and remove an object from the front of the queue. - /// - /// - /// - public T Dequeue() - { - if (_nodes.Count == 0) - { - throw new InvalidOperationException($"{nameof(Dequeue)} can not be called when the queue is empty."); - } - - var node = _nodes.First(); - _nodes.Remove(node); - return node.Item; - } - - /// - /// Clear all objects. - /// - public void Clear() - { - _nodes.Clear(); - } - - void ICollection.CopyTo(Array array, int index) - { - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - - if (array.Rank != 1) - { - throw new ArgumentException($"{nameof(array)} has invalid rank."); - } - - if (index < 0) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } - - if (array.Length - index < Count) - { - throw new ArgumentException($"{nameof(array)} does not have enough space."); - } - - if (array is T[] array1) - { - CopyTo(array1, index); - return; - } - - var elementType = array.GetType().GetElementType(); - var c = typeof(T); - if (!elementType.IsAssignableFrom(c) && !c.IsAssignableFrom(elementType)) - { - throw new ArgumentException($"Type of the {nameof(array)} element is invalid."); - } - - if (!(array is object[] objArray)) - { - throw new ArgumentException($"Type of the {nameof(array)} is invalid."); - } - - var linkedListNode = _nodes.First; - try - { - if (linkedListNode == null) - { - return; - } - - while (true) - { - objArray[index++] = linkedListNode.Value.Item; - linkedListNode = linkedListNode.Next; - if (linkedListNode == null) - { - return; - } - } - } - catch (ArrayTypeMismatchException) - { - throw new ArgumentException($"Type of the {nameof(array)} is invalid."); - } - } - - private void CopyTo(T[] array, int index) - { - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - - if (index < 0 || index > array.Length) - { - throw new ArgumentOutOfRangeException(nameof(index)); - } - - if (array.Length - index < Count) - { - throw new ArgumentException($"{nameof(array)} does not have enough space."); - } - - var linkedListNode = _nodes.First; - if (linkedListNode == null) - { - return; - } - - while (true) - { - array[index++] = linkedListNode.Value.Item; - linkedListNode = linkedListNode.Next; - if (linkedListNode == null) - { - return; - } - } - } - - bool ICollection.IsSynchronized => false; - - private object _syncRoot; - - object ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - { - Interlocked.CompareExchange(ref _syncRoot, new object(), null); - } - - return _syncRoot; - } - } - - private readonly struct Node - { - public Node(T item, int priority) - { - Item = item; - Priority = priority; - } - - public T Item { get; } - public int Priority { get; } - } - } -} \ No newline at end of file diff --git a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityQueue.cs.meta b/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityQueue.cs.meta deleted file mode 100644 index c1a27f6..0000000 --- a/Assets/UnityScreenNavigator/Runtime/Foundation/PriorityCollection/PriorityQueue.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b034f15a4158c4c98a1ed957410a5551 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset index d54f653..697726a 100644 --- a/ProjectSettings/EditorBuildSettings.asset +++ b/ProjectSettings/EditorBuildSettings.asset @@ -5,7 +5,7 @@ EditorBuildSettings: m_ObjectHideFlags: 0 serializedVersion: 2 m_Scenes: - - enabled: 1 + - enabled: 0 path: Assets/Demo/Core/DemoEntryPoint.unity guid: 1d3395278a0303744868c61438f1458b m_configObjects: diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 09bc31e..d143d5a 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -3,7 +3,7 @@ --- !u!129 &1 PlayerSettings: m_ObjectHideFlags: 0 - serializedVersion: 20 + serializedVersion: 24 productGUID: 081d24f9e448a4eab81401cd128addf3 AndroidProfiler: 0 AndroidFilterTouchesWhenObscured: 0 @@ -49,6 +49,8 @@ PlayerSettings: m_StereoRenderingPath: 0 m_ActiveColorSpace: 0 m_MTRendering: 1 + mipStripping: 0 + numberOfMipsStripped: 0 m_StackTraceTypes: 010000000100000001000000010000000100000001000000 iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 @@ -66,6 +68,12 @@ PlayerSettings: androidRenderOutsideSafeArea: 1 androidUseSwappy: 0 androidBlitType: 0 + androidResizableWindow: 0 + androidDefaultWindowWidth: 1920 + androidDefaultWindowHeight: 1080 + androidMinimumWindowWidth: 400 + androidMinimumWindowHeight: 300 + androidFullscreenMode: 1 defaultIsNativeResolution: 1 macRetinaSupport: 1 runInBackground: 1 @@ -117,7 +125,9 @@ PlayerSettings: stadiaTargetFramerate: 0 vulkanNumSwapchainBuffers: 3 vulkanEnableSetSRGBWrite: 0 + vulkanEnablePreTransform: 0 vulkanEnableLateAcquireNextImage: 0 + vulkanEnableCommandBufferRecycling: 1 m_SupportedAspectRatios: 4:3: 1 5:4: 1 @@ -126,52 +136,35 @@ PlayerSettings: Others: 1 bundleVersion: 0.1 preloadedAssets: - - {fileID: 11400000, guid: 514f7ef4ac39c644cb2e1176014eaeb7, type: 2} + - {fileID: 0} + - {fileID: 11400000, guid: 7d01b4f1814d44e26aa7bb4af99cf1e1, type: 2} metroInputSource: 0 wsaTransparentSwapchain: 0 m_HolographicPauseOnTrackingLoss: 1 xboxOneDisableKinectGpuReservation: 1 xboxOneEnable7thCore: 1 vrSettings: - cardboard: - depthFormat: 0 - enableTransitionView: 0 - daydream: - depthFormat: 0 - useSustainedPerformanceMode: 0 - enableVideoLayer: 0 - useProtectedVideoMemory: 0 - minimumSupportedHeadTracking: 0 - maximumSupportedHeadTracking: 1 - hololens: - depthFormat: 1 - depthBufferSharingEnabled: 1 - lumin: - depthFormat: 0 - frameTiming: 2 - enableGLCache: 0 - glCacheMaxBlobSize: 524288 - glCacheMaxFileSize: 8388608 - oculus: - sharedDepthBuffer: 1 - dashSupport: 1 - lowOverheadMode: 0 - protectedContext: 0 - v2Signing: 1 enable360StereoCapture: 0 isWsaHolographicRemotingEnabled: 0 enableFrameTimingStats: 0 + enableOpenGLProfilerGPURecorders: 1 useHDRDisplay: 0 D3DHDRBitDepth: 0 m_ColorGamuts: 00000000 targetPixelDensity: 30 resolutionScalingMode: 0 + resetResolutionOnWindowResize: 0 androidSupportedAspectRatio: 1 androidMaxAspectRatio: 2.1 - applicationIdentifier: {} - buildNumber: {} + applicationIdentifier: + Standalone: com.DefaultCompany.UnityScreenNavigator + buildNumber: + Standalone: 0 + iPhone: 0 + tvOS: 0 + overrideDefaultApplicationIdentifier: 0 AndroidBundleVersionCode: 1 - AndroidMinSdkVersion: 19 + AndroidMinSdkVersion: 22 AndroidTargetSdkVersion: 0 AndroidPreferredInstallLocation: 1 aotOptions: @@ -186,10 +179,10 @@ PlayerSettings: StripUnusedMeshComponents: 1 VertexChannelCompressionMask: 4054 iPhoneSdkVersion: 988 - iOSTargetOSVersionString: 10.0 + iOSTargetOSVersionString: 12.0 tvOSSdkVersion: 0 tvOSRequireExtendedGameController: 0 - tvOSTargetOSVersionString: 10.0 + tvOSTargetOSVersionString: 12.0 uIPrerenderedIcon: 0 uIRequiresPersistentWiFi: 0 uIRequiresFullScreen: 1 @@ -223,10 +216,11 @@ PlayerSettings: iOSLaunchScreeniPadFillPct: 100 iOSLaunchScreeniPadSize: 100 iOSLaunchScreeniPadCustomXibPath: - iOSUseLaunchScreenStoryboard: 0 iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: iOSDeviceRequirements: [] iOSURLSchemes: [] + macOSURLSchemes: [] iOSBackgroundModes: 0 iOSMetalForceHardShadows: 0 metalEditorSupport: 1 @@ -242,10 +236,19 @@ PlayerSettings: iOSRequireARKit: 0 iOSAutomaticallyDetectAndAddCapabilities: 1 appleEnableProMotion: 0 + shaderPrecisionModel: 0 clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea templatePackageId: com.unity.template.3d@4.2.8 templateDefaultScene: Assets/Scenes/SampleScene.unity + useCustomMainManifest: 0 + useCustomLauncherManifest: 0 + useCustomMainGradleTemplate: 0 + useCustomLauncherGradleManifest: 0 + useCustomBaseGradleTemplate: 0 + useCustomGradlePropertiesTemplate: 0 + useCustomProguardFile: 0 AndroidTargetArchitectures: 1 + AndroidTargetDevices: 0 AndroidSplashScreenScale: 0 androidSplashScreen: {fileID: 0} AndroidKeystoreName: @@ -262,6 +265,10 @@ PlayerSettings: height: 180 banner: {fileID: 0} androidGamepadSupportLevel: 0 + chromeosInputEmulation: 1 + AndroidMinifyWithR8: 0 + AndroidMinifyRelease: 0 + AndroidMinifyDebug: 0 AndroidValidateAppBundleSize: 1 AndroidAppBundleSizeToValidate: 150 m_BuildTargetIcons: [] @@ -374,6 +381,7 @@ PlayerSettings: - m_BuildTarget: WebGL m_StaticBatching: 0 m_DynamicBatching: 0 + m_BuildTargetShaderSettings: [] m_BuildTargetGraphicsJobs: - m_BuildTarget: MacStandaloneSupport m_GraphicsJobs: 0 @@ -409,13 +417,13 @@ PlayerSettings: m_BuildTargetGraphicsAPIs: - m_BuildTarget: AndroidPlayer m_APIs: 150000000b000000 - m_Automatic: 0 + m_Automatic: 1 - m_BuildTarget: iOSSupport m_APIs: 10000000 m_Automatic: 1 - m_BuildTarget: AppleTVSupport m_APIs: 10000000 - m_Automatic: 0 + m_Automatic: 1 - m_BuildTarget: WebGLSupport m_APIs: 0b000000 m_Automatic: 1 @@ -425,6 +433,8 @@ PlayerSettings: m_Devices: - Oculus - OpenVR + m_DefaultShaderChunkSizeInMB: 16 + m_DefaultShaderChunkCount: 0 openGLRequireES31: 0 openGLRequireES31AEP: 0 openGLRequireES32: 0 @@ -435,6 +445,8 @@ PlayerSettings: tvOS: 1 m_BuildTargetGroupLightmapEncodingQuality: [] m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetNormalMapEncoding: [] + m_BuildTargetDefaultTextureCompressionFormat: [] playModeTestRunnerEnabled: 0 runPlayModeTestAsEditModeTest: 0 actionOnDotNetUnhandledException: 1 @@ -444,12 +456,16 @@ PlayerSettings: cameraUsageDescription: locationUsageDescription: microphoneUsageDescription: + bluetoothUsageDescription: + switchNMETAOverride: switchNetLibKey: switchSocketMemoryPoolSize: 6144 switchSocketAllocatorPoolSize: 128 switchSocketConcurrencyLimit: 14 switchScreenResolutionBehavior: 2 switchUseCPUProfiler: 0 + switchUseGOLDLinker: 0 + switchLTOSetting: 0 switchApplicationID: 0x01004b9000490000 switchNSODependencies: switchTitleNames_0: @@ -525,7 +541,6 @@ PlayerSettings: switchReleaseVersion: 0 switchDisplayVersion: 1.0.0 switchStartupUserAccount: 0 - switchTouchScreenUsage: 0 switchSupportedLanguagesMask: 0 switchLogoType: 0 switchApplicationErrorCodeCategory: @@ -567,6 +582,7 @@ PlayerSettings: switchNativeFsCacheSize: 32 switchIsHoldTypeHorizontal: 0 switchSupportedNpadCount: 8 + switchEnableTouchScreen: 1 switchSocketConfigEnabled: 0 switchTcpInitialSendBufferSize: 32 switchTcpInitialReceiveBufferSize: 64 @@ -578,8 +594,12 @@ PlayerSettings: switchSocketInitializeEnabled: 1 switchNetworkInterfaceManagerInitializeEnabled: 1 switchPlayerConnectionEnabled: 1 + switchUseNewStyleFilepaths: 0 + switchUseLegacyFmodPriorities: 1 switchUseMicroSleepForYield: 1 + switchEnableRamDiskSupport: 0 switchMicroSleepForYieldTime: 25 + switchRamDiskSpaceSize: 12 ps4NPAgeRating: 12 ps4NPTitleSecret: ps4NPTrophyPackPath: @@ -655,31 +675,6 @@ PlayerSettings: ps4attribEyeToEyeDistanceSettingVR: 0 ps4IncludedModules: [] ps4attribVROutputEnabled: 0 - ps5ParamFilePath: - ps5VideoOutPixelFormat: 0 - ps5VideoOutInitialWidth: 1920 - ps5VideoOutOutputMode: 1 - ps5BackgroundImagePath: - ps5StartupImagePath: - ps5Pic2Path: - ps5StartupImagesFolder: - ps5IconImagesFolder: - ps5SaveDataImagePath: - ps5SdkOverride: - ps5BGMPath: - ps5ShareOverlayImagePath: - ps5NPConfigZipPath: - ps5Passcode: dVI5ZuGXbEWRK5RhRXdCdG5nG5azdNMK - ps5UseResolutionFallback: 0 - ps5UseAudio3dBackend: 0 - ps5ScriptOptimizationLevel: 2 - ps5Audio3dVirtualSpeakerCount: 14 - ps5UpdateReferencePackage: - ps5disableAutoHideSplash: 0 - ps5OperatingSystemCanDisableSplashScreen: 0 - ps5IncludedModules: [] - ps5SharedBinaryContentLabels: [] - ps5SharedBinarySystemFolders: [] monoEnv: splashScreenBackgroundSourceLandscape: {fileID: 0} splashScreenBackgroundSourcePortrait: {fileID: 0} @@ -696,20 +691,39 @@ PlayerSettings: webGLAnalyzeBuildSize: 0 webGLUseEmbeddedResources: 0 webGLCompressionFormat: 1 + webGLWasmArithmeticExceptions: 0 webGLLinkerTarget: 1 webGLThreadsSupport: 0 - webGLWasmStreaming: 0 + webGLDecompressionFallback: 0 + webGLPowerPreference: 2 scriptingDefineSymbols: - 1: USN_USE_ASYNC_METHODS - 4: USN_USE_ASYNC_METHODS - 7: USN_USE_ASYNC_METHODS + Android: USN_USE_ASYNC_METHODS + Standalone: USN_USE_ASYNC_METHODS + iPhone: USN_USE_ASYNC_METHODS + additionalCompilerArguments: {} platformArchitecture: {} scriptingBackend: {} il2cppCompilerConfiguration: {} - managedStrippingLevel: {} + managedStrippingLevel: + EmbeddedLinux: 1 + GameCoreScarlett: 1 + GameCoreXboxOne: 1 + Lumin: 1 + Nintendo Switch: 1 + PS4: 1 + PS5: 1 + Stadia: 1 + WebGL: 1 + Windows Store Apps: 1 + XboxOne: 1 + iPhone: 1 + tvOS: 1 incrementalIl2cppBuild: {} suppressCommonWarnings: 1 allowUnsafeCode: 0 + useDeterministicCompilation: 1 + enableRoslynAnalyzers: 1 + selectedPlatform: 0 additionalIl2CppArgs: scriptingRuntimeVersion: 1 gcIncremental: 0 @@ -745,6 +759,7 @@ PlayerSettings: metroFTAName: metroFTAFileTypes: [] metroProtocolName: + vcxProjDefaultLanguage: XboxOneProductId: XboxOneUpdateKey: XboxOneSandboxId: @@ -772,10 +787,7 @@ PlayerSettings: XboxOneXTitleMemory: 8 XboxOneOverrideIdentityName: XboxOneOverrideIdentityPublisher: - vrEditorSettings: - daydream: - daydreamIconForeground: {fileID: 0} - daydreamIconBackground: {fileID: 0} + vrEditorSettings: {} cloudServicesEnabled: UNet: 1 luminIcon: @@ -790,11 +802,15 @@ PlayerSettings: m_VersionCode: 1 m_VersionName: apiCompatibilityLevel: 6 + activeInputHandler: 0 + windowsGamepadBackendHint: 0 cloudProjectId: framebufferDepthMemorylessMode: 0 + qualitySettingsNames: [] projectName: organizationId: cloudEnabled: 0 - enableNativePlatformBackendsForNewInputSystem: 0 - disableOldInputManagerSupport: 0 legacyClampBlendShapeWeights: 0 + playerDataPath: + forceSRGBBlit: 1 + virtualTexturingSupportEnabled: 0 diff --git a/ProjectSettings/SceneTemplateSettings.json b/ProjectSettings/SceneTemplateSettings.json new file mode 100644 index 0000000..6f3e60f --- /dev/null +++ b/ProjectSettings/SceneTemplateSettings.json @@ -0,0 +1,167 @@ +{ + "templatePinStates": [], + "dependencyTypeInfos": [ + { + "userAdded": false, + "type": "UnityEngine.AnimationClip", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.Animations.AnimatorController", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.AnimatorOverrideController", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.Audio.AudioMixerController", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.ComputeShader", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Cubemap", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.GameObject", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.LightingDataAsset", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": false + }, + { + "userAdded": false, + "type": "UnityEngine.LightingSettings", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Material", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.MonoScript", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.PhysicMaterial", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.PhysicsMaterial2D", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.PostProcessing.PostProcessResources", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.VolumeProfile", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.SceneAsset", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": false + }, + { + "userAdded": false, + "type": "UnityEngine.Shader", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.ShaderVariantCollection", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Texture", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Texture2D", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Timeline.TimelineAsset", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + } + ], + "defaultDependencyTypeInfo": { + "userAdded": false, + "type": "", + "ignore": false, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + "newSceneOverride": 0 +} \ No newline at end of file