Skip to content

Commit

Permalink
when vessels are unloaded, clean up their PartSets and some part refe…
Browse files Browse the repository at this point in the history
…rences
  • Loading branch information
JonnyOThan committed Mar 13, 2024
1 parent e7325b1 commit 43c456a
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions KSPCommunityFixes/Performance/MemoryLeaks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ protected override void ApplyPatches(List<PatchInfo> patches)
PatchMethodType.Postfix,
AccessTools.Method(typeof(Part), nameof(Part.OnDestroy)),
this));
patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(Vessel), nameof(Vessel.Unload)),
this));

// EffectList dictionary enumerator leaks

Expand Down Expand Up @@ -703,6 +707,45 @@ static void Part_OnDestroy_Postfix(Part __instance)
#endif
}

// PartSets are awful as noted in OnSceneUnloaded. But vessel unloading is also a good time to clean these up instead of waiting for scene switch

static void CleanUpPartSet(PartSet partSet)
{
GameEvents.onPartResourceFlowStateChange.Remove(partSet.OnFlowStateChange);
GameEvents.onPartResourceFlowModeChange.Remove(partSet.OnFlowModeChange);

// these aren't *necessary* but help to reduce noise in reports
partSet.targetParts.Clear();
partSet.ship = null;
partSet.vessel = null;
}

// general unhooking of stuff when unloading a vessel. Note that vessel gameobjects are not usually destroyed until the vessel itself is
static void Vessel_Unload_Postfix(Vessel __instance)
{
__instance.rootPart = null;
FlightGlobals.ResetObjectPartUpwardsCache();
FlightGlobals.ResetObjectPartPointerUpwardsCache();

CleanUpPartSet(__instance.resourcePartSet);
CleanUpPartSet(__instance.simulationResourcePartSet);

foreach (var partSet in __instance.crossfeedSets)
{
CleanUpPartSet(partSet);
}

foreach (var partSet in __instance.simulationCrossfeedSets)
{
CleanUpPartSet(partSet);
}

__instance.resourcePartSet = null;
__instance.simulationResourcePartSet = null;
__instance.crossfeedSets.Clear();
__instance.simulationCrossfeedSets.Clear();
}

// EffectList is leaking Part references by keeping around this static enumerator
static void EffectList_Initialize_Postfix()
{
Expand Down

0 comments on commit 43c456a

Please sign in to comment.