Skip to content

Commit 83fe47f

Browse files
committed
Avoid duplicate call to PSystemSetup.SetActive in FlightDriver.setStartupNewVessel (#350)
Avoid second call to SetActive in FlightDriver.setStartupNewVessel When you launch out of the VAB, FlightDriver.setStartupNewVessel ends up starting all PQS instances twice. The initial start of PQS is very expensive, and all the work done on the first call is basically thrown away. This patches `FlightDriver.setStartupNewVessel` to avoid calling `PSystemSetup.SetActive` a second time. This is just a matter of patching the 3 different calls to shims that track whether they have been called.
1 parent fbbe476 commit 83fe47f

3 files changed

Lines changed: 74 additions & 0 deletions

File tree

GameData/KSPCommunityFixes/Settings.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,9 @@ KSP_COMMUNITY_FIXES
345345
// and on other occasions, wasting a ton of CPU processing time.
346346
PQSCoroutineLeak = true
347347

348+
/// Prevent KSP from restarting PQS for the current planet multiple times when launching a new ship.
349+
PQSOnlyStartOnce = true
350+
348351
// Remove unused ProgressTracking update handlers. Provides a very noticeable performance uplift in
349352
// career games having a large amount of celestial bodies and/or vessels.
350353
ProgressTrackingSpeedBoost = true

KSPCommunityFixes/KSPCommunityFixes.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@
228228
<Compile Include="Performance\ModuleDockingNodeFindOtherNodesFaster.cs" />
229229
<Compile Include="Performance\OptimizedModuleRaycasts.cs" />
230230
<Compile Include="Performance\PQSCoroutineLeak.cs" />
231+
<Compile Include="Performance\PQSOnlyStartOnce.cs" />
231232
<Compile Include="Performance\PQSUpdateNoMemoryAlloc.cs" />
232233
<Compile Include="Performance\ProgressTrackingSpeedBoost.cs" />
233234
<Compile Include="QoL\AutostrutActions.cs" />
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
2+
using System.Collections.Generic;
3+
using System.Reflection.Emit;
4+
using HarmonyLib;
5+
6+
namespace KSPCommunityFixes.Performance
7+
{
8+
class PQSOnlyStartOnce : BasePatch
9+
{
10+
11+
protected override void ApplyPatches()
12+
{
13+
AddPatch(PatchType.Transpiler, typeof(FlightDriver), nameof(FlightDriver.setStartupNewVessel));
14+
}
15+
16+
17+
static IEnumerable<CodeInstruction> FlightDriver_setStartupNewVessel_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator gen)
18+
{
19+
var method1 = SymbolExtensions.GetMethodInfo<PSystemSetup>(p => p.SetPQSActive(null));
20+
var method2 = SymbolExtensions.GetMethodInfo<PSystemSetup>(p => p.SetPQSActive());
21+
22+
var matcher = new CodeMatcher(instructions);
23+
var state = gen.DeclareLocal(typeof(State));
24+
25+
matcher
26+
.MatchStartForward(new CodeMatch(OpCodes.Callvirt, method1))
27+
.Repeat(
28+
matcher =>
29+
{
30+
matcher.RemoveInstruction();
31+
matcher.InsertAndAdvance(new CodeInstruction(OpCodes.Ldloca, state));
32+
matcher.InsertAndAdvance(CodeInstruction.Call<State>(s => SetPQSActive(null, null, ref s)));
33+
}
34+
);
35+
36+
matcher.Start();
37+
matcher
38+
.MatchStartForward(new CodeMatch(OpCodes.Callvirt, method2))
39+
.Repeat(
40+
matcher =>
41+
{
42+
matcher.RemoveInstruction();
43+
matcher.InsertAndAdvance(new CodeInstruction(OpCodes.Ldloca, state));
44+
matcher.InsertAndAdvance(CodeInstruction.Call<State>(s => SetPQSActive(null, ref s)));
45+
}
46+
);
47+
48+
return matcher.Instructions();
49+
}
50+
51+
struct State
52+
{
53+
public bool activated;
54+
}
55+
56+
static void SetPQSActive(PSystemSetup psystem, PQS pqs, ref State state)
57+
{
58+
psystem.SetPQSActive(pqs);
59+
state.activated = true;
60+
}
61+
62+
static void SetPQSActive(PSystemSetup psystem, ref State state)
63+
{
64+
if (state.activated)
65+
return;
66+
67+
psystem.SetPQSActive();
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)