From d5199811389ddf377a53ed9d54bb7366a0d39fc9 Mon Sep 17 00:00:00 2001 From: ifBars Date: Thu, 24 Sep 2026 00:02:35 -0700 Subject: [PATCH 1/2] fix(Lifecycle): detach native listeners on scene unload --- S1API/Lifecycle/GameLifecycle.cs | 57 +++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/S1API/Lifecycle/GameLifecycle.cs b/S1API/Lifecycle/GameLifecycle.cs index 817d0bbb..a91e45ad 100644 --- a/S1API/Lifecycle/GameLifecycle.cs +++ b/S1API/Lifecycle/GameLifecycle.cs @@ -30,6 +30,14 @@ namespace S1API.Lifecycle public static class GameLifecycle { private static bool _initialized; + private static S1Persistence.LoadManager? _loadManager; + private static S1Persistence.SaveManager? _saveManager; + private static UnityAction? _preLoadListener; + private static UnityAction? _loadCompleteListener; + private static UnityAction? _preSceneChangeListener; + private static UnityAction? _saveInfoLoadedListener; + private static UnityAction? _saveStartListener; + private static UnityAction? _saveCompleteListener; /// /// Fired before the game begins loading saved data. @@ -151,21 +159,30 @@ internal static void Initialize() return; #if IL2CPPMELON - loadManager.onPreLoad.AddListener((UnityAction)InvokeOnPreLoad); - loadManager.onLoadComplete.AddListener((UnityAction)InvokeOnLoadComplete); - loadManager.onPreSceneChange.AddListener((UnityAction)InvokeOnPreSceneChange); - loadManager.onSaveInfoLoaded.AddListener((UnityAction)InvokeOnSaveInfoLoaded); - saveManager.onSaveStart.AddListener((UnityAction)InvokeOnSaveStart); - saveManager.onSaveComplete.AddListener((UnityAction)InvokeOnSaveComplete); + _preLoadListener ??= (UnityAction)InvokeOnPreLoad; + _loadCompleteListener ??= (UnityAction)InvokeOnLoadComplete; + _preSceneChangeListener ??= (UnityAction)InvokeOnPreSceneChange; + _saveInfoLoadedListener ??= (UnityAction)InvokeOnSaveInfoLoaded; + _saveStartListener ??= (UnityAction)InvokeOnSaveStart; + _saveCompleteListener ??= (UnityAction)InvokeOnSaveComplete; #elif MONOMELON - loadManager.onPreLoad.AddListener(new UnityAction(InvokeOnPreLoad)); - loadManager.onLoadComplete.AddListener(new UnityAction(InvokeOnLoadComplete)); - loadManager.onPreSceneChange.AddListener(new UnityAction(InvokeOnPreSceneChange)); - loadManager.onSaveInfoLoaded.AddListener(new UnityAction(InvokeOnSaveInfoLoaded)); - saveManager.onSaveStart.AddListener(new UnityAction(InvokeOnSaveStart)); - saveManager.onSaveComplete.AddListener(new UnityAction(InvokeOnSaveComplete)); + _preLoadListener ??= new UnityAction(InvokeOnPreLoad); + _loadCompleteListener ??= new UnityAction(InvokeOnLoadComplete); + _preSceneChangeListener ??= new UnityAction(InvokeOnPreSceneChange); + _saveInfoLoadedListener ??= new UnityAction(InvokeOnSaveInfoLoaded); + _saveStartListener ??= new UnityAction(InvokeOnSaveStart); + _saveCompleteListener ??= new UnityAction(InvokeOnSaveComplete); #endif + loadManager.onPreLoad.AddListener(_preLoadListener); + loadManager.onLoadComplete.AddListener(_loadCompleteListener); + loadManager.onPreSceneChange.AddListener(_preSceneChangeListener); + loadManager.onSaveInfoLoaded.AddListener(_saveInfoLoadedListener); + saveManager.onSaveStart.AddListener(_saveStartListener); + saveManager.onSaveComplete.AddListener(_saveCompleteListener); + + _loadManager = loadManager; + _saveManager = saveManager; _initialized = true; } @@ -175,6 +192,22 @@ internal static void Initialize() /// internal static void Reset() { + if (_loadManager != null) + { + _loadManager.onPreLoad.RemoveListener(_preLoadListener); + _loadManager.onLoadComplete.RemoveListener(_loadCompleteListener); + _loadManager.onPreSceneChange.RemoveListener(_preSceneChangeListener); + _loadManager.onSaveInfoLoaded.RemoveListener(_saveInfoLoadedListener); + } + + if (_saveManager != null) + { + _saveManager.onSaveStart.RemoveListener(_saveStartListener); + _saveManager.onSaveComplete.RemoveListener(_saveCompleteListener); + } + + _loadManager = null; + _saveManager = null; _initialized = false; } From f1be38684d6c0814e1fe6b7560da582ea9d91f6e Mon Sep 17 00:00:00 2001 From: ifBars Date: Thu, 24 Sep 2026 21:49:31 -0700 Subject: [PATCH 2/2] fix(Lifecycle): retain pre-scene listener through menu reload --- S1API/Lifecycle/GameLifecycle.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/S1API/Lifecycle/GameLifecycle.cs b/S1API/Lifecycle/GameLifecycle.cs index a91e45ad..49d6f1a1 100644 --- a/S1API/Lifecycle/GameLifecycle.cs +++ b/S1API/Lifecycle/GameLifecycle.cs @@ -31,6 +31,7 @@ public static class GameLifecycle { private static bool _initialized; private static S1Persistence.LoadManager? _loadManager; + private static S1Persistence.LoadManager? _preSceneChangeManager; private static S1Persistence.SaveManager? _saveManager; private static UnityAction? _preLoadListener; private static UnityAction? _loadCompleteListener; @@ -176,7 +177,14 @@ internal static void Initialize() loadManager.onPreLoad.AddListener(_preLoadListener); loadManager.onLoadComplete.AddListener(_loadCompleteListener); - loadManager.onPreSceneChange.AddListener(_preSceneChangeListener); + if (_preSceneChangeManager != loadManager) + { + if (_preSceneChangeManager != null) + _preSceneChangeManager.onPreSceneChange.RemoveListener(_preSceneChangeListener); + + loadManager.onPreSceneChange.AddListener(_preSceneChangeListener); + _preSceneChangeManager = loadManager; + } loadManager.onSaveInfoLoaded.AddListener(_saveInfoLoadedListener); saveManager.onSaveStart.AddListener(_saveStartListener); saveManager.onSaveComplete.AddListener(_saveCompleteListener); @@ -196,7 +204,6 @@ internal static void Reset() { _loadManager.onPreLoad.RemoveListener(_preLoadListener); _loadManager.onLoadComplete.RemoveListener(_loadCompleteListener); - _loadManager.onPreSceneChange.RemoveListener(_preSceneChangeListener); _loadManager.onSaveInfoLoaded.RemoveListener(_saveInfoLoadedListener); }