Skip to content

Commit bdc26fb

Browse files
authored
perf: Optimize other resource converter modules (#169)
* perf: Disable asteroid harvesters when inactive When IsActivated is false these won't do anything. In this case we can save a bunch of time by completely disabling the module, instead of constantly running useless FixedUpdate calls that don't do anything. * perf: Disable comet harvesters when inactive * perf: Optimize ModuleSystemHeatConverter * Properly handle AlwaysActive
1 parent 6c4e88c commit bdc26fb

3 files changed

Lines changed: 275 additions & 253 deletions

File tree

Source/Modules/ModuleSystemHeatAsteroidHarvester.cs

Lines changed: 89 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using System.Collections.Generic;
21
using UnityEngine;
32
using KSP.Localization;
3+
using Unity.Profiling;
44

55
namespace SystemHeat
66
{
@@ -24,7 +24,7 @@ public class ModuleSystemHeatAsteroidHarvester : ModuleAsteroidDrill
2424
// Map system outlet temperature (K) to heat generation (kW)
2525
[KSPField(isPersistant = false)]
2626
public float systemPower = 0f;
27-
//
27+
//
2828
[KSPField(isPersistant = false)]
2929
public float shutdownTemperature = 1000f;
3030

@@ -37,128 +37,140 @@ public class ModuleSystemHeatAsteroidHarvester : ModuleAsteroidDrill
3737
[KSPField(isPersistant = false, guiActive = true, guiActiveEditor = true, guiName = "Harvester Efficiency")]
3838
public string HarvesterEfficiency = "-1%";
3939

40-
// base paramters
41-
private List<ResourceBaseRatio> inputs;
42-
private List<ResourceBaseRatio> outputs;
4340
protected ModuleSystemHeat heatModule;
4441

42+
private static readonly ProfilerMarker BaseFixedUpdateMarker = new("ModuleAsteroidDrill.FixedUpdate");
43+
4544
public override string GetInfo()
4645
{
4746
string info = base.GetInfo();
4847

4948
int pos = info.IndexOf("\n\n");
5049
if (pos < 0)
5150
return info;
52-
else
53-
return info.Substring(0, pos) + Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_PartInfoAdd",
54-
Utils.ToSI(systemPower,"F0"),
55-
systemOutletTemperature.ToString("F0"),
56-
shutdownTemperature.ToString("F0")
57-
) + info.Substring(pos);
51+
52+
var extraInfo = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_PartInfoAdd",
53+
Utils.ToSI(systemPower, "F0"),
54+
systemOutletTemperature.ToString("F0"),
55+
shutdownTemperature.ToString("F0")
56+
);
57+
return info.Substring(0, pos) + extraInfo + info.Substring(pos);
5858
}
5959

6060
public void Start()
6161
{
62-
heatModule = ModuleUtils.FindHeatModule(this.part, systemHeatModuleID);
62+
heatModule = ModuleUtils.FindHeatModule(part, systemHeatModuleID);
63+
64+
Utils.Log("[ModuleSystemHeatAsteroidHarvester] Setup completed", LogType.Modules);
65+
Fields["HarvesterEfficiency"].guiName = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_Efficiency", ConverterName);
66+
}
6367

68+
public override void FixedUpdate()
69+
{
6470
if (HighLogic.LoadedSceneIsFlight)
6571
{
66-
SetupResourceRatios();
72+
FixedUpdateFlight();
6773
}
6874
else
6975
{
70-
SetupResourceRatios();
76+
UpdateFlux();
7177
}
72-
Utils.Log("[ModuleSystemHeatAsteroidHarvester] Setup completed", LogType.Modules);
73-
Fields["HarvesterEfficiency"].guiName = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_Efficiency", base.ConverterName);
7478
}
7579

76-
public override void FixedUpdate()
80+
void Update()
7781
{
78-
base.FixedUpdate();
79-
if (heatModule != null)
80-
{
81-
if (HighLogic.LoadedSceneIsFlight)
82-
{
83-
GenerateHeatFlight();
84-
UpdateSystemHeatFlight();
85-
}
86-
if (HighLogic.LoadedSceneIsEditor)
87-
{
88-
GenerateHeatEditor();
89-
}
90-
}
82+
if (!part.IsPAWVisible())
83+
return;
84+
85+
HarvesterEfficiency = Localizer.Format(
86+
"#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_Efficiency_Value",
87+
(GetHeatThrottle() * 100f).ToString("F1")
88+
);
9189
}
9290

93-
void Update()
91+
void OnDisable()
9492
{
95-
if (heatModule != null && part.IsPAWVisible())
96-
{
97-
HarvesterEfficiency = Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Field_Efficiency_Value", (systemEfficiency.Evaluate(heatModule.currentLoopTemperature) * 100f).ToString("F1"));
98-
}
93+
heatModule?.AddFlux(moduleID, 0f, 0f, false);
94+
HarvesterEfficiency = "-";
9995
}
10096

