84 lines
2.6 KiB
C#
84 lines
2.6 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 SharedAltarCache
|
|
= PerformanceFish.Cache.ByIndex<RimWorld.Ideo,
|
|
PerformanceFish.ThoughtWorker_Precept_AltarSharingOptimization.SharedAltarCacheValue>;
|
|
|
|
namespace PerformanceFish;
|
|
|
|
public sealed class ThoughtWorker_Precept_AltarSharingOptimization : ClassWithFishPatches
|
|
{
|
|
public sealed class SharedAltar_Patch : FirstPriorityFishPatch
|
|
{
|
|
public override string Description { get; }
|
|
= "Caches results of ideology's shared altar thoughtworker and throttles it to wait a minimum of 128 ticks "
|
|
+ "between refreshes. Quite impactful on performance";
|
|
|
|
public override MethodBase TargetMethodInfo { get; } = AccessTools.Method(
|
|
typeof(ThoughtWorker_Precept_AltarSharing), nameof(ThoughtWorker_Precept_AltarSharing.SharedAltar));
|
|
|
|
public static bool Prefix(ThoughtWorker_Precept_AltarSharing __instance, Pawn pawn, ref Thing? __result,
|
|
out bool __state)
|
|
{
|
|
if (!pawn.IsSpawned())
|
|
{
|
|
__result = null;
|
|
return __state = false;
|
|
}
|
|
|
|
ref var cache = ref SharedAltarCache.Get.GetReference(pawn.Ideo);
|
|
|
|
if (cache.Dirty)
|
|
return __state = true;
|
|
|
|
__result = cache.thing;
|
|
return __state = false;
|
|
}
|
|
|
|
public static void Postfix(Pawn pawn, Thing __result, bool __state)
|
|
{
|
|
if (!__state)
|
|
return;
|
|
|
|
SharedAltarCache.Get[pawn.Ideo] = new(pawn, __result);
|
|
}
|
|
}
|
|
|
|
public record struct SharedAltarCacheValue
|
|
{
|
|
public Thing? thing;
|
|
private int _nextLateRefreshTick;
|
|
private int _nextEarlyRefreshTick;
|
|
private int _allStructuresListVersion;
|
|
private ListerThings _lister;
|
|
|
|
public SharedAltarCacheValue(Pawn pawn, Thing? result)
|
|
{
|
|
thing = result;
|
|
_nextLateRefreshTick = TickHelper.Add(3072, pawn.thingIDNumber, 2048);
|
|
_nextEarlyRefreshTick = TickHelper.Add(128, pawn.thingIDNumber, 128);
|
|
_lister = pawn.GetMap().listerThings;
|
|
_allStructuresListVersion = _lister.listsByGroup[(int)ThingRequestGroup.BuildingArtificial]._version;
|
|
}
|
|
|
|
public bool Dirty
|
|
{
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
get
|
|
{
|
|
var ticks = TickHelper.TicksGame;
|
|
return _nextLateRefreshTick < ticks
|
|
|| (_nextEarlyRefreshTick < ticks
|
|
&& _allStructuresListVersion
|
|
!= _lister.listsByGroup[(int)ThingRequestGroup.BuildingArtificial]._version);
|
|
}
|
|
}
|
|
|
|
public bool Equals(SharedAltarCacheValue other) => (thing == other.thing) & (_lister == other._lister);
|
|
|
|
public override int GetHashCode() => HashCode.Combine(thing, _lister);
|
|
}
|
|
} |