From f05e2be30a86f2b3358e06ccecfd45faf5a6a4e0 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 18 Jul 2023 00:49:47 -0400 Subject: [PATCH] Clear all coroutines/delays on scene unload --- .../Components/Volumes/LoadCreditsVolume.cs | 3 +- NewHorizons/Handlers/FadeHandler.cs | 5 ++- NewHorizons/Handlers/PlayerSpawnHandler.cs | 2 +- NewHorizons/Utility/OWML/Delay.cs | 43 +++++++++++++++++-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/NewHorizons/Components/Volumes/LoadCreditsVolume.cs b/NewHorizons/Components/Volumes/LoadCreditsVolume.cs index 3fc191f2..18edcbd1 100644 --- a/NewHorizons/Components/Volumes/LoadCreditsVolume.cs +++ b/NewHorizons/Components/Volumes/LoadCreditsVolume.cs @@ -1,5 +1,6 @@ using NewHorizons.External.SerializableEnums; using NewHorizons.Handlers; +using NewHorizons.Utility; using NewHorizons.Utility.OWML; using System.Collections; using UnityEngine; @@ -28,7 +29,7 @@ namespace NewHorizons.Components.Volumes if (hitObj.CompareTag("PlayerDetector") && enabled) { // Have to run it off the mod behaviour since the game over controller disables everything - Main.Instance.StartCoroutine(GameOver()); + Delay.StartCoroutine(GameOver()); } } diff --git a/NewHorizons/Handlers/FadeHandler.cs b/NewHorizons/Handlers/FadeHandler.cs index 9316030a..fbaa0b5b 100644 --- a/NewHorizons/Handlers/FadeHandler.cs +++ b/NewHorizons/Handlers/FadeHandler.cs @@ -1,3 +1,4 @@ +using NewHorizons.Utility.OWML; using System; using System.Collections; using UnityEngine; @@ -6,7 +7,7 @@ namespace NewHorizons.Handlers { public static class FadeHandler { - public static void FadeOut(float length) => Main.Instance.StartCoroutine(FadeOutCoroutine(length)); + public static void FadeOut(float length) => Delay.StartCoroutine(FadeOutCoroutine(length)); private static IEnumerator FadeOutCoroutine(float length) { @@ -24,7 +25,7 @@ namespace NewHorizons.Handlers yield return new WaitForEndOfFrame(); } - public static void FadeThen(float length, Action action) => Main.Instance.StartCoroutine(FadeThenCoroutine(length, action)); + public static void FadeThen(float length, Action action) => Delay.StartCoroutine(FadeThenCoroutine(length, action)); private static IEnumerator FadeThenCoroutine(float length, Action action) { diff --git a/NewHorizons/Handlers/PlayerSpawnHandler.cs b/NewHorizons/Handlers/PlayerSpawnHandler.cs index 8d70907b..499a4d7f 100644 --- a/NewHorizons/Handlers/PlayerSpawnHandler.cs +++ b/NewHorizons/Handlers/PlayerSpawnHandler.cs @@ -40,7 +40,7 @@ namespace NewHorizons.Handlers var matchInitialMotion = SearchUtilities.Find("Player_Body").GetComponent(); if (matchInitialMotion != null) UnityEngine.Object.Destroy(matchInitialMotion); - Main.Instance.StartCoroutine(SpawnCoroutine(2)); + Delay.StartCoroutine(SpawnCoroutine(2)); } } diff --git a/NewHorizons/Utility/OWML/Delay.cs b/NewHorizons/Utility/OWML/Delay.cs index 979712b7..e25dc928 100644 --- a/NewHorizons/Utility/OWML/Delay.cs +++ b/NewHorizons/Utility/OWML/Delay.cs @@ -1,15 +1,49 @@ using System; using System.Collections; using UnityEngine; +using UnityEngine.SceneManagement; namespace NewHorizons.Utility.OWML { public static class Delay { - public static void RunWhen(Func predicate, Action action) => Main.Instance.ModHelper.Events.Unity.RunWhen(predicate, action); - public static void FireInNUpdates(Action action, int n) => Main.Instance.ModHelper.Events.Unity.FireInNUpdates(action, n); - public static void FireOnNextUpdate(Action action) => Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(action); - public static void RunWhenAndInNUpdates(Action action, Func predicate, int n) => Main.Instance.StartCoroutine(RunWhenOrInNUpdatesCoroutine(action, predicate, n)); + #region OnSceneUnloaded + static Delay() => SceneManager.sceneUnloaded += OnSceneUnloaded; + + private static void OnSceneUnloaded(Scene _) => Main.Instance.StopAllCoroutines(); + #endregion + + #region public methods + public static void StartCoroutine(IEnumerator coroutine) => Main.Instance.StartCoroutine(coroutine); + + public static void RunWhen(Func predicate, Action action) => StartCoroutine(RunWhenCoroutine(action, predicate)); + + public static void FireInNUpdates(Action action, int n) => StartCoroutine(FireInNUpdatesCoroutine(action, n)); + + public static void FireOnNextUpdate(Action action) => FireInNUpdates(action, 1); + + public static void RunWhenAndInNUpdates(Action action, Func predicate, int n) => Delay.StartCoroutine(RunWhenOrInNUpdatesCoroutine(action, predicate, n)); + #endregion + + #region Coroutines + private static IEnumerator RunWhenCoroutine(Action action, Func predicate) + { + while (!predicate.Invoke()) + { + yield return new WaitForEndOfFrame(); + } + + action.Invoke(); + } + + private static IEnumerator FireInNUpdatesCoroutine(Action action, int n) + { + for (int i = 0; i < n; i++) + { + yield return new WaitForEndOfFrame(); + } + action?.Invoke(); + } private static IEnumerator RunWhenOrInNUpdatesCoroutine(Action action, Func predicate, int n) { @@ -24,5 +58,6 @@ namespace NewHorizons.Utility.OWML action.Invoke(); } + #endregion } }