diff --git a/Runtime/Assets/Compatibility.meta b/Runtime/Assets/Compatibility.meta new file mode 100644 index 0000000..86a2df0 --- /dev/null +++ b/Runtime/Assets/Compatibility.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ac9f062bab344482b6a9002a9cc1a45f +timeCreated: 1708223474 \ No newline at end of file diff --git a/Runtime/Assets/Compatibility/CompatibleSceneLoader.cs b/Runtime/Assets/Compatibility/CompatibleSceneLoader.cs new file mode 100644 index 0000000..cfe9500 --- /dev/null +++ b/Runtime/Assets/Compatibility/CompatibleSceneLoader.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Mew.Core.TaskHelpers; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace Mew.Core.Assets +{ + internal static class CompatibleSceneLoader + { + internal static async ValueTask LoadSceneAsync(UnifiedScene unifiedScene, LoadSceneParameters parameters) + { +#if UNITY_2023_2_OR_NEWER + await SceneManager.LoadSceneAsync(unifiedScene.SceneReference, parameters); +#else + var asyncOp = SceneManager.LoadSceneAsync(unifiedScene.SceneReference, parameters); + while (!asyncOp.isDone) await TaskHelper.NextFrame(); +#endif + var loadedScene = SceneManager.GetSceneAt(SceneManager.loadedSceneCount - 1); + return new SceneHandle(loadedScene); + } + + internal static async ValueTask UnloadSceneAsync(SceneHandle sceneHandle) + { +#if UNITY_2023_2_OR_NEWER + await SceneManager.UnloadSceneAsync(sceneHandle.Scene); +#else + var asyncOp = SceneManager.UnloadSceneAsync(sceneHandle.Scene); + while (!asyncOp.isDone) await TaskHelper.NextFrame(); +#endif + } + } +} \ No newline at end of file diff --git a/Runtime/Assets/Compatibility/CompatibleSceneLoader.cs.meta b/Runtime/Assets/Compatibility/CompatibleSceneLoader.cs.meta new file mode 100644 index 0000000..3eaeab3 --- /dev/null +++ b/Runtime/Assets/Compatibility/CompatibleSceneLoader.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5c8143c657a14c1d9fc13234b987d58f +timeCreated: 1708223530 \ No newline at end of file diff --git a/Runtime/Assets/Scene/UnifiedSceneLoader.cs b/Runtime/Assets/Scene/UnifiedSceneLoader.cs index 34327de..c318053 100644 --- a/Runtime/Assets/Scene/UnifiedSceneLoader.cs +++ b/Runtime/Assets/Scene/UnifiedSceneLoader.cs @@ -2,7 +2,6 @@ using System.Threading; using System.Threading.Tasks; using Mew.Core.TaskHelpers; -using UnityEngine; using UnityEngine.SceneManagement; #if USE_MEW_CORE_ASSETS @@ -42,15 +41,7 @@ public static async Task LoadAsync(UnifiedScene unifiedScene, Canc #endif if (unifiedScene.SceneReference is not null && unifiedScene.SceneReference.IsValid) { -#if UNITY_2023_2_OR_NEWER - await SceneManager.LoadSceneAsync(unifiedScene.SceneReference, parameters); -#else - var asyncOp = SceneManager.LoadSceneAsync(unifiedScene.SceneReference, parameters); - while (!asyncOp.isDone) - await TaskHelper.NextFrame(); -#endif - var loadedScene = SceneManager.GetSceneAt(SceneManager.loadedSceneCount - 1); - handle = new SceneHandle(loadedScene); + handle = await CompatibleSceneLoader.LoadSceneAsync(unifiedScene, parameters); } #if UNITY_EDITOR // for test use @@ -92,16 +83,7 @@ public static async ValueTask UnloadAsync(ISceneHandle targetHandle) case SceneHandle sceneHandle: { if (sceneHandle.Scene.isLoaded) - { -#if UNITY_2023_2_OR_NEWER - await SceneManager.UnloadSceneAsync(sceneHandle.Scene); -#else - var asyncOp = SceneManager.UnloadSceneAsync(sceneHandle.Scene); - while (!asyncOp.isDone) - await TaskHelper.NextFrame(); -#endif - - } + await CompatibleSceneLoader.UnloadSceneAsync(sceneHandle); break; } } diff --git a/Runtime/Helpers/Compatibility.meta b/Runtime/Helpers/Compatibility.meta new file mode 100644 index 0000000..e3f7205 --- /dev/null +++ b/Runtime/Helpers/Compatibility.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 55bbd8c7742544b6adea08fdd0546780 +timeCreated: 1708224055 \ No newline at end of file diff --git a/Runtime/Helpers/Compatibility/TaskHelperInternal.cs b/Runtime/Helpers/Compatibility/TaskHelperInternal.cs new file mode 100644 index 0000000..b9d07b9 --- /dev/null +++ b/Runtime/Helpers/Compatibility/TaskHelperInternal.cs @@ -0,0 +1,45 @@ +#if UNITY_2023_2_OR_NEWER +using System.Collections.Generic; +using System.Threading.Tasks; +using UnityEngine; + +namespace Mew.Core.TaskHelpers +{ + internal static class TaskHelperInternal + { + private static readonly Stack Pool = new(); + private static readonly Queue Queued = new(); + private static readonly List Running = new(); + private static bool registered; + + public static async Task NextFrame() + { + if (!registered) + { + MewLoop.Add(OnUpdate); + registered = true; + } + if (Pool.Count == 0) + Pool.Push(new AwaitableCompletionSource()); + var awaitableCompletionSource = Pool.Pop(); + awaitableCompletionSource.Reset(); + Queued.Enqueue(awaitableCompletionSource); + await awaitableCompletionSource.Awaitable; + return; + + void OnUpdate() + { + while (Queued.Count > 0) + Running.Add(Queued.Dequeue()); + + foreach (var completionSource in Running) + { + completionSource.TrySetResult(); + Pool.Push(completionSource); + } + Running.Clear(); + } + } + } +} +#endif diff --git a/Runtime/Helpers/Compatibility/TaskHelperInternal.cs.meta b/Runtime/Helpers/Compatibility/TaskHelperInternal.cs.meta new file mode 100644 index 0000000..eee8ea5 --- /dev/null +++ b/Runtime/Helpers/Compatibility/TaskHelperInternal.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8c369699668040ae99eabb16a8ca11ab +timeCreated: 1708223955 \ No newline at end of file diff --git a/Runtime/Helpers/Compatibility/TaskHelperLegacyUnity.cs b/Runtime/Helpers/Compatibility/TaskHelperLegacyUnity.cs new file mode 100644 index 0000000..0c5859e --- /dev/null +++ b/Runtime/Helpers/Compatibility/TaskHelperLegacyUnity.cs @@ -0,0 +1,20 @@ +#if !UNITY_2023_2_OR_NEWER +using System.Threading.Tasks; + +namespace Mew.Core.TaskHelpers +{ + internal static class TaskHelperLegacyInternal + { + public static async Task NextFrame() + { + TaskCompletionSource taskCompletionSource = new(); + MewLoop.Add(OnUpdate); + await taskCompletionSource.Task; + MewLoop.Remove(OnUpdate); + return; + + void OnUpdate() => taskCompletionSource.TrySetResult(true); + } + } +} +#endif \ No newline at end of file diff --git a/Runtime/Helpers/Compatibility/TaskHelperLegacyUnity.cs.meta b/Runtime/Helpers/Compatibility/TaskHelperLegacyUnity.cs.meta new file mode 100644 index 0000000..0de0e60 --- /dev/null +++ b/Runtime/Helpers/Compatibility/TaskHelperLegacyUnity.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c475ab55817442b7a082fd712bdc46ee +timeCreated: 1708224045 \ No newline at end of file diff --git a/Runtime/Helpers/SceneManagerHelper.cs b/Runtime/Helpers/SceneManagerHelper.cs index 19b6992..c9e5fc2 100644 --- a/Runtime/Helpers/SceneManagerHelper.cs +++ b/Runtime/Helpers/SceneManagerHelper.cs @@ -1,4 +1,7 @@ using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using UnityEngine; using UnityEngine.SceneManagement; namespace Mew.Core.SceneHelpers diff --git a/Runtime/Helpers/TaskHelper.cs b/Runtime/Helpers/TaskHelper.cs index 88e0de7..20a8e1e 100644 --- a/Runtime/Helpers/TaskHelper.cs +++ b/Runtime/Helpers/TaskHelper.cs @@ -1,54 +1,15 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using UnityEngine; +using System.Threading.Tasks; namespace Mew.Core.TaskHelpers { public static class TaskHelper { -#if UNITY_2023_2_OR_NEWER - private static readonly Stack pool = new(); - private static readonly Queue queued = new(); - private static readonly List running = new(); - private static bool registered; -#endif - public static async Task NextFrame() { #if UNITY_2023_2_OR_NEWER - if (!registered) - { - MewLoop.Add(OnUpdate); - registered = true; - } - if (pool.Count == 0) - pool.Push(new AwaitableCompletionSource()); - var awaitableCompletionSource = pool.Pop(); - awaitableCompletionSource.Reset(); - queued.Enqueue(awaitableCompletionSource); - await awaitableCompletionSource.Awaitable; - return; - - void OnUpdate() - { - while (queued.Count > 0) - running.Add(queued.Dequeue()); - - foreach (var completionSource in running) - { - completionSource.TrySetResult(); - pool.Push(completionSource); - } - running.Clear(); - } + await TaskHelperInternal.NextFrame(); #else - TaskCompletionSource taskCompletionSource = new(); - MewLoop.Add(OnUpdate); - await taskCompletionSource.Task; - MewLoop.Remove(OnUpdate); - return; - - void OnUpdate() => taskCompletionSource.TrySetResult(true); + await TaskHelperLegacyInternal.NextFrame(); #endif } }