Constrain reflection fast paths and preserve 1.6 tick behavior
This commit is contained in:
@@ -48,27 +48,19 @@ public sealed class CompTickOptimization : ClassWithFishPrepatches
|
||||
private static readonly bool _hediffCompPostTickIntervalBaseIsTrivial
|
||||
= IsTrivialVoidMethod(_hediffCompPostTickIntervalMethod);
|
||||
|
||||
#if V1_6
|
||||
private static int _canSkipInheritedBaseThingCompTickState;
|
||||
#else
|
||||
private static readonly Lazy<bool> _canSkipInheritedBaseThingCompTick
|
||||
= new(static () => _thingCompTickBaseIsTrivial && !HasHarmonyPatches(_thingCompTickMethod));
|
||||
#endif
|
||||
private struct BasePatchState
|
||||
{
|
||||
public int CheckedTick;
|
||||
public bool HasChecked;
|
||||
public bool CanSkip;
|
||||
}
|
||||
|
||||
private static readonly Lazy<bool> _canSkipInheritedBaseThingCompTickInterval
|
||||
= new(static () => _thingCompTickIntervalBaseIsTrivial && !HasHarmonyPatches(_thingCompTickIntervalMethod));
|
||||
|
||||
private static readonly Lazy<bool> _canSkipInheritedBaseThingCompTickRare
|
||||
= new(static () => _thingCompTickRareBaseIsTrivial && !HasHarmonyPatches(_thingCompTickRareMethod));
|
||||
|
||||
private static readonly Lazy<bool> _canSkipInheritedBaseThingCompTickLong
|
||||
= new(static () => _thingCompTickLongBaseIsTrivial && !HasHarmonyPatches(_thingCompTickLongMethod));
|
||||
|
||||
private static readonly Lazy<bool> _canSkipInheritedBaseHediffCompPostTick
|
||||
= new(static () => _hediffCompPostTickBaseIsTrivial && !HasHarmonyPatches(_hediffCompPostTickMethod));
|
||||
|
||||
private static readonly Lazy<bool> _canSkipInheritedBaseHediffCompPostTickInterval = new(
|
||||
static () => _hediffCompPostTickIntervalBaseIsTrivial && !HasHarmonyPatches(_hediffCompPostTickIntervalMethod));
|
||||
private static BasePatchState _thingCompTickState;
|
||||
private static BasePatchState _thingCompTickIntervalState;
|
||||
private static BasePatchState _thingCompTickRareState;
|
||||
private static BasePatchState _thingCompTickLongState;
|
||||
private static BasePatchState _hediffCompPostTickState;
|
||||
private static BasePatchState _hediffCompPostTickIntervalState;
|
||||
|
||||
private static readonly FishTable<Type, bool> _thingCompTickTypes = new()
|
||||
{
|
||||
@@ -196,12 +188,22 @@ public sealed class CompTickOptimization : ClassWithFishPrepatches
|
||||
|
||||
public static void ReplacementBody(ThingWithComps instance, int delta)
|
||||
{
|
||||
#if V1_6
|
||||
var comps = instance.comps;
|
||||
if (comps is null)
|
||||
return;
|
||||
#else
|
||||
var comps = instance.AllComps;
|
||||
#endif
|
||||
var count = comps.Count;
|
||||
var canSkipInheritedBase = CanSkipInheritedBaseThingCompTickInterval();
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
#if V1_6
|
||||
var comp = instance.comps![i];
|
||||
#else
|
||||
var comp = comps[i];
|
||||
#endif
|
||||
if (!canSkipInheritedBase || !_thingCompTickIntervalTypes.GetOrAdd(comp.GetType()))
|
||||
comp.CompTickInterval(delta);
|
||||
}
|
||||
@@ -223,12 +225,22 @@ public sealed class CompTickOptimization : ClassWithFishPrepatches
|
||||
|
||||
public static void ReplacementBody(ThingWithComps instance)
|
||||
{
|
||||
#if V1_6
|
||||
var comps = instance.comps;
|
||||
if (comps is null)
|
||||
return;
|
||||
#else
|
||||
var comps = instance.AllComps;
|
||||
#endif
|
||||
var count = comps.Count;
|
||||
var canSkipInheritedBase = CanSkipInheritedBaseThingCompTickRare();
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
#if V1_6
|
||||
var comp = instance.comps![i];
|
||||
#else
|
||||
var comp = comps[i];
|
||||
#endif
|
||||
if (!canSkipInheritedBase || !_thingCompTickRareTypes.GetOrAdd(comp.GetType()))
|
||||
comp.CompTickRare();
|
||||
}
|
||||
@@ -250,12 +262,22 @@ public sealed class CompTickOptimization : ClassWithFishPrepatches
|
||||
|
||||
public static void ReplacementBody(ThingWithComps instance)
|
||||
{
|
||||
#if V1_6
|
||||
var comps = instance.comps;
|
||||
if (comps is null)
|
||||
return;
|
||||
#else
|
||||
var comps = instance.AllComps;
|
||||
#endif
|
||||
var count = comps.Count;
|
||||
var canSkipInheritedBase = CanSkipInheritedBaseThingCompTickLong();
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
#if V1_6
|
||||
var comp = instance.comps![i];
|
||||
#else
|
||||
var comp = comps[i];
|
||||
#endif
|
||||
if (!canSkipInheritedBase || !_thingCompTickLongTypes.GetOrAdd(comp.GetType()))
|
||||
comp.CompTickLong();
|
||||
}
|
||||
@@ -281,13 +303,12 @@ public sealed class CompTickOptimization : ClassWithFishPrepatches
|
||||
if (comps == null)
|
||||
return;
|
||||
|
||||
var count = comps.Count;
|
||||
var severityAdjustment = 0f;
|
||||
var canSkipInheritedBase = CanSkipInheritedBaseHediffCompPostTick();
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
for (var i = 0; i < instance.comps!.Count; i++)
|
||||
{
|
||||
var comp = comps[i];
|
||||
var comp = instance.comps[i];
|
||||
if (!canSkipInheritedBase || !_hediffCompPostTickTypes.GetOrAdd(comp.GetType()))
|
||||
comp.CompPostTick(ref severityAdjustment);
|
||||
}
|
||||
@@ -316,13 +337,12 @@ public sealed class CompTickOptimization : ClassWithFishPrepatches
|
||||
if (comps == null)
|
||||
return;
|
||||
|
||||
var count = comps.Count;
|
||||
var severityAdjustment = 0f;
|
||||
var canSkipInheritedBase = CanSkipInheritedBaseHediffCompPostTickInterval();
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
for (var i = 0; i < instance.comps!.Count; i++)
|
||||
{
|
||||
var comp = comps[i];
|
||||
var comp = instance.comps[i];
|
||||
if (!canSkipInheritedBase || !_hediffCompPostTickIntervalTypes.GetOrAdd(comp.GetType()))
|
||||
comp.CompPostTickInterval(ref severityAdjustment, delta);
|
||||
}
|
||||
@@ -334,39 +354,47 @@ public sealed class CompTickOptimization : ClassWithFishPrepatches
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool CanSkipInheritedBaseThingCompTick()
|
||||
{
|
||||
#if V1_6
|
||||
var state = _canSkipInheritedBaseThingCompTickState;
|
||||
if (state == 0)
|
||||
{
|
||||
state = _thingCompTickBaseIsTrivial && !HasHarmonyPatches(_thingCompTickMethod) ? 2 : 1;
|
||||
_canSkipInheritedBaseThingCompTickState = state;
|
||||
}
|
||||
return state == 2;
|
||||
#else
|
||||
return _canSkipInheritedBaseThingCompTick.Value;
|
||||
#endif
|
||||
}
|
||||
=> CanSkipBaseMethod(_thingCompTickMethod, _thingCompTickBaseIsTrivial, ref _thingCompTickState);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool CanSkipInheritedBaseThingCompTickInterval()
|
||||
=> _canSkipInheritedBaseThingCompTickInterval.Value;
|
||||
=> CanSkipBaseMethod(_thingCompTickIntervalMethod, _thingCompTickIntervalBaseIsTrivial,
|
||||
ref _thingCompTickIntervalState);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool CanSkipInheritedBaseThingCompTickRare()
|
||||
=> _canSkipInheritedBaseThingCompTickRare.Value;
|
||||
=> CanSkipBaseMethod(_thingCompTickRareMethod, _thingCompTickRareBaseIsTrivial, ref _thingCompTickRareState);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool CanSkipInheritedBaseThingCompTickLong()
|
||||
=> _canSkipInheritedBaseThingCompTickLong.Value;
|
||||
=> CanSkipBaseMethod(_thingCompTickLongMethod, _thingCompTickLongBaseIsTrivial, ref _thingCompTickLongState);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool CanSkipInheritedBaseHediffCompPostTick()
|
||||
=> _canSkipInheritedBaseHediffCompPostTick.Value;
|
||||
=> CanSkipBaseMethod(_hediffCompPostTickMethod, _hediffCompPostTickBaseIsTrivial,
|
||||
ref _hediffCompPostTickState);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool CanSkipInheritedBaseHediffCompPostTickInterval()
|
||||
=> _canSkipInheritedBaseHediffCompPostTickInterval.Value;
|
||||
=> CanSkipBaseMethod(_hediffCompPostTickIntervalMethod, _hediffCompPostTickIntervalBaseIsTrivial,
|
||||
ref _hediffCompPostTickIntervalState);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool CanSkipBaseMethod(MethodBase method, bool isTrivial, ref BasePatchState state)
|
||||
{
|
||||
if (!isTrivial)
|
||||
return false;
|
||||
|
||||
var tick = Find.TickManager?.TicksGame ?? int.MinValue;
|
||||
if (!state.HasChecked || state.CheckedTick != tick)
|
||||
{
|
||||
state.CanSkip = !HasHarmonyPatches(method);
|
||||
state.CheckedTick = tick;
|
||||
state.HasChecked = true;
|
||||
}
|
||||
|
||||
return state.CanSkip;
|
||||
}
|
||||
|
||||
private static bool InheritsThingCompTick(Type type)
|
||||
=> AccessTools.Method(type, nameof(ThingComp.CompTick))?.DeclaringType == typeof(ThingComp);
|
||||
|
||||
Reference in New Issue
Block a user