diff --git a/MiraAPI/Hud/CustomPlayerMenu.cs b/MiraAPI/Hud/CustomPlayerMenu.cs index cf16706..fb27f14 100644 --- a/MiraAPI/Hud/CustomPlayerMenu.cs +++ b/MiraAPI/Hud/CustomPlayerMenu.cs @@ -96,7 +96,7 @@ public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr) onClick(null); })); - DestroyableSingleton.Instance.Analytics.MinigameOpened(PlayerControl.LocalPlayer.Data, TaskType); + DebugAnalytics.Instance.Analytics.MinigameOpened(PlayerControl.LocalPlayer.Data, TaskType); var list = PlayerControl.AllPlayerControls.ToArray().Where(playerMatch).ToList(); potentialVictims = []; var list2 = new Il2CppSystem.Collections.Generic.List(); diff --git a/MiraAPI/Modifiers/ModifierDisplay/ModifierDisplayComponent.cs b/MiraAPI/Modifiers/ModifierDisplay/ModifierDisplayComponent.cs index fb24d6f..4a6411f 100644 --- a/MiraAPI/Modifiers/ModifierDisplay/ModifierDisplayComponent.cs +++ b/MiraAPI/Modifiers/ModifierDisplay/ModifierDisplayComponent.cs @@ -4,6 +4,7 @@ using System.Linq; using HarmonyLib; using Il2CppInterop.Runtime.Attributes; using MiraAPI.LocalSettings; +using MiraAPI.Utilities; using MiraAPI.Utilities.Assets; using Reactor.Utilities.Attributes; using Reactor.Utilities.Extensions; @@ -137,7 +138,7 @@ public class ModifierDisplayComponent(nint cppPtr) : MonoBehaviour(cppPtr) internal void DestroyComponent(ModifierUiComponent component) { _modifiers.Remove(component.Modifier!); - component.gameObject.DestroyImmediate(); + component.gameObject.DeepDestroy(); RefreshModifiers(); } @@ -207,7 +208,7 @@ public class ModifierDisplayComponent(nint cppPtr) : MonoBehaviour(cppPtr) continue; } - mod.Value.gameObject.Destroy(); + mod.Value.gameObject.DeepDestroy(); _modifiers.Remove(mod.Key); } diff --git a/MiraAPI/Patches/DetectiveNotesMinigamePatch.cs b/MiraAPI/Patches/DetectiveNotesMinigamePatch.cs index b0e37e7..a11ec7e 100644 --- a/MiraAPI/Patches/DetectiveNotesMinigamePatch.cs +++ b/MiraAPI/Patches/DetectiveNotesMinigamePatch.cs @@ -26,7 +26,7 @@ public static class DetectiveNotesMinigamePatch return; } __instance.impostorButton = new List(); - var allRoles = DestroyableSingleton.Instance.AllRoles; + var allRoles = RoleManager.Instance.AllRoles; var customRoles = CustomRoleManager.CustomRoleBehaviours; foreach (var role in allRoles) { diff --git a/MiraAPI/Patches/Freeplay/TaskAdderPatches.cs b/MiraAPI/Patches/Freeplay/TaskAdderPatches.cs index 5bee1ae..f1612d9 100644 --- a/MiraAPI/Patches/Freeplay/TaskAdderPatches.cs +++ b/MiraAPI/Patches/Freeplay/TaskAdderPatches.cs @@ -276,8 +276,9 @@ public static class TaskAdderPatches __instance.transform.FindChild("TitleText_TMP")?.gameObject.DestroyImmediate(); } - __instance.ActiveItems.ToArray().Do(x => x.gameObject.Destroy()); + __instance.ActiveItems.ToArray().Do(x => x.gameObject.DeepDestroy(false)); __instance.ActiveItems.Clear(); + Utilities.Extensions.ClearGarbageCollector(); float num = 0f; float num2 = 0f; diff --git a/MiraAPI/Patches/HudManagerPatches.cs b/MiraAPI/Patches/HudManagerPatches.cs index 4214491..ac71a5a 100644 --- a/MiraAPI/Patches/HudManagerPatches.cs +++ b/MiraAPI/Patches/HudManagerPatches.cs @@ -143,8 +143,9 @@ public static class HudManagerPatches foreach (var t in BottomLeft.GetComponentsInChildren(true)) { - t.gameObject.Destroy(); + t.gameObject.DeepDestroy(false); } + Utilities.Extensions.ClearGarbageCollector(); var gridArrange = BottomLeft.GetComponent(); var aspectPosition = BottomLeft.GetComponent(); diff --git a/MiraAPI/Patches/LocalSettings/ToggleBehaviourPatch.cs b/MiraAPI/Patches/LocalSettings/ToggleBehaviourPatch.cs index ea137c8..696ac9d 100644 --- a/MiraAPI/Patches/LocalSettings/ToggleBehaviourPatch.cs +++ b/MiraAPI/Patches/LocalSettings/ToggleBehaviourPatch.cs @@ -21,8 +21,8 @@ public static class ToggleBehaviourPatch // Used to mask the text __instance.Text.richText = true; __instance.Text.text = $"" + - $"{DestroyableSingleton.Instance.GetString(__instance.BaseText)}: " + - $"{DestroyableSingleton.Instance.GetString(__instance.onState ? StringNames.SettingsOn : StringNames.SettingsOff)}"; + $"{TranslationController.Instance.GetString(__instance.BaseText)}: " + + $"{TranslationController.Instance.GetString(__instance.onState ? StringNames.SettingsOn : StringNames.SettingsOff)}"; __instance.Text.sortingOrder = 151; __instance.Text.renderer.sortingLayerName = "Default"; __instance.Text.renderer.sortingOrder = 151; diff --git a/MiraAPI/Patches/Menu/HatsTabPatches.cs b/MiraAPI/Patches/Menu/HatsTabPatches.cs index 5f07cfd..25eca33 100644 --- a/MiraAPI/Patches/Menu/HatsTabPatches.cs +++ b/MiraAPI/Patches/Menu/HatsTabPatches.cs @@ -11,8 +11,6 @@ using Reactor.Utilities; using Reactor.Utilities.Extensions; using TMPro; using UnityEngine; -using UnityEngine.Events; -using UnityEngine.UI; using Object = UnityEngine.Object; namespace MiraAPI.Patches.Menu; @@ -94,9 +92,10 @@ public static class HatsTabPatches if (loadRoutine != null) Coroutines.Stop(loadRoutine); hatIndex = 0; - foreach (var instanceColorChip in __instance.ColorChips) instanceColorChip.gameObject.Destroy(); + foreach (var instanceColorChip in __instance.ColorChips) instanceColorChip.gameObject.DeepDestroy(false); __instance.ColorChips.Clear(); - __instance.scroller.Inner.GetComponentsInChildren().Do(x => x.gameObject.Destroy()); + __instance.scroller.Inner.GetComponentsInChildren().Do(x => x.gameObject.DeepDestroy(false)); + Utilities.Extensions.ClearGarbageCollector(); var groupNameText = __instance.GetComponentInChildren(false); diff --git a/MiraAPI/Patches/Menu/MainMenuManagerPatches.cs b/MiraAPI/Patches/Menu/MainMenuManagerPatches.cs index 90f04fb..a52bc78 100644 --- a/MiraAPI/Patches/Menu/MainMenuManagerPatches.cs +++ b/MiraAPI/Patches/Menu/MainMenuManagerPatches.cs @@ -1,4 +1,5 @@ -using System.Collections; +using System; +using System.Collections; using HarmonyLib; using MiraAPI.LocalSettings; using MiraAPI.Utilities.Assets; @@ -13,6 +14,8 @@ namespace MiraAPI.Patches.Menu; [HarmonyPatch(typeof(MainMenuManager))] public static class MainMenuManagerPatches { + internal static bool NeedsDeepDestroy { get; private set; } + /// /// A postifix on Awake to load all the addressables registered. /// @@ -20,6 +23,9 @@ public static class MainMenuManagerPatches [HarmonyPostfix] public static void AwakePostfix() { + var requiredVersion = new Version(2026, 6, 5); + var version = Version.Parse(Application.version); + NeedsDeepDestroy = version >= requiredVersion; AddressablesLoader.LoadAll(); Coroutines.Start(SetFps()); } diff --git a/MiraAPI/Patches/Menu/NameplatesTabPatches.cs b/MiraAPI/Patches/Menu/NameplatesTabPatches.cs index 1526cce..ca4b79d 100644 --- a/MiraAPI/Patches/Menu/NameplatesTabPatches.cs +++ b/MiraAPI/Patches/Menu/NameplatesTabPatches.cs @@ -51,7 +51,7 @@ public static class NameplatesTabPatches } __instance.plateId = HatManager.Instance.GetNamePlateById(DataManager.Player.Customization.namePlate).ProdId; - if (!SortedNameplates.ContainsKey("Vanilla")) AddRange(DestroyableSingleton.Instance.GetUnlockedNamePlates().Select(x => ("Vanilla", x))); + if (!SortedNameplates.ContainsKey("Vanilla")) AddRange(HatManager.Instance.GetUnlockedNamePlates().Select(x => ("Vanilla", x))); InventoryUtility.CreateNextBackButtons(__instance, PreviousPage, NextPage); @@ -81,9 +81,10 @@ public static class NameplatesTabPatches private static void GenerateHats(NameplatesTab __instance, int page) { - foreach (ColorChip instanceColorChip in __instance.ColorChips) instanceColorChip.gameObject.Destroy(); + foreach (var instanceColorChip in __instance.ColorChips) instanceColorChip.gameObject.DeepDestroy(false); __instance.ColorChips.Clear(); - __instance.scroller.Inner.GetComponentsInChildren().Do(x => x.gameObject.Destroy()); + __instance.scroller.Inner.GetComponentsInChildren().Do(x => x.gameObject.DeepDestroy(false)); + Utilities.Extensions.ClearGarbageCollector(); var groupNameText = __instance.GetComponentInChildren(false); diff --git a/MiraAPI/Patches/Menu/SkinsTabPatches.cs b/MiraAPI/Patches/Menu/SkinsTabPatches.cs index 8e99bf2..24bec7c 100644 --- a/MiraAPI/Patches/Menu/SkinsTabPatches.cs +++ b/MiraAPI/Patches/Menu/SkinsTabPatches.cs @@ -83,9 +83,10 @@ public static class SkinsTabPatches private static void GenerateHats(SkinsTab __instance, int page) { - foreach (ColorChip instanceColorChip in __instance.ColorChips) instanceColorChip.gameObject.Destroy(); + foreach (var instanceColorChip in __instance.ColorChips) instanceColorChip.gameObject.DeepDestroy(false); __instance.ColorChips.Clear(); - __instance.scroller.Inner.GetComponentsInChildren().Do(x => x.gameObject.Destroy()); + __instance.scroller.Inner.GetComponentsInChildren().Do(x => x.gameObject.DeepDestroy(false)); + Utilities.Extensions.ClearGarbageCollector(); var groupNameText = __instance.GetComponentInChildren(false); diff --git a/MiraAPI/Patches/Menu/VisorsTabPatches.cs b/MiraAPI/Patches/Menu/VisorsTabPatches.cs index c543a94..8d50ece 100644 --- a/MiraAPI/Patches/Menu/VisorsTabPatches.cs +++ b/MiraAPI/Patches/Menu/VisorsTabPatches.cs @@ -51,7 +51,7 @@ public static class VisorsTabPatches } __instance.visorId = HatManager.Instance.GetVisorById(DataManager.Player.Customization.Visor).ProdId; - if (!SortedVisors.ContainsKey("Vanilla")) AddRange(DestroyableSingleton.Instance.GetUnlockedVisors().Select(x => ("Vanilla", x))); + if (!SortedVisors.ContainsKey("Vanilla")) AddRange(HatManager.Instance.GetUnlockedVisors().Select(x => ("Vanilla", x))); InventoryUtility.CreateNextBackButtons(__instance, PreviousPage, NextPage); @@ -81,9 +81,10 @@ public static class VisorsTabPatches private static void GenerateHats(VisorsTab __instance, int page) { - foreach (ColorChip instanceColorChip in __instance.ColorChips) instanceColorChip.gameObject.Destroy(); + foreach (var instanceColorChip in __instance.ColorChips) instanceColorChip.gameObject.DeepDestroy(false); __instance.ColorChips.Clear(); - __instance.scroller.Inner.GetComponentsInChildren().Do(x => x.gameObject.Destroy()); + __instance.scroller.Inner.GetComponentsInChildren().Do(x => x.gameObject.DeepDestroy(false)); + Utilities.Extensions.ClearGarbageCollector(); var groupNameText = __instance.GetComponentInChildren(false); diff --git a/MiraAPI/Patches/Options/GamePresetsTabPatches.cs b/MiraAPI/Patches/Options/GamePresetsTabPatches.cs index 2c6cc68..a4b6cca 100644 --- a/MiraAPI/Patches/Options/GamePresetsTabPatches.cs +++ b/MiraAPI/Patches/Options/GamePresetsTabPatches.cs @@ -262,7 +262,7 @@ internal static class GamePresetsTabPatches iconSpriteRend.sprite = MiraAssets.RefreshIcon.LoadAsset(); Helpers.DivideSize(refreshButton.gameObject, 2f); - refreshButton.buttonText.gameObject.Destroy(); + refreshButton.buttonText.gameObject.DeepDestroy(); refreshButton.OnClick = new Button.ButtonClickedEvent(); refreshButton.OnClick.AddListener((UnityAction)Refresh); diff --git a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs index 62560a8..082cc9c 100644 --- a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs +++ b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs @@ -53,15 +53,30 @@ public static class RoleSettingMenuPatches [HarmonyPatch(nameof(RolesSettingsMenu.SetQuotaTab))] public static bool SetQuotaTabPatch(RolesSettingsMenu __instance) { - Headers.ForEach(Object.Destroy); - RoleOptionSettings.ForEach(Object.Destroy); + foreach (var obj in Headers) + { + if (!obj) + { + continue; + } + obj.DeepDestroy(false); + } Headers.Clear(); + foreach (var obj in RoleOptionSettings) + { + if (!obj) + { + continue; + } + obj.gameObject.DeepDestroy(false); + } RoleOptionSettings.Clear(); CurrentRole = null; CurrentRoleOptions = null; __instance.roleChances = new Il2CppSystem.Collections.Generic.List(); __instance.advancedSettingChildren = new Il2CppSystem.Collections.Generic.List(); + Utilities.Extensions.ClearGarbageCollector(); var maskBg = __instance.scrollBar.transform.FindChild("MaskBg"); var hitbox = __instance.scrollBar.transform.FindChild("Hitbox"); @@ -204,9 +219,9 @@ public static class RoleSettingMenuPatches var blankLabel = quotaInst.transform.FindChild("BlankLabel").gameObject; var chanceLabel = quotaInst.transform.FindChild("Chance Label").gameObject; var countLabel = quotaInst.transform.FindChild("# Label").gameObject; - blankLabel.Destroy(); - chanceLabel.Destroy(); - countLabel.Destroy(); + blankLabel.DeepDestroy(false); + chanceLabel.DeepDestroy(false); + countLabel.DeepDestroy(false); categoryHeaderMasked.Background.sprite = MiraAssets.CategoryHeader.LoadAsset(); categoryHeaderMasked.Background.sprite.texture.filterMode = FilterMode.Bilinear; @@ -289,16 +304,25 @@ public static class RoleSettingMenuPatches { RoleGroupHidden[group] = !groupHidden; } - foreach (var header in Headers) + foreach (var obj in Headers) { - header.Destroy(); + if (!obj) + { + continue; + } + obj.DeepDestroy(false); } Headers.Clear(); - foreach (var option in RoleOptionSettings) + foreach (var obj in RoleOptionSettings) { - option.gameObject.Destroy(); + if (!obj) + { + continue; + } + obj.gameObject.DeepDestroy(false); } RoleOptionSettings.Clear(); + Utilities.Extensions.ClearGarbageCollector(); __instance.SetQuotaTab(); })); headerBtn.SetButtonEnableState(true); @@ -422,11 +446,12 @@ public static class RoleSettingMenuPatches { foreach (var optBehaviour in __instance.AdvancedRolesSettings.GetComponentsInChildren()) { - optBehaviour.gameObject.DestroyImmediate(); + optBehaviour.gameObject.DeepDestroy(false); } CurrentRole = role; __instance.advancedSettingChildren.Clear(); + Utilities.Extensions.ClearGarbageCollector(); // TODO: create sub groups under the role settings. var filteredOptions = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups @@ -618,7 +643,7 @@ public static class RoleSettingMenuPatches var newButton = Object.Instantiate(roleOptionSetting.buttons[0], roleOptionSetting.transform); newButton.name = "ConfigButton"; newButton.transform.localPosition = new Vector3(0.4473f, -0.3f, -2f); - newButton.transform.FindChild("Text_TMP").gameObject.DestroyImmediate(); + newButton.transform.FindChild("Text_TMP").gameObject.DeepDestroy(); newButton.activeSprites.Destroy(); var btnRend = newButton.transform.FindChild("ButtonSprite").GetComponent(); diff --git a/MiraAPI/Patches/Roles/HudManagerPatches.cs b/MiraAPI/Patches/Roles/HudManagerPatches.cs index 5ae8cc6..cdf7382 100644 --- a/MiraAPI/Patches/Roles/HudManagerPatches.cs +++ b/MiraAPI/Patches/Roles/HudManagerPatches.cs @@ -1,7 +1,9 @@ using HarmonyLib; using InnerNet; using MiraAPI.Roles; +using MiraAPI.Utilities; using Reactor.Utilities.Extensions; +using UnityEngine; namespace MiraAPI.Patches.Roles; @@ -69,9 +71,10 @@ public static class HudManagerPatches CustomRoleManager.UpdateRoleTab(RoleTab, customRole); } - else if (RoleTab) + else if (RoleTab != null) { - RoleTab?.gameObject.Destroy(); + RoleTab.gameObject.DeepDestroy(); + RoleTab = null; } } } diff --git a/MiraAPI/Presets/PresetManager.cs b/MiraAPI/Presets/PresetManager.cs index 2a33b4d..83b352f 100644 --- a/MiraAPI/Presets/PresetManager.cs +++ b/MiraAPI/Presets/PresetManager.cs @@ -4,6 +4,7 @@ using System.Linq; using BepInEx.Configuration; using MiraAPI.PluginLoading; using MiraAPI.Roles; +using MiraAPI.Utilities; using Reactor.Utilities; using UnityEngine; @@ -61,7 +62,7 @@ public static class PresetManager { if (btn != null) { - Object.DestroyImmediate(btn); + btn.DeepDestroy(); } } diff --git a/MiraAPI/Presets/SavePresetPopup.cs b/MiraAPI/Presets/SavePresetPopup.cs index 87959e7..23ce48b 100644 --- a/MiraAPI/Presets/SavePresetPopup.cs +++ b/MiraAPI/Presets/SavePresetPopup.cs @@ -26,7 +26,7 @@ public class SavePresetPopup(nint cppPtr) : Minigame(cppPtr) // Cleanup holder object public void OnDestroy() { - transform.parent.gameObject.Destroy(); + transform.parent.gameObject.DeepDestroy(); } public override void Close() diff --git a/MiraAPI/Utilities/Assets/AddressablesLoader.cs b/MiraAPI/Utilities/Assets/AddressablesLoader.cs index f1ecddd..a309ed3 100644 --- a/MiraAPI/Utilities/Assets/AddressablesLoader.cs +++ b/MiraAPI/Utilities/Assets/AddressablesLoader.cs @@ -171,24 +171,24 @@ public static class AddressablesLoader var visorBehaviours = DiscoverAndReportData(RegisteredVisorKeys); var hatData = new List(); - hatData.AddRange(DestroyableSingleton.Instance.allHats); + hatData.AddRange(HatManager.Instance.allHats); hatData.ForEach(x => x.StoreName = "Vanilla"); - DestroyableSingleton.Instance.allHats = PrepareArray(hatData, hatBehaviours); + HatManager.Instance.allHats = PrepareArray(hatData, hatBehaviours); var skinData = new List(); - skinData.AddRange(DestroyableSingleton.Instance.allSkins); + skinData.AddRange(HatManager.Instance.allSkins); skinData.ForEach(x => x.StoreName = "Vanilla"); - DestroyableSingleton.Instance.allSkins = PrepareArray(skinData, skinBehaviours); + HatManager.Instance.allSkins = PrepareArray(skinData, skinBehaviours); var visorData = new List(); - visorData.AddRange(DestroyableSingleton.Instance.allVisors); + visorData.AddRange(HatManager.Instance.allVisors); VisorsTabPatches.AddRange(visorBehaviours); - DestroyableSingleton.Instance.allVisors = PrepareArray(visorData, visorBehaviours.Select(x=>x.Data).ToList()); + HatManager.Instance.allVisors = PrepareArray(visorData, visorBehaviours.Select(x=>x.Data).ToList()); var namePlateData = new List(); - namePlateData.AddRange(DestroyableSingleton.Instance.allNamePlates); + namePlateData.AddRange(HatManager.Instance.allNamePlates); NameplatesTabPatches.AddRange(namePlateBehaviours); - DestroyableSingleton.Instance.allNamePlates = PrepareArray(namePlateData, namePlateBehaviours.Select(x => x.Data).ToList()); + HatManager.Instance.allNamePlates = PrepareArray(namePlateData, namePlateBehaviours.Select(x => x.Data).ToList()); } private static T[] PrepareArray(List data, List behaviours) where T : CosmeticData diff --git a/MiraAPI/Utilities/Extensions.cs b/MiraAPI/Utilities/Extensions.cs index 7364e44..c74fadc 100644 --- a/MiraAPI/Utilities/Extensions.cs +++ b/MiraAPI/Utilities/Extensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -7,9 +8,11 @@ using System.Text.RegularExpressions; using HarmonyLib; using MiraAPI.GameOptions; using MiraAPI.Networking; +using MiraAPI.Patches.Menu; using MiraAPI.Roles; using MiraAPI.Voting; using Reactor.Utilities; +using Reactor.Utilities.Extensions; using Rewired; using Rewired.Data; using TMPro; @@ -53,7 +56,7 @@ public static class Extensions bool isComplete; if (self.amClosing == Minigame.CloseState.Closing) { - UnityEngine.Object.Destroy(self.gameObject); + self.gameObject.DeepDestroy(); return; } if (self.CloseSound && Constants.ShouldPlaySfx()) @@ -70,7 +73,7 @@ public static class Extensions } self.amClosing = Minigame.CloseState.Closing; self.logger.Info(string.Concat("Closing minigame ", self.GetType().Name)); - IAnalyticsReporter analytics = DestroyableSingleton.Instance.Analytics; + IAnalyticsReporter analytics = DebugAnalytics.Instance.Analytics; NetworkedPlayerInfo data = PlayerControl.LocalPlayer.Data; TaskTypes taskType = self.TaskType; float realtimeSinceStartup = Time.realtimeSinceStartup - self.timeOpened; @@ -219,6 +222,135 @@ public static class Extensions return Mathf.Approximately(number, Mathf.Round(number)); } + /// + /// Destroys the object properly. + /// + /// The object to destroy. + /// Whether to run the garbage collector immediately. + public static void DeepDestroy(this GameObject obj, bool clearGc = true) + { + if (MainMenuManagerPatches.NeedsDeepDestroy) + { + Coroutines.Start(Nuke(obj, clearGc)); + } + else + { + obj?.Destroy(); + } + } + + private static IEnumerator Nuke(GameObject? go, bool clearGc) + { + if (go == null) + yield break; + + try + { + go.transform.SetParent(null, false); + } + catch + { + // ignored + } + + try + { + go.SetActive(false); + } + catch + { + // ignored + } + + foreach (var mb in go.GetComponentsInChildren(true)) + { + if (mb == null) + continue; + + try + { + mb.StopAllCoroutines(); + } + catch + { + // ignored + } + + try + { + mb.enabled = false; + } + catch + { + // ignored + } + } + + foreach (var renderer in go.GetComponentsInChildren(true)) + { + if (renderer == null) + continue; + + try + { + foreach (var mat in renderer.materials) + { + if (mat != null) + UnityEngine.Object.Destroy(mat); + } + } + catch + { + // ignored + } + } + + foreach (var filter in go.GetComponentsInChildren(true)) + { + if (filter == null) + continue; + + try + { + var mesh = filter.mesh; + if (mesh != null) + UnityEngine.Object.Destroy(mesh); + } + catch + { + // ignored + } + } + + UnityEngine.Object.Destroy(go); + yield return null; + if (clearGc) + { + yield return CoFreeResources(); + } + } + + /// + /// Clears up the Garbage Collector manually if necessary. + /// + public static void ClearGarbageCollector() + { + if (!MainMenuManagerPatches.NeedsDeepDestroy) + { + return; + } + Coroutines.Start(CoFreeResources()); + } + + private static IEnumerator CoFreeResources() + { + yield return Resources.UnloadUnusedAssets(); + + GC.Collect(0, GCCollectionMode.Forced, blocking: true); + GC.WaitForPendingFinalizers(); + GC.Collect(0, GCCollectionMode.Forced, blocking: true); + } + /// /// Gets a cache of 's to improve performance. /// diff --git a/MiraAPI/Voting/VotingUtils.cs b/MiraAPI/Voting/VotingUtils.cs index f6bccb5..abafdd0 100644 --- a/MiraAPI/Voting/VotingUtils.cs +++ b/MiraAPI/Voting/VotingUtils.cs @@ -208,7 +208,7 @@ public static class VotingUtils } MeetingHud.Instance.TitleText.text = - DestroyableSingleton.Instance.GetString( + TranslationController.Instance.GetString( StringNames.MeetingVotingResults, Il2CppSystem.Array.Empty());