Added stat caching, fixed all the bugs
Added RitualObligationTriggers analyzer category, Fixed defs from other mods with broken market value breaking fish's storage patches, Fixed storage caches not updating for quality, rotting and similar changes to stored things, Fixed storage caches not updating capacity when reinstalling storage, Fixed prison labor compatibility, Improved multiplayer compatibility, Fixed ideology style dominance and altar sharing patches throwing errors instead of defaulting to disabled when not having ideology, Fixed compatibility with RIMMSqol's world pawn GC patch by disabling that patch, Fixed rare threading issues throwing errors on startup
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace PerformanceFish.Hauling;
|
||||
|
||||
public record struct HaulDestinationManagerCache
|
||||
public record struct HaulDestinationManagerCache()
|
||||
{
|
||||
public static readonly int StoragePriorityCount = Enum.GetValues(typeof(StoragePriority)).Length;
|
||||
|
||||
@@ -24,8 +24,4 @@ public record struct HaulDestinationManagerCache
|
||||
|
||||
PriorityChanged?.Invoke(manager);
|
||||
}
|
||||
|
||||
public HaulDestinationManagerCache()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -31,8 +31,11 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
|
||||
|
||||
public static void Postfix(HaulDestinationManager __instance, IHaulDestination haulDestination)
|
||||
{
|
||||
if (haulDestination is ISlotGroupParent)
|
||||
__instance.Cache().OnPriorityChanged(__instance);
|
||||
if (haulDestination is not ISlotGroupParent slotGroupParent)
|
||||
return;
|
||||
|
||||
__instance.Cache().OnPriorityChanged(__instance);
|
||||
slotGroupParent.GetSlotGroup().NotifyCellCountChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +49,11 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
|
||||
|
||||
public static void Postfix(HaulDestinationManager __instance, IHaulDestination haulDestination)
|
||||
{
|
||||
if (haulDestination is ISlotGroupParent)
|
||||
__instance.Cache().OnPriorityChanged(__instance);
|
||||
if (haulDestination is not ISlotGroupParent slotGroupParent)
|
||||
return;
|
||||
|
||||
__instance.Cache().OnPriorityChanged(__instance);
|
||||
slotGroupParent.GetSlotGroup().ResetDistricts();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,18 +18,32 @@ public sealed class StorageSettingsPatches : ClassWithFishPatches
|
||||
public override string Description { get; }
|
||||
= "Caches results of storage settings checks for things when hauling";
|
||||
|
||||
protected internal override void OnPatchingCompleted()
|
||||
=> Events.ThingEvents.QualityChanging += NotifyQualityChanging;
|
||||
|
||||
public static void NotifyQualityChanging(Thing thing)
|
||||
{
|
||||
if (!thing.IsItem() || thing.TryGetMap() is not { } map)
|
||||
return;
|
||||
|
||||
var haulDestinations = map.haulDestinationManager.AllHaulDestinationsListForReading;
|
||||
for (var i = haulDestinations.Count; i-- > 0;)
|
||||
haulDestinations[i].GetStoreSettings().Cache().AllowedToAccept.Remove(thing.thingIDNumber);
|
||||
}
|
||||
|
||||
public override Expression<Action> TargetMethod { get; }
|
||||
= static () => default(StorageSettings)!.AllowedToAccept(default(Thing));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool Prefix(StorageSettings __instance, Thing t, ref bool __result, out bool __state)
|
||||
{
|
||||
var cachedAllowedToAcceptValue = __instance.Cache().AllowedToAccept.GetOrAdd(t.thingIDNumber);
|
||||
ref var allowedToAcceptCacheValue
|
||||
= ref __instance.Cache().AllowedToAccept.GetOrAddReference(t.thingIDNumber);
|
||||
|
||||
if (StorageSettingsCache.IsDirty(cachedAllowedToAcceptValue))
|
||||
if (allowedToAcceptCacheValue.Dirty)
|
||||
return __state = true;
|
||||
|
||||
__result = cachedAllowedToAcceptValue.AsBool() /*&& CapacityAllows(__instance, t)*/;
|
||||
__result = allowedToAcceptCacheValue.Value;
|
||||
|
||||
return __state = false;
|
||||
}
|
||||
@@ -45,7 +59,8 @@ public sealed class StorageSettingsPatches : ClassWithFishPatches
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void UpdateCache(StorageSettings __instance, Thing t, bool __result)
|
||||
=> __instance.Cache().Update(t.thingIDNumber, __result && t is { def: not null, thingIDNumber: not -1 });
|
||||
=> __instance.Cache().AllowedToAccept.GetOrAddReference(t.thingIDNumber)
|
||||
.Update(t, __result && t is { def: not null, thingIDNumber: not -1 });
|
||||
}
|
||||
|
||||
public sealed class TryNotifyChanged_Patch : FishPatch
|
||||
@@ -107,9 +122,9 @@ public sealed class StorageSettingsPatches : ClassWithFishPatches
|
||||
}
|
||||
}
|
||||
|
||||
public record struct StorageSettingsCache
|
||||
public record struct StorageSettingsCache()
|
||||
{
|
||||
public FishTable<int, int> AllowedToAccept = new();
|
||||
public FishTable<int, AllowedToAcceptCacheValue> AllowedToAccept = new();
|
||||
|
||||
private Thing? _parent;
|
||||
|
||||
@@ -129,15 +144,10 @@ public sealed class StorageSettingsPatches : ClassWithFishPatches
|
||||
|
||||
public List<Thing> StoredThingsOfDef(ThingDef def) => _storedThingsByDef.GetOrAdd(def.shortHash);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsDirty(int allowedToAcceptValue) => allowedToAcceptValue == int.MaxValue;
|
||||
|
||||
public void Update(int thingIDNumber, bool allowedToAccept)
|
||||
=> AllowedToAccept[thingIDNumber] = allowedToAccept.AsInt();
|
||||
|
||||
public void Initialize(Thing? slotGroupParent)
|
||||
{
|
||||
_parent = slotGroupParent;
|
||||
_storedThingCount = 0;
|
||||
_storedThingsByDef.Clear();
|
||||
AllowedToAccept.Clear();
|
||||
_lwmProps = slotGroupParent?.TryGetLwmCompProperties();
|
||||
@@ -177,8 +187,27 @@ public sealed class StorageSettingsPatches : ClassWithFishPatches
|
||||
|
||||
SettingsChanged?.Invoke(storageSettings);
|
||||
}
|
||||
}
|
||||
|
||||
public StorageSettingsCache() => AllowedToAccept.ValueInitializer = static _ => int.MaxValue;
|
||||
public record struct AllowedToAcceptCacheValue()
|
||||
{
|
||||
private int
|
||||
_value = int.MaxValue,
|
||||
_nextUpdateTick = -2;
|
||||
|
||||
public bool Value => _value.AsBool();
|
||||
|
||||
public bool Dirty
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => (_value == int.MaxValue) | TickHelper.Past(_nextUpdateTick);
|
||||
}
|
||||
|
||||
public void Update(Thing thing, bool allowedToAccept)
|
||||
{
|
||||
_value = allowedToAccept.AsInt();
|
||||
_nextUpdateTick = TickHelper.Add(512, thing.thingIDNumber, 128);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Debug
|
||||
|
||||
@@ -113,11 +113,7 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
||||
var thingEvents = thing.Events();
|
||||
|
||||
if (thing is ISlotGroupParent)
|
||||
{
|
||||
thingEvents.Spawned += NotifySlotGroupCellCountChanged;
|
||||
thingEvents.Spawned += StorageSettingsPatches.InitializeSlotGroupParent;
|
||||
thingEvents.DeSpawned += NotifySlotGroupCellCountChanged;
|
||||
}
|
||||
|
||||
if (!thing.IsItem())
|
||||
return;
|
||||
@@ -126,12 +122,6 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
||||
thingEvents.DeregisteredAtThingGrid += TryNotifyLostThing;
|
||||
}
|
||||
|
||||
public static void NotifySlotGroupCellCountChanged(Thing slotGroupParent, Map map)
|
||||
=> NotifySlotGroupCellCountChanged(slotGroupParent);
|
||||
|
||||
public static void NotifySlotGroupCellCountChanged(Thing slotGroupParent)
|
||||
=> slotGroupParent.GetSlotGroup()?.NotifyCellCountChanged();
|
||||
|
||||
public static void TryNotifyReceivedThing(Thing thing, Map map, in IntVec3 cell)
|
||||
{
|
||||
if (cell.GetSlotGroupParent(map) is { } parent and Thing)
|
||||
@@ -370,13 +360,27 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void TryRemoveFromListerHaulables(Thing t, StoragePriority currentPriority)
|
||||
{
|
||||
if (ModCompatibility.ActiveMods.Multiplayer | !HaulablesTickPatchActive)
|
||||
return;
|
||||
|
||||
if (t.IsInAnyStorage() /*t.IsInValidStorage()*/ && t.TryGetMapHeld() is { } map)
|
||||
map.listerHaulables.TryRemoveDirectly(t);
|
||||
|
||||
map.listerHaulables.Cache().ThingsQueuedToRemove.Add(t);
|
||||
|
||||
// remove for any storage instead of only valid storage to prevent further haul attempts until the next
|
||||
// automatic ListerHaulablesTick cycle
|
||||
}
|
||||
|
||||
private static int _haulablesTickPatchActive = int.MaxValue;
|
||||
|
||||
private static bool HaulablesTickPatchActive
|
||||
=> _haulablesTickPatchActive != int.MaxValue
|
||||
? _haulablesTickPatchActive.AsBool()
|
||||
: UpdateHaulablesTickPatchActive();
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static bool UpdateHaulablesTickPatchActive()
|
||||
=> (_haulablesTickPatchActive = Get<Haulables.TickPatch>().IsActive.AsInt()).AsBool();
|
||||
|
||||
public static class Debug
|
||||
{
|
||||
[Conditional("STORAGE_GROUP_DEBUG")]
|
||||
|
||||
Reference in New Issue
Block a user