Fixed rare TryFindBestBetterStoreCellFor errors, added better exception handling for drawing errors thrown by other mods
Those log messages now include things and the position where drawing fails Plant printing was slightly improved further too, correctly handling theoretical hydroponics of sizes above 20 now
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -15,6 +15,7 @@
|
|||||||
<li>Ludeon.RimWorld.Royalty</li>
|
<li>Ludeon.RimWorld.Royalty</li>
|
||||||
<li>Ludeon.RimWorld.Ideology</li>
|
<li>Ludeon.RimWorld.Ideology</li>
|
||||||
<li>Ludeon.RimWorld.Biotech</li>
|
<li>Ludeon.RimWorld.Biotech</li>
|
||||||
|
<li>Ludeon.RimWorld.Anomaly</li>
|
||||||
<li>UnlimitedHugs.HugsLib</li>
|
<li>UnlimitedHugs.HugsLib</li>
|
||||||
<li>OskarPotocki.VanillaFactionsExpanded.Core</li>
|
<li>OskarPotocki.VanillaFactionsExpanded.Core</li>
|
||||||
<li>Taranchuk.PerformanceOptimizer</li>
|
<li>Taranchuk.PerformanceOptimizer</li>
|
||||||
|
|||||||
@@ -24,4 +24,6 @@ public record struct CellIndex(int Value)
|
|||||||
public bool IsFogged(Map map) => map.fogGrid.fogGrid[Value];
|
public bool IsFogged(Map map) => map.fogGrid.fogGrid[Value];
|
||||||
|
|
||||||
public float GetSnowDepth(Map map) => map.snowGrid.depthGrid[Value];
|
public float GetSnowDepth(Map map) => map.snowGrid.depthGrid[Value];
|
||||||
|
|
||||||
|
public Building? GetEdifice(Map map) => map.edificeGrid[Value];
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<RootNamespace>PerformanceFish</RootNamespace>
|
<RootNamespace>PerformanceFish</RootNamespace>
|
||||||
<AssemblyName>PerformanceFish</AssemblyName>
|
<AssemblyName>PerformanceFish</AssemblyName>
|
||||||
<Authors>bradson</Authors>
|
<Authors>bradson</Authors>
|
||||||
<Version>0.6.1.1</Version>
|
<Version>0.6.2.0</Version>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<TargetFramework>net48</TargetFramework>
|
<TargetFramework>net48</TargetFramework>
|
||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
|
|||||||
@@ -11,16 +11,15 @@ public record struct HaulDestinationManagerCache()
|
|||||||
|
|
||||||
public event Action<HaulDestinationManager>? PriorityChanged;
|
public event Action<HaulDestinationManager>? PriorityChanged;
|
||||||
|
|
||||||
public int[] GroupCountByPriority = new int[StoragePriorityCount];
|
public readonly int[] GroupCountByPriority = new int[StoragePriorityCount];
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
public void OnPriorityChanged(HaulDestinationManager manager)
|
public void OnPriorityChanged(HaulDestinationManager manager)
|
||||||
{
|
{
|
||||||
var slotGroupsByPriority = manager.AllGroupsListInPriorityOrder;
|
GroupCountByPriority.Clear();
|
||||||
|
manager.AllGroupsListInPriorityOrder.UnwrapArray(out var slotGroupsByPriority, out var slotGroupCount);
|
||||||
Array.Clear(GroupCountByPriority, 0, GroupCountByPriority.Length);
|
for (var i = slotGroupCount; --i >= 0;)
|
||||||
for (var i = slotGroupsByPriority.Count; i-- > 0;)
|
GroupCountByPriority[(int)slotGroupsByPriority.UnsafeLoad(i).Settings.Priority]++;
|
||||||
GroupCountByPriority[(int)slotGroupsByPriority[i].Settings.Priority]++;
|
|
||||||
|
|
||||||
PriorityChanged?.Invoke(manager);
|
PriorityChanged?.Invoke(manager);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
|
|||||||
= AccessTools.DeclaredMethod(typeof(HaulDestinationManager),
|
= AccessTools.DeclaredMethod(typeof(HaulDestinationManager),
|
||||||
nameof(HaulDestinationManager.Notify_HaulDestinationChangedPriority));
|
nameof(HaulDestinationManager.Notify_HaulDestinationChangedPriority));
|
||||||
|
|
||||||
|
public static void Prefix(HaulDestinationManager __instance) => __instance.RecalculateStorageGroupMemberCount();
|
||||||
|
|
||||||
public static void Postfix(HaulDestinationManager __instance)
|
public static void Postfix(HaulDestinationManager __instance)
|
||||||
=> __instance.Cache().OnPriorityChanged(__instance);
|
=> __instance.Cache().OnPriorityChanged(__instance);
|
||||||
}
|
}
|
||||||
@@ -29,6 +31,12 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
|
|||||||
= AccessTools.DeclaredMethod(typeof(HaulDestinationManager),
|
= AccessTools.DeclaredMethod(typeof(HaulDestinationManager),
|
||||||
nameof(HaulDestinationManager.AddHaulDestination));
|
nameof(HaulDestinationManager.AddHaulDestination));
|
||||||
|
|
||||||
|
public static void Prefix(HaulDestinationManager __instance, IHaulDestination haulDestination)
|
||||||
|
{
|
||||||
|
if (haulDestination is IStorageGroupMember { Group: { } group })
|
||||||
|
group.SpawnedMemberCount()++;
|
||||||
|
}
|
||||||
|
|
||||||
public static void Postfix(HaulDestinationManager __instance, IHaulDestination haulDestination)
|
public static void Postfix(HaulDestinationManager __instance, IHaulDestination haulDestination)
|
||||||
{
|
{
|
||||||
if (haulDestination is not ISlotGroupParent slotGroupParent)
|
if (haulDestination is not ISlotGroupParent slotGroupParent)
|
||||||
@@ -47,6 +55,12 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
|
|||||||
= AccessTools.DeclaredMethod(typeof(HaulDestinationManager),
|
= AccessTools.DeclaredMethod(typeof(HaulDestinationManager),
|
||||||
nameof(HaulDestinationManager.RemoveHaulDestination));
|
nameof(HaulDestinationManager.RemoveHaulDestination));
|
||||||
|
|
||||||
|
public static void Prefix(HaulDestinationManager __instance, IHaulDestination haulDestination)
|
||||||
|
{
|
||||||
|
if (haulDestination is IStorageGroupMember { Group: { } group })
|
||||||
|
group.SpawnedMemberCount()--;
|
||||||
|
}
|
||||||
|
|
||||||
public static void Postfix(HaulDestinationManager __instance, IHaulDestination haulDestination)
|
public static void Postfix(HaulDestinationManager __instance, IHaulDestination haulDestination)
|
||||||
{
|
{
|
||||||
if (haulDestination is not ISlotGroupParent slotGroupParent)
|
if (haulDestination is not ISlotGroupParent slotGroupParent)
|
||||||
@@ -76,8 +90,8 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
|
|||||||
if (__result != 0)
|
if (__result != 0)
|
||||||
return __result;
|
return __result;
|
||||||
|
|
||||||
var storageSettingsGroupA = a.TryGetStorageGroup();
|
var storageSettingsGroupA = a.StorageGroup;
|
||||||
var storageSettingsGroupB = b.TryGetStorageGroup();
|
var storageSettingsGroupB = b.StorageGroup;
|
||||||
|
|
||||||
return storageSettingsGroupA == null
|
return storageSettingsGroupA == null
|
||||||
? storageSettingsGroupB == null
|
? storageSettingsGroupB == null
|
||||||
@@ -91,7 +105,7 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
|
|||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
public static int CompareStorageSettingsGroups(StorageGroup a, StorageGroup b)
|
public static int CompareStorageSettingsGroups(StorageGroup a, StorageGroup b)
|
||||||
{
|
{
|
||||||
var result = b.MemberCount.CompareTo(a.MemberCount);
|
var result = b.SpawnedMemberCount().CompareTo(a.SpawnedMemberCount());
|
||||||
return result != 0 ? result : a.loadID.CompareTo(b.loadID);
|
return result != 0 ? result : a.loadID.CompareTo(b.loadID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,21 @@ public static class StorageExtensions
|
|||||||
? storage.TrueItemsPerCell() * cellCount
|
? storage.TrueItemsPerCell() * cellCount
|
||||||
: cellCount;
|
: cellCount;
|
||||||
|
|
||||||
|
public static void RecalculateStorageGroupMemberCount(this HaulDestinationManager haulDestinationManager)
|
||||||
|
{
|
||||||
|
haulDestinationManager.map.storageGroups.groups.UnwrapArray(out var storageGroups, out var storageGroupCount);
|
||||||
|
for (var i = storageGroupCount; --i >= 0;)
|
||||||
|
storageGroups.UnsafeLoad(i).SpawnedMemberCount() = 0;
|
||||||
|
|
||||||
|
haulDestinationManager.AllGroupsListInPriorityOrder.UnwrapArray(out var slotGroupsByPriority,
|
||||||
|
out var slotGroupCount);
|
||||||
|
for (var i = slotGroupCount; --i >= 0;)
|
||||||
|
{
|
||||||
|
if (slotGroupsByPriority.UnsafeLoad(i).StorageGroup is { } storageGroup)
|
||||||
|
storageGroup.SpawnedMemberCount()++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static StorageExtensions()
|
static StorageExtensions()
|
||||||
{
|
{
|
||||||
LwmCompCacheValue.EnsureInitialized();
|
LwmCompCacheValue.EnsureInitialized();
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
|||||||
|
|
||||||
#if STORAGE_GROUP_DEBUG
|
#if STORAGE_GROUP_DEBUG
|
||||||
if (!Debug.LoggedOnce && !(Current.Game?.tickManager?.Paused ?? true))
|
if (!Debug.LoggedOnce && !(Current.Game?.tickManager?.Paused ?? true))
|
||||||
Debug.LogStuff(listInPriorityOrder);
|
Debug.LogStuff(haulDestinationManager);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var foundPriority = currentPriority;
|
var foundPriority = currentPriority;
|
||||||
@@ -287,10 +287,10 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
|||||||
|
|
||||||
var slotGroup = listInPriorityOrder[i++];
|
var slotGroup = listInPriorityOrder[i++];
|
||||||
int otherGroupMembers;
|
int otherGroupMembers;
|
||||||
var storageGroup = slotGroup.TryGetStorageGroup();
|
var storageGroup = slotGroup.StorageGroup;
|
||||||
if (storageGroup != null)
|
if (storageGroup != null)
|
||||||
{
|
{
|
||||||
otherGroupMembers = storageGroup.MemberCount - 1;
|
otherGroupMembers = storageGroup.SpawnedMemberCount() - 1;
|
||||||
Debug.VerifyStorageGroup(otherGroupMembers, listInPriorityOrder, i, storageGroup);
|
Debug.VerifyStorageGroup(otherGroupMembers, listInPriorityOrder, i, storageGroup);
|
||||||
|
|
||||||
groupsOfPriorityCount -= otherGroupMembers;
|
groupsOfPriorityCount -= otherGroupMembers;
|
||||||
@@ -334,19 +334,18 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
FixCache:
|
FixCache:
|
||||||
if (hadToFixCache)
|
if (!hadToFixCache)
|
||||||
|
{
|
||||||
|
hadToFixCache = true;
|
||||||
|
UpdateCache(haulDestinationManager);
|
||||||
|
goto StartOfLoop;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
LogErrorForFailedTryFindBestBetterStoreCellForAttempt(t, carrier, map, currentPriority, faction,
|
LogErrorForFailedTryFindBestBetterStoreCellForAttempt(t, carrier, map, currentPriority, faction,
|
||||||
closestSlot);
|
closestSlot);
|
||||||
goto Result;
|
goto Result;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
hadToFixCache = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateCache(haulDestinationManager);
|
|
||||||
goto StartOfLoop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
@@ -357,11 +356,29 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
|||||||
map}', currentPriority '{currentPriority}', faction '{
|
map}', currentPriority '{currentPriority}', faction '{
|
||||||
faction}'. The last found cell was '{
|
faction}'. The last found cell was '{
|
||||||
closestSlot}'. It is most likely incompatible with something in the mod list.\n{
|
closestSlot}'. It is most likely incompatible with something in the mod list.\n{
|
||||||
Debug.GetStorageGroupInfo(map?.haulDestinationManager?.AllGroupsListInPriorityOrder)}");
|
Debug.GetStorageGroupInfo(map?.haulDestinationManager)}");
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
public static void UpdateCache(HaulDestinationManager haulDestinationManager)
|
public static void UpdateCache(HaulDestinationManager haulDestinationManager)
|
||||||
{
|
{
|
||||||
|
var storageGroups = haulDestinationManager.map.storageGroups.groups;
|
||||||
|
for (var i = storageGroups.Count; i-- > 0;)
|
||||||
|
{
|
||||||
|
var group = storageGroups[i];
|
||||||
|
var members = group.members;
|
||||||
|
for (var j = members.Count; j-- > 0;)
|
||||||
|
{
|
||||||
|
var member = members[j];
|
||||||
|
if (member.Group != group)
|
||||||
|
members.RemoveAt(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (members.Count == 0)
|
||||||
|
storageGroups.RemoveAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
haulDestinationManager.RecalculateStorageGroupMemberCount();
|
||||||
|
|
||||||
haulDestinationManager.AllGroupsListInPriorityOrder.InsertionSort(HaulDestinationManager
|
haulDestinationManager.AllGroupsListInPriorityOrder.InsertionSort(HaulDestinationManager
|
||||||
.CompareSlotGroupPrioritiesDescending);
|
.CompareSlotGroupPrioritiesDescending);
|
||||||
haulDestinationManager.Cache().OnPriorityChanged(haulDestinationManager);
|
haulDestinationManager.Cache().OnPriorityChanged(haulDestinationManager);
|
||||||
@@ -404,36 +421,36 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
|||||||
for (var b = otherGroupMembers; b-- > 0;)
|
for (var b = otherGroupMembers; b-- > 0;)
|
||||||
{
|
{
|
||||||
var otherSlotGroup = listInPriorityOrder[i + b];
|
var otherSlotGroup = listInPriorityOrder[i + b];
|
||||||
if (otherSlotGroup.TryGetStorageGroup() == storageGroup)
|
if (otherSlotGroup.StorageGroup == storageGroup)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Log.Error($"Incorrect haul destination order! Storage '{
|
Log.Error($"Incorrect haul destination order! Storage '{
|
||||||
otherSlotGroup.parent}' was expected to have Storage group '{storageGroup}', but had '{
|
otherSlotGroup.parent}' was expected to have Storage group '{storageGroup}', but had '{
|
||||||
otherSlotGroup.TryGetStorageGroup().ToStringSafe()}' instead");
|
otherSlotGroup.StorageGroup.ToStringSafe()}' instead");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Conditional("STORAGE_GROUP_DEBUG")]
|
[Conditional("STORAGE_GROUP_DEBUG")]
|
||||||
public static void LogStuff(List<SlotGroup> listInPriorityOrder)
|
public static void LogStuff(HaulDestinationManager haulDestinationManager)
|
||||||
{
|
{
|
||||||
LoggedOnce = true;
|
LoggedOnce = true;
|
||||||
Log.Message(GetStorageGroupInfo(listInPriorityOrder));
|
Log.Message(GetStorageGroupInfo(haulDestinationManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetStorageGroupInfo(List<SlotGroup>? slotGroupsInPriorityOrder)
|
public static string GetStorageGroupInfo(HaulDestinationManager? haulDestinationManager)
|
||||||
{
|
{
|
||||||
|
var slotGroupsInPriorityOrder = haulDestinationManager?.AllGroupsListInPriorityOrder;
|
||||||
if (slotGroupsInPriorityOrder is null)
|
if (slotGroupsInPriorityOrder is null)
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
||||||
var storageGroups = slotGroupsInPriorityOrder.Select(static slotGroup => slotGroup.TryGetStorageGroup())
|
var storageGroups = haulDestinationManager!.map.storageGroups.groups;
|
||||||
.Where(Is.NotNull).Distinct().ToList();
|
|
||||||
|
|
||||||
return StringHelper.Resolve($"SlotGroup count: {
|
return StringHelper.Resolve($"SlotGroup count: {
|
||||||
slotGroupsInPriorityOrder.Count}, StorageGroup count: {
|
slotGroupsInPriorityOrder.Count}, StorageGroup count: {
|
||||||
storageGroups.Count}, slotGroups in storage groups: {storageGroups
|
storageGroups.Count}, slotGroups in storage groups: {storageGroups
|
||||||
.Select(static group => group!.MemberCount)
|
.Select(static group => group!.SpawnedMemberCount())
|
||||||
.Sum()}, outside of storage groups: {slotGroupsInPriorityOrder
|
.Sum()}, outside of storage groups: {slotGroupsInPriorityOrder
|
||||||
.Select(static slotGroup => slotGroup.TryGetStorageGroup())
|
.Select(static slotGroup => slotGroup.StorageGroup)
|
||||||
.Where(Is.Null).Count()}");
|
.Where(Is.Null).Count()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ public static class PrepatcherFields
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static extern ref StorageSettingsPatches.StorageSettingsCache Cache(this StorageSettings storageSettings);
|
public static extern ref StorageSettingsPatches.StorageSettingsCache Cache(this StorageSettings storageSettings);
|
||||||
|
|
||||||
|
[PrepatcherField]
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static extern ref int SpawnedMemberCount(this StorageGroup storageGroup);
|
||||||
|
|
||||||
#if V1_4
|
#if V1_4
|
||||||
[PrepatcherField]
|
[PrepatcherField]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public sealed class DynamicDrawManagerPatches : ClassWithFishPrepatches
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error("Exception drawing dynamic things: " + ex);
|
Log.Error($"Exception drawing dynamic things for map '{instance.map}':\n{ex}");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -92,7 +92,7 @@ public sealed class DynamicDrawManagerPatches : ClassWithFishPrepatches
|
|||||||
ThingsToDraw.Add(drawThing);
|
ThingsToDraw.Add(drawThing);
|
||||||
|
|
||||||
if (!DebugViewSettings.singleThreadedDrawing)
|
if (!DebugViewSettings.singleThreadedDrawing)
|
||||||
drawThing.DynamicDrawPhase(DrawPhase.EnsureInitialized);
|
EnsureInitialized(drawThing);
|
||||||
}
|
}
|
||||||
else if (drawThing is Pawn pawn && checkShadows && shadowViewRect.Contains(drawThing.Position))
|
else if (drawThing is Pawn pawn && checkShadows && shadowViewRect.Contains(drawThing.Position))
|
||||||
{
|
{
|
||||||
@@ -102,6 +102,18 @@ public sealed class DynamicDrawManagerPatches : ClassWithFishPrepatches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void EnsureInitialized(Thing drawThing)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
drawThing.DynamicDrawPhase(DrawPhase.EnsureInitialized);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.EnsureInitializedException(drawThing, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void DrawShadowsNow()
|
public static void DrawShadowsNow()
|
||||||
{
|
{
|
||||||
PawnShadowsToDraw.UnwrapArray(out var pawnShadowsToDraw, out var pawnShadowsToDrawCount);
|
PawnShadowsToDraw.UnwrapArray(out var pawnShadowsToDraw, out var pawnShadowsToDrawCount);
|
||||||
@@ -115,7 +127,7 @@ public sealed class DynamicDrawManagerPatches : ClassWithFishPrepatches
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error($"Exception drawing shadow for '{pawn}': {ex}");
|
Logging.DrawShadowException(pawn, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +145,7 @@ public sealed class DynamicDrawManagerPatches : ClassWithFishPrepatches
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error($"Exception drawing '{drawThing}': {ex}");
|
Logging.DrawException(drawThing, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +193,38 @@ public sealed class DynamicDrawManagerPatches : ClassWithFishPrepatches
|
|||||||
{
|
{
|
||||||
public Thing[] thingsToDraw = Array.Empty<Thing>();
|
public Thing[] thingsToDraw = Array.Empty<Thing>();
|
||||||
|
|
||||||
public void Execute(int index) => thingsToDraw[index].DynamicDrawPhase(DrawPhase.ParallelPreDraw);
|
public void Execute(int index)
|
||||||
|
{
|
||||||
|
var thing = thingsToDraw[index];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
thing.DynamicDrawPhase(DrawPhase.ParallelPreDraw);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.ParallelPreDrawException(thing, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Logging
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
public static void EnsureInitializedException(Thing drawThing, Exception ex)
|
||||||
|
=> Log.Error($"Exception in EnsureInitialized for '{drawThing}' at cell {
|
||||||
|
drawThing.PositionHeld}:\n{ex}");
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
public static void DrawException(Thing drawThing, Exception ex)
|
||||||
|
=> Log.Error($"Exception drawing '{drawThing}' at cell {drawThing.PositionHeld}:\n{ex}");
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
public static void DrawShadowException(Pawn pawn, Exception ex)
|
||||||
|
=> Log.Error($"Exception drawing shadow for '{pawn}' at cell {pawn.PositionHeld}:\n{ex}");
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
public static void ParallelPreDrawException(Thing thing, Exception ex)
|
||||||
|
=> Log.Error($"Exception in ParallelPreDraw for '{thing}' at cell {thing.PositionHeld}:\n{ex}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ namespace PerformanceFish.Rendering;
|
|||||||
|
|
||||||
public sealed class PrintImprovements : ClassWithFishPrepatches
|
public sealed class PrintImprovements : ClassWithFishPrepatches
|
||||||
{
|
{
|
||||||
|
public const float
|
||||||
|
X_ADJUSTMENT = 0.0005f,
|
||||||
|
Y_ADJUSTMENT = 0.0045f,
|
||||||
|
COMBINED_ADJUSTMENT = X_ADJUSTMENT + Y_ADJUSTMENT;
|
||||||
|
|
||||||
public sealed class PrintPlanePatch : FishPrepatch
|
public sealed class PrintPlanePatch : FishPrepatch
|
||||||
{
|
{
|
||||||
public override string? Description { get; }
|
public override string? Description { get; }
|
||||||
@@ -57,19 +62,19 @@ public sealed class PrintImprovements : ClassWithFishPrepatches
|
|||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static float TopLeftAdjustment(in Vector2 size)
|
public static float TopLeftAdjustment(in Vector2 size)
|
||||||
=> (size.y * 0.0048f) + (size.x * 0.0002f);
|
=> (size.y * Y_ADJUSTMENT) + (size.x * X_ADJUSTMENT);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static float TopRightAdjustment(in Vector2 size)
|
public static float TopRightAdjustment(in Vector2 size)
|
||||||
=> (size.y * 0.0048f) - (size.x * 0.0002f);
|
=> (size.y * Y_ADJUSTMENT) - (size.x * X_ADJUSTMENT);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static float BottomLeftAdjustment(in Vector2 size)
|
public static float BottomLeftAdjustment(in Vector2 size)
|
||||||
=> (size.y * -0.0048f) + (size.x * 0.0002f);
|
=> (size.y * -Y_ADJUSTMENT) + (size.x * X_ADJUSTMENT);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static float BottomRightAdjustment(in Vector2 size)
|
public static float BottomRightAdjustment(in Vector2 size)
|
||||||
=> (size.y * -0.0048f) - (size.x * 0.0002f);
|
=> (size.y * -Y_ADJUSTMENT) - (size.x * X_ADJUSTMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class PlantPatch : FishPrepatch
|
public sealed class PlantPatch : FishPrepatch
|
||||||
@@ -113,22 +118,22 @@ public sealed class PrintImprovements : ClassWithFishPrepatches
|
|||||||
|
|
||||||
public static Vector3 AdjustCenter(Vector3 center, Plant plant)
|
public static Vector3 AdjustCenter(Vector3 center, Plant plant)
|
||||||
{
|
{
|
||||||
if (Math.Abs(center.y - LowPlantAltitude) > 0.001f)
|
var plantAltitude = plant.def.altitudeLayer;
|
||||||
|
if (Math.Abs(center.y - plantAltitude.AltitudeFor()) >= COMBINED_ADJUSTMENT)
|
||||||
return center;
|
return center;
|
||||||
|
|
||||||
var plantPosition = plant.PositionHeld;
|
|
||||||
var map = plant.MapHeld;
|
var map = plant.MapHeld;
|
||||||
if (map.edificeGrid[plantPosition.CellToIndex(map)] is
|
if (map.edificeGrid[plant.PositionHeld.CellToIndex(map)] is { } building
|
||||||
|
&& building.def.altitudeLayer == plantAltitude)
|
||||||
{
|
{
|
||||||
def.altitudeLayer: AltitudeLayer.LowPlant
|
var buildingDrawPos = building.DrawPos;
|
||||||
} building)
|
var buildingSize = building.GetRotatedDrawSize();
|
||||||
{
|
|
||||||
center.y += ((plantPosition.z - building.OccupiedRect().minZ) * 0.01f) + 0.005f;
|
center.y += ((buildingSize.y - (buildingDrawPos.z - center.z)) * Y_ADJUSTMENT)
|
||||||
|
+ ((buildingSize.x - (buildingDrawPos.x - center.x)) * X_ADJUSTMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return center;
|
return center;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly float LowPlantAltitude = AltitudeLayer.LowPlant.AltitudeFor();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,9 +99,9 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
{
|
{
|
||||||
public override string Description { get; } = "Caches GetField lookups";
|
public override string Description { get; } = "Caches GetField lookups";
|
||||||
|
|
||||||
public override MethodBase TargetMethodInfo { get; }
|
public override MethodBase? TargetMethodInfo { get; }
|
||||||
= AccessTools.Method(typeof(RuntimeType), nameof(RuntimeType.GetField),
|
= AccessTools.DeclaredMethod(typeof(RuntimeType), nameof(RuntimeType.GetField),
|
||||||
[typeof(string), typeof(BindingFlags)])!;
|
[typeof(string), typeof(BindingFlags)]);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(Type __instance, string name, BindingFlags bindingAttr, out FieldInfo? __result,
|
public static bool Prefix(Type __instance, string name, BindingFlags bindingAttr, out FieldInfo? __result,
|
||||||
@@ -145,8 +145,9 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
{
|
{
|
||||||
public override string Description { get; } = "Caches GetFields lookups";
|
public override string Description { get; } = "Caches GetFields lookups";
|
||||||
|
|
||||||
public override MethodBase TargetMethodInfo { get; }
|
public override MethodBase? TargetMethodInfo { get; }
|
||||||
= AccessTools.Method(typeof(RuntimeType), nameof(RuntimeType.GetFields), [typeof(BindingFlags)])!;
|
= AccessTools.DeclaredMethod(typeof(RuntimeType), nameof(RuntimeType.GetFields),
|
||||||
|
[typeof(BindingFlags)]);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(Type __instance, BindingFlags bindingAttr, out FieldInfo[]? __result,
|
public static bool Prefix(Type __instance, BindingFlags bindingAttr, out FieldInfo[]? __result,
|
||||||
@@ -186,9 +187,9 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
{
|
{
|
||||||
public override string Description { get; } = "Caches GetMethod lookups";
|
public override string Description { get; } = "Caches GetMethod lookups";
|
||||||
|
|
||||||
public override Expression<Action> TargetMethod { get; }
|
public override MethodBase? TargetMethodInfo { get; }
|
||||||
// ReSharper disable once ReturnValueOfPureMethodIsNotUsed
|
= AccessTools.DeclaredMethod(typeof(Type), nameof(Type.GetMethod),
|
||||||
= static () => default(Type)!.GetMethod(null!, default(BindingFlags));
|
[typeof(string), typeof(BindingFlags)]);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(Type __instance, string name, BindingFlags bindingAttr, out MethodInfo? __result,
|
public static bool Prefix(Type __instance, string name, BindingFlags bindingAttr, out MethodInfo? __result,
|
||||||
@@ -223,9 +224,9 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
{
|
{
|
||||||
public override string Description { get; } = "Caches GetMethod lookups";
|
public override string Description { get; } = "Caches GetMethod lookups";
|
||||||
|
|
||||||
public override Expression<Action> TargetMethod { get; }
|
public override MethodBase? TargetMethodInfo { get; }
|
||||||
// ReSharper disable once ReturnValueOfPureMethodIsNotUsed
|
= AccessTools.DeclaredMethod(typeof(Type), nameof(Type.GetMethod),
|
||||||
= static () => default(Type)!.GetMethod(null!, null!);
|
[typeof(string), typeof(Type[])]);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(Type __instance, string name, Type[] types, out MethodInfo? __result,
|
public static bool Prefix(Type __instance, string name, Type[] types, out MethodInfo? __result,
|
||||||
@@ -257,8 +258,11 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
{
|
{
|
||||||
public override string Description { get; } = "Caches GetMethod lookups";
|
public override string Description { get; } = "Caches GetMethod lookups";
|
||||||
|
|
||||||
public override Expression<Action> TargetMethod { get; }
|
public override MethodBase? TargetMethodInfo { get; }
|
||||||
= static () => default(Type)!.GetMethod(null!, default, null, null!, null);
|
= AccessTools.DeclaredMethod(typeof(Type), nameof(Type.GetMethod),
|
||||||
|
[
|
||||||
|
typeof(string), typeof(BindingFlags), typeof(Binder), typeof(Type[]), typeof(ParameterModifier[])
|
||||||
|
]);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(Type __instance, string name, BindingFlags bindingAttr, Binder? binder,
|
public static bool Prefix(Type __instance, string name, BindingFlags bindingAttr, Binder? binder,
|
||||||
@@ -300,8 +304,9 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
{
|
{
|
||||||
public override string Description { get; } = "Caches GetConstructor lookups";
|
public override string Description { get; } = "Caches GetConstructor lookups";
|
||||||
|
|
||||||
public override Expression<Action> TargetMethod { get; }
|
public override MethodBase? TargetMethodInfo { get; }
|
||||||
= static () => default(Type)!.GetConstructor(default, null, null!, null);
|
= AccessTools.DeclaredMethod(typeof(Type), nameof(Type.GetConstructor),
|
||||||
|
[typeof(BindingFlags), typeof(Binder), typeof(Type[]), typeof(ParameterModifier[])]);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(Type __instance, BindingFlags bindingAttr, Binder? binder, Type[] types,
|
public static bool Prefix(Type __instance, BindingFlags bindingAttr, Binder? binder, Type[] types,
|
||||||
@@ -341,9 +346,9 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
{
|
{
|
||||||
public override string Description { get; } = "Caches GetProperty lookups";
|
public override string Description { get; } = "Caches GetProperty lookups";
|
||||||
|
|
||||||
public override Expression<Action> TargetMethod { get; }
|
public override MethodBase? TargetMethodInfo { get; }
|
||||||
// ReSharper disable once ReturnValueOfPureMethodIsNotUsed
|
= AccessTools.DeclaredMethod(typeof(Type), nameof(Type.GetProperty),
|
||||||
= static () => default(Type)!.GetProperty(null!, default(BindingFlags));
|
[typeof(string), typeof(BindingFlags)]);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(Type __instance, string name, BindingFlags bindingAttr,
|
public static bool Prefix(Type __instance, string name, BindingFlags bindingAttr,
|
||||||
@@ -384,7 +389,7 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
// https://github.com/Unity-Technologies/mono/blob/unity-2019.4-mbe/mono/metadata/icall.c#L2737-L2754
|
// https://github.com/Unity-Technologies/mono/blob/unity-2019.4-mbe/mono/metadata/icall.c#L2737-L2754
|
||||||
|
|
||||||
public override MethodBase TargetMethodInfo { get; }
|
public override MethodBase TargetMethodInfo { get; }
|
||||||
= AccessTools.PropertyGetter(typeof(RuntimeType), nameof(RuntimeType.FullName));
|
= AccessTools.DeclaredPropertyGetter(typeof(RuntimeType), nameof(RuntimeType.FullName));
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(RuntimeType __instance, ref string? __result, out bool __state)
|
public static bool Prefix(RuntimeType __instance, ref string? __result, out bool __state)
|
||||||
@@ -747,7 +752,7 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
public override MethodBase TargetMethodInfo { get; }
|
public override MethodBase TargetMethodInfo { get; }
|
||||||
= AccessTools.Method(typeof(MonoField), nameof(MonoField.GetValue))!;
|
= AccessTools.DeclaredMethod(typeof(MonoField), nameof(MonoField.GetValue))!;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(FieldInfo __instance, object? obj, ref object? __result)
|
public static bool Prefix(FieldInfo __instance, object? obj, ref object? __result)
|
||||||
@@ -771,8 +776,9 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
public override string Description { get; }
|
public override string Description { get; }
|
||||||
= "Optimizes the SetValue method by invoking it through specialized cached delegates";
|
= "Optimizes the SetValue method by invoking it through specialized cached delegates";
|
||||||
|
|
||||||
public override Expression<Action> TargetMethod { get; }
|
public override MethodBase? TargetMethodInfo { get; }
|
||||||
= static () => default(FieldInfo)!.SetValue(null, null);
|
= AccessTools.DeclaredMethod(typeof(FieldInfo), nameof(FieldInfo.SetValue),
|
||||||
|
[typeof(object), typeof(object)]);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(FieldInfo __instance, object? obj, object? value)
|
public static bool Prefix(FieldInfo __instance, object? obj, object? value)
|
||||||
@@ -924,8 +930,9 @@ public sealed class ReflectionCaching : ClassWithFishPatches
|
|||||||
= "Optimizes the Invoke method by compiling specialized cached delegates. Disabled by default due to "
|
= "Optimizes the Invoke method by compiling specialized cached delegates. Disabled by default due to "
|
||||||
+ "issues with various mods, like RIMMSqol and Performance Optimizer";
|
+ "issues with various mods, like RIMMSqol and Performance Optimizer";
|
||||||
|
|
||||||
public override Expression<Action> TargetMethod { get; }
|
public override MethodBase? TargetMethodInfo { get; }
|
||||||
= static () => default(MethodBase)!.Invoke(null, null);
|
= AccessTools.DeclaredMethod(typeof(MethodBase), nameof(MethodBase.Invoke),
|
||||||
|
[typeof(object), typeof(object[])]);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Prefix(MethodBase __instance, object? obj, object[]? parameters, ref object? __result)
|
public static bool Prefix(MethodBase __instance, object? obj, object[]? parameters, ref object? __result)
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ public static class MiscExtensions
|
|||||||
public static StorageSettings? TryGetGroupStoreSettings(this ISlotGroupParent slotGroupParent)
|
public static StorageSettings? TryGetGroupStoreSettings(this ISlotGroupParent slotGroupParent)
|
||||||
=> slotGroupParent.TryGetStorageGroup()?.GetStoreSettings();
|
=> slotGroupParent.TryGetStorageGroup()?.GetStoreSettings();
|
||||||
|
|
||||||
public static StorageGroup? TryGetStorageGroup(this SlotGroup slotGroup) => slotGroup.parent.TryGetStorageGroup();
|
|
||||||
|
|
||||||
public static StorageGroup? TryGetStorageGroup(this ISlotGroupParent slotGroupParent)
|
public static StorageGroup? TryGetStorageGroup(this ISlotGroupParent slotGroupParent)
|
||||||
=> slotGroupParent is IStorageGroupMember groupMember ? groupMember.Group : null;
|
=> slotGroupParent is IStorageGroupMember groupMember ? groupMember.Group : null;
|
||||||
|
|
||||||
@@ -82,6 +80,9 @@ public static class MiscExtensions
|
|||||||
return grid.regionGrid[c.CellToIndex(map)] is { valid: true } region ? region : null;
|
return grid.regionGrid[c.CellToIndex(map)] is { valid: true } region ? region : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vector2 GetRotatedDrawSize(this Thing thing)
|
||||||
|
=> !thing.Graphic.ShouldDrawRotated && thing.Rotation.IsHorizontal ? thing.DrawSize.Rotated() : thing.DrawSize;
|
||||||
|
|
||||||
public static bool ContainsThingStackableWith(this List<Thing> thingsOfSingleDef, Thing t)
|
public static bool ContainsThingStackableWith(this List<Thing> thingsOfSingleDef, Thing t)
|
||||||
{
|
{
|
||||||
var def = t.def;
|
var def = t.def;
|
||||||
|
|||||||
Reference in New Issue
Block a user