62 lines
2.0 KiB
C#
62 lines
2.0 KiB
C#
// Copyright (c) 2023 bradson
|
|
// 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 Mono.Cecil;
|
|
using Mono.Cecil.Cil;
|
|
using PerformanceFish.Events;
|
|
using PerformanceFish.Prepatching;
|
|
|
|
namespace PerformanceFish.Hauling;
|
|
|
|
public sealed class GridsUtilityPatches : ClassWithFishPrepatches
|
|
{
|
|
public sealed class GetItemCountPatch : FishPrepatch
|
|
{
|
|
public override int Priority => HarmonyLib.Priority.First;
|
|
|
|
public override string? Description { get; }
|
|
= "Caches item counts in a grid, to not have to repeat counting on every request.";
|
|
|
|
public override MethodBase TargetMethodBase { get; } = methodof(GridsUtility.GetItemCount);
|
|
|
|
protected internal override void BeforeHarmonyPatching() => ThingEvents.Initialized += TryRegister;
|
|
|
|
public static void TryRegister(Thing thing)
|
|
{
|
|
if (!thing.IsItem())
|
|
return;
|
|
|
|
var thingEvents = thing.Events();
|
|
thingEvents.RegisteredAtThingGrid += Increment;
|
|
thingEvents.DeregisteredAtThingGrid += Decrement;
|
|
}
|
|
|
|
public static void Increment(Thing thing, Map map, in IntVec3 cell)
|
|
=> map.ItemCountGrid()[cell]++;
|
|
|
|
public static void Decrement(Thing thing, Map map, in IntVec3 cell)
|
|
{
|
|
ref var itemCount = ref map.ItemCountGrid()[cell];
|
|
itemCount--;
|
|
|
|
if (itemCount < 0)
|
|
{
|
|
itemCount = 0;
|
|
ErrorForInvalidCount(thing);
|
|
}
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
private static void ErrorForInvalidCount(Thing thing)
|
|
=> Log.Error($"Tried decrementing item count at cell {thing.Position} for thing '{
|
|
thing}', but it was already 0. This should never happen.");
|
|
|
|
public override void Transpiler(ILProcessor ilProcessor, ModuleDefinition module)
|
|
=> ilProcessor.ReplaceBodyWith(ReplacementBody);
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static int ReplacementBody(IntVec3 c, Map map) => map.ItemCountGrid()[c];
|
|
}
|
|
} |