1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-09 16:13:31 +08:00

improve performance of LabOpt by replacing use of FieldInfo with self CIL-patches

This commit is contained in:
2023-09-12 02:59:56 +08:00
parent 6361ab21c6
commit e12d20980a
2 changed files with 40 additions and 14 deletions

View File

@@ -10,19 +10,16 @@ namespace LabOpt;
public static class LabOptPatchFunctions public static class LabOptPatchFunctions
{ {
private static readonly FieldInfo RootLabIdField = AccessTools.Field(typeof(LabComponent), "rootLabId");
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SetRootId(ref LabComponent lab, int rootId) public static void SetRootId(ref LabComponent lab, int rootId)
{ {
RootLabIdField.SetValueDirect(__makeref(lab), rootId); lab.pcId = rootId;
} }
public static void SetRootLabIdForStacking(FactorySystem factorySystem, int labId, int nextEntityId) public static void SetRootLabIdForStacking(FactorySystem factorySystem, int labId, int nextEntityId)
{ {
var labPool = factorySystem.labPool; var labPool = factorySystem.labPool;
var factory = factorySystem.factory; var factory = factorySystem.factory;
var rootId = (int)RootLabIdField.GetValue(labPool[labId]); var rootId = labPool[labId].pcId;
if (rootId <= 0) if (rootId <= 0)
{ {
var radiusBear = factory.planet.radius + 2.0f; var radiusBear = factory.planet.radius + 2.0f;
@@ -37,7 +34,7 @@ public static class LabOptPatchFunctions
do do
{ {
ref var targetLab = ref labPool[targetLabId]; ref var targetLab = ref labPool[targetLabId];
RootLabIdField.SetValueDirect(__makeref(targetLab), rootId); targetLab.pcId = rootId;
// LabOptPatch.Logger.LogDebug($"Set rootLabId of lab {targetLabId} to {rootId}, {needSetFunction}"); // LabOptPatch.Logger.LogDebug($"Set rootLabId of lab {targetLabId} to {rootId}, {needSetFunction}");
if (needSetFunction) if (needSetFunction)
{ {
@@ -84,13 +81,12 @@ public static class LabOptPatchFunctions
var rootId = pair.Value; var rootId = pair.Value;
while (parentDict.TryGetValue(rootId, out var parentId)) rootId = parentId; while (parentDict.TryGetValue(rootId, out var parentId)) rootId = parentId;
ref var targetLab = ref labPool[pair.Key]; ref var targetLab = ref labPool[pair.Key];
RootLabIdField.SetValueDirect(__makeref(targetLab), rootId); targetLab.pcId = rootId;
// LabOptPatch.Logger.LogDebug($"Set rootLabId of lab {pair.Key} to {rootId}"); // LabOptPatch.Logger.LogDebug($"Set rootLabId of lab {pair.Key} to {rootId}");
AssignRootLabValues(ref labPool[rootId], ref targetLab); AssignRootLabValues(ref labPool[rootId], ref targetLab);
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AssignRootLabValues(ref LabComponent rootLab, ref LabComponent thisLab) private static void AssignRootLabValues(ref LabComponent rootLab, ref LabComponent thisLab)
{ {
int len; int len;
@@ -375,7 +371,7 @@ public static class LabOptPatchFunctions
public static void SetFunctionManually(ref LabComponent lab, bool researchMode, int recpId, int techId, SignData[] signPool, LabComponent[] labPool) public static void SetFunctionManually(ref LabComponent lab, bool researchMode, int recpId, int techId, SignData[] signPool, LabComponent[] labPool)
{ {
var rootLabId = (int)RootLabIdField.GetValue(lab); var rootLabId = lab.pcId;
if (rootLabId > 0) if (rootLabId > 0)
{ {
ref var rootLab = ref labPool[rootLabId]; ref var rootLab = ref labPool[rootLabId];
@@ -407,7 +403,7 @@ public static class LabOptPatchFunctions
while (nextLabId > 0) while (nextLabId > 0)
{ {
ref var nextLab = ref labPool[nextLabId]; ref var nextLab = ref labPool[nextLabId];
if ((int)RootLabIdField.GetValue(nextLab) != thisId) break; if (nextLab.pcId != thisId) break;
if (needs != nextLab.needs) if (needs != nextLab.needs)
SetFunctionInternal(ref nextLab, researchMode, recpId, techId, signPool, labPool); SetFunctionInternal(ref nextLab, researchMode, recpId, techId, signPool, labPool);
nextLabId = nextLab.nextLabId; nextLabId = nextLab.nextLabId;
@@ -415,8 +411,7 @@ public static class LabOptPatchFunctions
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SetFunctionInternal(ref LabComponent lab, bool researchMode, int recpId, int techId, SignData[] signPool, LabComponent[] labPool)
private static void SetFunctionInternal(ref LabComponent lab, bool researchMode, int recpId, int techId, SignData[] signPool, LabComponent[] labPool)
{ {
// LabOptPatch.Logger.LogDebug($"SetFunctionInternal: id={lab.id} root={(int)RootLabIdField.GetValue(lab)} research={researchMode} recp={recpId} tech={techId}"); // LabOptPatch.Logger.LogDebug($"SetFunctionInternal: id={lab.id} root={(int)RootLabIdField.GetValue(lab)} research={researchMode} recp={recpId} tech={techId}");
lab.replicating = false; lab.replicating = false;
@@ -443,7 +438,7 @@ public static class LabOptPatchFunctions
lab.productCounts = null; lab.productCounts = null;
lab.produced = null; lab.produced = null;
lab.productive = true; lab.productive = true;
var rootLabId = (int)RootLabIdField.GetValue(lab); var rootLabId = lab.pcId;
if (rootLabId > 0) if (rootLabId > 0)
{ {
ref var rootLab = ref labPool[rootLabId]; ref var rootLab = ref labPool[rootLabId];
@@ -512,7 +507,7 @@ public static class LabOptPatchFunctions
lab.extraTimeSpend = recipeProto.TimeSpend * 100000; lab.extraTimeSpend = recipeProto.TimeSpend * 100000;
lab.productive = recipeProto.productive; lab.productive = recipeProto.productive;
lab.forceAccMode &= lab.productive; lab.forceAccMode &= lab.productive;
var rootLabId = (int)RootLabIdField.GetValue(lab); var rootLabId = lab.pcId;
if (rootLabId > 0) if (rootLabId > 0)
{ {
ref var rootLab = ref labPool[rootLabId]; ref var rootLab = ref labPool[rootLabId];

View File

@@ -332,4 +332,35 @@ public class LabOptPatch : BaseUnityPlugin
{ {
LabOptPatchFunctions.SetRootId(ref __instance, 0); LabOptPatchFunctions.SetRootId(ref __instance, 0);
} }
[HarmonyTranspiler]
[HarmonyPatch(typeof(LabOptPatchFunctions), nameof(LabOptPatchFunctions.SetRootId))]
[HarmonyPatch(typeof(LabOptPatchFunctions), nameof(LabOptPatchFunctions.SetRootLabIdForStacking))]
[HarmonyPatch(typeof(LabOptPatchFunctions), nameof(LabOptPatchFunctions.SetRootLabIdOnLoading))]
[HarmonyPatch(typeof(LabOptPatchFunctions), nameof(LabOptPatchFunctions.SetFunctionManually))]
[HarmonyPatch(typeof(LabOptPatchFunctions), nameof(LabOptPatchFunctions.SetFunctionInternal))]
private static IEnumerable<CodeInstruction> LabOptPatchFunctions_PatchRootId_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var matcher = new CodeMatcher(instructions, generator);
matcher.Start().MatchForward(false,
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(LabComponent), nameof(LabComponent.pcId)))
);
if (matcher.IsValid)
{
matcher.Repeat(codeMatcher => codeMatcher.SetInstructionAndAdvance(
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(LabComponent), "rootLabId"))
));
}
matcher.Start().MatchForward(false,
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(LabComponent), nameof(LabComponent.pcId)))
);
if (matcher.IsValid)
{
matcher.Repeat(codeMatcher => codeMatcher.SetInstructionAndAdvance(
new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(LabComponent), "rootLabId"))
));
}
return matcher.InstructionEnumeration();
}
} }