101-
protected void GenerateHeatEditor()
97+
void FixedUpdateFlight()
10298
{
103-
if (base.IsActivated)
99+
if (heatModule == null)
104100
{
105-
heatModule.AddFlux(moduleID, systemOutletTemperature, systemPower, true);
106-
}
107-
else
108-
{
109-
heatModule.AddFlux(moduleID, 0f, 0f, false);
101+
// This disables this module entirely, so it won't be called every frame.
102+
enabled = false;
103+
return;
110104
}
105+
106+
CheckOverheat();
107+
108+
if (!IsActivated && !AlwaysActive)
109+
enabled = false;
110+
111+
using (BaseFixedUpdateMarker.ConditionalAuto())
112+
base.FixedUpdate();
111113
}
112114

113-
protected void GenerateHeatFlight()
115+
void UpdateFlux() => UpdateFlux(lastTimeFactor);
116+
void UpdateFlux(double timeFactor)
114117
{
115-
if (base.ModuleIsActive())
118+
if (heatModule == null)
119+
return;
120+
121+
if (ModuleIsActive())
116122
{
117-
float fluxScale = 1f;
118-
if (base.lastTimeFactor == 0d)
119-
{
120-
fluxScale = 0f;
121-
}
122-
heatModule.AddFlux(moduleID, systemOutletTemperature, systemPower * fluxScale, true);
123+
float scale = timeFactor != 0.0 ? 1f : 0f;
124+
if (HighLogic.LoadedSceneIsEditor)
125+
scale = 1f;
126+
127+
heatModule.AddFlux(moduleID, systemOutletTemperature, systemPower * scale, true);
123128
}
124129
else
125130
{
126131
heatModule.AddFlux(moduleID, 0f, 0f, false);
127132
}
128133
}
129134

130-
protected void UpdateSystemHeatFlight()
135+
void CheckOverheat()
131136
{
132-
if (base.ModuleIsActive())
133-
{
134-
if (heatModule.currentLoopTemperature > shutdownTemperature)
135-
{
136-
ScreenMessages.PostScreenMessage(
137-
new ScreenMessage(
138-
Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatHarvester_Message_Shutdown",
139-
part.partInfo.title),
140-
3.0f,
141-
ScreenMessageStyle.UPPER_CENTER));
142-
ToggleResourceConverterAction(new KSPActionParam(0, KSPActionType.Activate));
143-
Utils.Log("[ModuleSystemHeatConverter]: Overheated, shutdown fired", LogType.Modules);
144-
}
145-
}
137+
if (!ModuleIsActive())
138+
return;
139+
if (heatModule.currentLoopTemperature <= shutdownTemperature)
140+
return;
141+
142+
ScreenMessages.PostScreenMessage(
143+
new ScreenMessage(
144+
Localizer.Format(
145+
"#LOC_SystemHeat_ModuleSystemHeatHarvester_Message_Shutdown",
146+
part.partInfo.title),
147+
3.0f,
148+
ScreenMessageStyle.UPPER_CENTER));
149+
StopResourceConverter();
150+
151+
Utils.Log("[ModuleSystemHeatConverter]: Overheated, shutdown fired", LogType.Modules);
152+
}
153+
154+
public override void StartResourceConverter()
155+
{
156+
enabled = true;
157+
base.StartResourceConverter();
146158
}
147159

148-
private void SetupResourceRatios()
160+
// In stock this would use the ModuleCoreHeat on the same part. We don't
161+
// want that, and just override it to point to our own efficiency multiplier.
162+
public override float GetHeatThrottle()
149163
{
150-
inputs = new List<ResourceBaseRatio>();
151-
outputs = new List<ResourceBaseRatio>();
164+
if (heatModule == null)
165+
return 1f;
152166

153-
for (int i = 0; i < inputList.Count; i++)
154-
{
155-
inputs.Add(new ResourceBaseRatio(inputList[i].ResourceName, inputList[i].Ratio));
156-
}
157-
for (int i = 0; i < outputList.Count; i++)
158-
{
159-
outputs.Add(new ResourceBaseRatio(outputList[i].ResourceName, outputList[i].Ratio));
160-
}
167+
return systemEfficiency.Evaluate(heatModule.currentLoopTemperature);
168+
}
169+
170+
protected override void PostProcess(ConverterResults result, double deltaTime)
171+
{
172+
base.PostProcess(result, deltaTime);
173+
UpdateFlux(result.TimeFactor);
161174
}
162175
}
163176
}
164-

0 commit comments

Comments
 (0)