diff --git a/1.4/Assemblies/PerformanceFish.dll b/1.4/Assemblies/PerformanceFish.dll index ae4dc30..369aadb 100644 Binary files a/1.4/Assemblies/PerformanceFish.dll and b/1.4/Assemblies/PerformanceFish.dll differ diff --git a/1.4/Assemblies/PerformanceFish.pdb b/1.4/Assemblies/PerformanceFish.pdb index 03d1be7..0967816 100644 Binary files a/1.4/Assemblies/PerformanceFish.pdb and b/1.4/Assemblies/PerformanceFish.pdb differ diff --git a/Source/PerformanceFish/Hauling/StoreUtilityPrepatches.cs b/Source/PerformanceFish/Hauling/StoreUtilityPrepatches.cs index 8817142..43efe3c 100644 --- a/Source/PerformanceFish/Hauling/StoreUtilityPrepatches.cs +++ b/Source/PerformanceFish/Hauling/StoreUtilityPrepatches.cs @@ -257,6 +257,10 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches var closestDistSquared = (float)int.MaxValue; var closestSlot = IntVec3.Invalid; + var hadToFixCache = false; + + StartOfLoop: + var listInPriorityOrderCount = listInPriorityOrder.Count; var groupCountByPriority = GetCachedGroupCountByPriority(haulDestinationManager); var i = 0; for (var priorityGroupIndex = groupCountByPriority.Length; priorityGroupIndex-- > 0;) @@ -274,6 +278,9 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches while (groupsOfPriorityCount-- > 0) { + if (i >= listInPriorityOrderCount) + goto FixCache; + var slotGroup = listInPriorityOrder[i++]; int otherGroupMembers; var storageGroup = slotGroup.TryGetStorageGroup(); @@ -303,12 +310,16 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches if (otherGroupMembers <= 0) break; + if (i >= listInPriorityOrderCount) + goto FixCache; + otherGroupMembers--; slotGroup = listInPriorityOrder[i++]; } } } + Result: if (!closestSlot.IsValid) { foundCell = IntVec3.Invalid; @@ -317,6 +328,39 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches foundCell = closestSlot; return true; + + FixCache: + if (hadToFixCache) + { + LogErrorForFailedTryFindBestBetterStoreCellForAttempt(t, carrier, map, currentPriority, faction, + closestSlot); + goto Result; + } + else + { + hadToFixCache = true; + } + + UpdateCache(haulDestinationManager); + goto StartOfLoop; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LogErrorForFailedTryFindBestBetterStoreCellForAttempt(Thing t, Pawn carrier, Map? map, + StoragePriority currentPriority, Faction faction, IntVec3 closestSlot) + => Log.Error($"Performance Fish's TryFindBestBetterStoreCellFor patch failed to compute accurate " + + $"results after a recache attempt for thing '{t}', pawn '{carrier}', map '{ + map}', currentPriority '{currentPriority}', faction '{ + faction}'. The last found cell was '{ + closestSlot}'. It is most likely incompatible with something in the mod list.\n{ + Debug.GetStorageGroupInfo(map?.haulDestinationManager?.AllGroupsListInPriorityOrder)}"); + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void UpdateCache(HaulDestinationManager haulDestinationManager) + { + haulDestinationManager.AllGroupsListInPriorityOrder.InsertionSort(HaulDestinationManager + .CompareSlotGroupPrioritiesDescending); + haulDestinationManager.Cache().OnPriorityChanged(haulDestinationManager); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -355,13 +399,24 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches public static void LogStuff(List listInPriorityOrder) { LoggedOnce = true; - var storageGroups = listInPriorityOrder.Select(static slotGroup => slotGroup.TryGetStorageGroup()) + Log.Message(GetStorageGroupInfo(listInPriorityOrder)); + } + + public static string GetStorageGroupInfo(List? slotGroupsInPriorityOrder) + { + if (slotGroupsInPriorityOrder is null) + return string.Empty; + + var storageGroups = slotGroupsInPriorityOrder.Select(static slotGroup => slotGroup.TryGetStorageGroup()) .Where(Is.NotNull).Distinct().ToList(); - Log.Message($"SlotGroup count: {listInPriorityOrder.Count}, StorageGroup count: { - storageGroups.Count}, slotGroups in storage groups: { - storageGroups.Select(static group => group!.MemberCount).Sum()}, outside of storage groups: { - listInPriorityOrder.Select(static slotGroup => slotGroup.TryGetStorageGroup()) - .Where(Is.Null).Count()}"); + + return StringHelper.Resolve($"SlotGroup count: { + slotGroupsInPriorityOrder.Count}, StorageGroup count: { + storageGroups.Count}, slotGroups in storage groups: {storageGroups + .Select(static group => group!.MemberCount) + .Sum()}, outside of storage groups: {slotGroupsInPriorityOrder + .Select(static slotGroup => slotGroup.TryGetStorageGroup()) + .Where(Is.Null).Count()}"); } public static bool LoggedOnce; diff --git a/Source/PerformanceFish/PerformanceFish.csproj b/Source/PerformanceFish/PerformanceFish.csproj index f564521..749a533 100644 --- a/Source/PerformanceFish/PerformanceFish.csproj +++ b/Source/PerformanceFish/PerformanceFish.csproj @@ -17,7 +17,7 @@ enable True v1.4 - 0.3.999.91 + 0.3.999.92 1701;1702;IL2121;CS8500;CS9082;CA1000;CA1002;CA1003;CA1707;CA1010;CA1715;CA1716;CA1724;CA1031;CA1033; CA1034;CA1043;CA1051;CA1305;CA1310;CA1710;CA1711;CA1810;CA1812;CA1819;CA1851;CA2002;CA5394;CA1725;CA1062