/// <summary> /// Unloads the given GadgetMod. /// Cannot fully release the mod's RAM usage, as the old instance of the mod assembly that is stored in RAM cannot be fully removed. /// WARNING: Will trigger an immediate garbage collection, causing a short freeze! /// </summary> public static void UnloadMod(GadgetMod mod) { try { if (mod.Name == "GadgetCore") { throw new InvalidOperationException(GadgetMods.GetModByAssembly(Assembly.GetCallingAssembly()).Name + " seriously just tried to unload GadgetCore... Really?"); } List <GadgetMod> modsToUnload = mod.LoadedGadgets.SelectMany(x => Gadgets.LoadOrderTree.Find(x).FlattenUniqueByBreadth().Where(y => y != x)).Where(x => x != null).Select(x => x.Mod).Distinct().ToList(); bool wasBatchLoading = BatchLoading; BatchLoading = true; foreach (GadgetMod modToUnload in modsToUnload) { UnloadModInternal(modToUnload); } mod.Unload(); GC.Collect(); BatchLoading = wasBatchLoading; DisableQueuedGadgets(); Gadgets.SortGadgets(); } catch (Exception e) { Logger.LogError("Error unloading " + mod.Name + ": " + e); } }
/// <summary> /// Hard-reloads the given GadgetMod. (Loads it freshly from the disk). /// Also reloads all mods that are dependent on this mod. /// Causes a permanent increase in the game's RAM usage, as the old instance of the mod assembly that is stored in RAM cannot be fully removed. /// WARNING: Will trigger an immediate GC collection, causing a short freeze! /// </summary> public static GadgetMod ReloadMod(GadgetMod mod) { try { if (mod.Name == "GadgetCore") { throw new InvalidOperationException(GadgetMods.GetModByAssembly(Assembly.GetCallingAssembly()).Name + " seriously just tried to reload GadgetCore... Really?"); } string modPath = mod.ModPath; List <GadgetMod> modsToReload = mod.LoadedGadgets.SelectMany(x => Gadgets.LoadOrderTree.Find(x).FlattenUniqueByBreadth()).Where(x => x != null).Select(x => x.Mod).Distinct().ToList(); foreach (GadgetMod modToUnload in modsToReload) { if (modToUnload.Name != "GadgetCore") { UnloadModInternal(modToUnload); } } GC.Collect(); BatchLoading = true; Logger.Log("Loading mod files..."); for (int i = 0; i < modsToReload.Count; i++) { if (modsToReload[i].Name != "GadgetCore") { if (modsToReload[i].IsArchive) { if (modsToReload[i].ModPath == modPath) { modsToReload[i] = mod = LoadModFile(modsToReload[i].ModPath); } else { modsToReload[i] = LoadModFile(modsToReload[i].ModPath); } } else { if (modsToReload[i].ModPath == modPath) { modsToReload[i] = mod = LoadModDir(modsToReload[i].ModPath); } else { modsToReload[i] = LoadModDir(modsToReload[i].ModPath); } } } else { RefreshMod(modsToReload[i]); } } Logger.Log("Done loading mod files."); Logger.Log("Loading mods..."); foreach (GadgetMod modToReload in modsToReload) { LoadGadgetMod(modToReload); } Logger.Log("Done loading mods."); Logger.Log("Sorting Gadgets..."); Gadgets.SortGadgets(); Logger.Log("Done sorting Gadgets."); Logger.Log("Queueing Gadgets for initialization..."); foreach (GadgetInfo gadget in modsToReload.SelectMany(x => x.LoadedGadgets)) { QueuedGadgets.Add(gadget); } Logger.Log("Done queueing Gadgets."); EnableQueuedGadgets(); BatchLoading = false; } catch (Exception e) { Logger.LogError("Error reloading " + mod.Name + ": " + e); } return(mod); }