RimWorld.Toils_Bed:FailOnBedNoLongerUseable optimization to skip calls to BedNoLongerUseable with a tick offset

This commit is contained in:
missionz3r0
2024-12-22 20:07:08 -05:00
parent 0fd4686b18
commit 92beae4e9a
6 changed files with 64 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
View File
@@ -86,6 +86,9 @@
<!-- JobGiver_Haul -->
<li>RimWorld.JobGiver_Haul:TryGiveJob</li>
<!-- Toils_Bed -->
<li>RimWorld.Toils_Bed:BedNoLongerUsable</li>
<!-- IdeoUtility -->
<li>RimWorld.IdeoUtility:GetStyleDominance</li>
@@ -0,0 +1,61 @@
// Copyright (c) 2024 bradson, missionz3r0
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
using System.Linq;
using System.Reflection.Emit;
using Verse.AI;
namespace PerformanceFish.JobSystem;
public sealed class Toils_BedOptimization : ClassWithFishPatches
{
public sealed class FailOnBedNoLongerUsable_Patch : FishPatch
{
public override string Description { get; }
= "Adds a HashOffset to skip BedNoLongerUsable calls every tick.";
public override MethodBase TargetMethodInfo { get; }
= FindDelegateMethod(
AccessTools.Method(typeof(Toils_Bed), nameof(Toils_Bed.FailOnBedNoLongerUsable), [typeof(Toil), typeof(TargetIndex), typeof(TargetIndex)]),
"FailOn"
);
public static bool Prefix(ref bool __result)
{
if (TickHelper.MatchesModulo(64))
return true;
return __result = false;
}
}
private static MethodBase FindDelegateMethod(
MethodBase containingMethod,
string secondOrderMethod
)
{
var body = PatchProcessor.ReadMethodBody(containingMethod).ToList();
for (var i = 0; i < body.Count; i++)
{
var (opcode, operand) = body[i];
if (operand is not MethodInfo info || info.Name != secondOrderMethod)
continue;
while (--i >= 0)
{
(opcode, operand) = body[i];
if (opcode == OpCodes.Ldftn)
return (MethodBase)operand;
}
break;
}
throw new InvalidOperationException(
$"Performance Fish failed to find a delegate called from method {secondOrderMethod} within method {containingMethod}"
);
}
}