From 2cc1ebc07471c7de4a5ca70866d6abdb7274cece Mon Sep 17 00:00:00 2001 From: krzychu124 Date: Sun, 23 Jan 2022 06:21:55 +0100 Subject: [PATCH 1/3] Append patch after known vanilla instruction instead of inserting before it (improves compatibility) --- .../_BuildingDecoration/LoadPathsPatch.cs | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs b/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs index 0f98463d5..26e83783f 100644 --- a/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs +++ b/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs @@ -4,11 +4,13 @@ namespace TrafficManager.Patches._BuildingDecoration { using TrafficManager.Util; using System; using System.Reflection.Emit; + using JetBrains.Annotations; //public static void LoadPaths(BuildingInfo info, ushort buildingID, ref Building data, float elevation) [HarmonyPatch(typeof(BuildingDecoration), nameof(BuildingDecoration.LoadPaths))] + [UsedImplicitly] public class LoadPathsPatch { - ///Called after intersection is built + ///Called after intersection is built internal static void AfterIntersectionBuilt(BuildingInfo info) { if (!Shortcuts.InSimulationThread()) return; // only rendering @@ -18,21 +20,24 @@ internal static void AfterIntersectionBuilt(BuildingInfo info) { } // code from: https://github.com/Strdate/SmartIntersections/blob/master/SmartIntersections/Patch/LoadPathsPatch.cs + [UsedImplicitly] public static IEnumerable Transpiler(ILGenerator il, IEnumerable instructions) { - var fTempNodeBuffer = AccessTools.DeclaredField(typeof(NetManager), nameof(NetManager.m_tempNodeBuffer)) - ?? throw new Exception("cound not find NetManager.m_tempNodeBuffer"); - var mClear = AccessTools.DeclaredMethod(fTempNodeBuffer.FieldType, nameof(FastList.Clear)) - ?? throw new Exception("cound not find m_tempNodeBuffer.Clear"); + var fTempSegmentBuffer = AccessTools.DeclaredField(typeof(NetManager), nameof(NetManager.m_tempSegmentBuffer)) + ?? throw new Exception("Could not find NetManager.m_tempSegmentBuffer"); + var mSize = AccessTools.DeclaredField(fTempSegmentBuffer.FieldType, nameof(FastList.m_size)) + ?? throw new Exception("Could not find m_tempSegmentBuffer.m_size"); var mAfterIntersectionBuilt = AccessTools.DeclaredMethod( typeof(LoadPathsPatch), nameof(AfterIntersectionBuilt)) - ?? throw new Exception("cound not find AfterIntersectionBuilt()"); + ?? throw new Exception("Could not find AfterIntersectionBuilt()"); List codes = TranspilerUtil.ToCodeList(instructions); - bool comp(int i) => - codes[i].opcode == OpCodes.Ldfld && codes[i].operand == fTempNodeBuffer && - codes[i + 1].opcode == OpCodes.Callvirt && codes[i + 1].operand == mClear; - int index = TranspilerUtil.SearchGeneric(codes, comp, index: 0, counter: 2); - index -= 1; // index to insert instructions. + + bool compareFn(int i) => + codes[i].opcode == OpCodes.Blt && + codes[i - 1].opcode == OpCodes.Ldfld && codes[i - 1].operand == mSize && + codes[i - 2].opcode == OpCodes.Ldfld && codes[i - 2].operand == fTempSegmentBuffer; + int index = TranspilerUtil.SearchGeneric(codes, compareFn, index: 0, counter: 1); + index += 1; // index to insert instructions. (end of the loop) var newInstructions = new[] { new CodeInstruction(OpCodes.Ldarg_0), // load argument info From 1488948b25909a0e1f2b881d08692feb0d97eaa1 Mon Sep 17 00:00:00 2001 From: krzychu124 Date: Sun, 23 Jan 2022 06:23:24 +0100 Subject: [PATCH 2/3] Delay transfering records to the end of simulation step, remove force call to node/segment recalculation - may break transfering and other mods --- TLM/TLM/Util/PlaceIntersectionUtil.cs | 46 +++++++++++---------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/TLM/TLM/Util/PlaceIntersectionUtil.cs b/TLM/TLM/Util/PlaceIntersectionUtil.cs index 24b40e989..4e378127b 100644 --- a/TLM/TLM/Util/PlaceIntersectionUtil.cs +++ b/TLM/TLM/Util/PlaceIntersectionUtil.cs @@ -2,6 +2,7 @@ namespace TrafficManager.Util { using System.Collections.Generic; using System.Linq; using CSUtil.Commons; + using Manager.Impl; using TrafficManager.State.Asset; using TrafficManager.Util; using TrafficManager.Lifecycle; @@ -9,8 +10,10 @@ namespace TrafficManager.Util { public static class PlaceIntersectionUtil { ///maps old netowkr ids to new network ids + /// source segment id array created by on asset serialization /// segment list provided by LoadPaths. - public static void MapSegments( + /// segment map to fill in with pairs (old;new) + private static void FillSegmentsMap( SegmentNetworkIDs[] oldSegments, ushort[] newSegmentIds, Dictionary map) { @@ -34,8 +37,9 @@ public static void MapSegments( /// /// segment list provided by LoadPaths. public static void ApplyTrafficRules(BuildingInfo intersectionInfo, ushort[] newSegmentIds) { - /************************* - * Prepration: */ + /****************/ + /* Preparation: */ + /****************/ Log._Debug($"PlaceIntersectionUtil.ApplyTrafficRules({intersectionInfo?.ToString() ?? "null"})"); @@ -64,34 +68,22 @@ public static void ApplyTrafficRules(BuildingInfo intersectionInfo, ushort[] new var pathNetworkIDs = assetData.PathNetworkIDs; if (pathNetworkIDs == null) return; - /************************* - * Apply traffic rules: */ + /***********************/ + /* Create segment map: */ + /***********************/ + Shortcuts.AssertNotNull(newSegmentIds, "newSegmentIds"); + FillSegmentsMap(oldSegments: pathNetworkIDs, newSegmentIds: newSegmentIds, map: map); - MapSegments(oldSegments: pathNetworkIDs, newSegmentIds: newSegmentIds, map: map); + // Note to previous solution: + // Node/segment calculation shouldn't be performed at this state! + // Forcing it here may trigger another 'fake' LoadPaths call breaking other mods attached to that method! - foreach (var item in map) - CalculateNetwork(item.Value); - - assetData.Record.Transfer(map); + /*****************************************/ + /* Queue traffic rules transfer process: */ + /*****************************************/ + UtilityManager.Instance.QueueTransferRecordable(assetData.Record, map); OnPlaceIntersection?.Invoke(intersectionInfo, map); } - - /// - /// early calculate networks so that we are able to set traffic rules without delay. - /// - public static void CalculateNetwork(InstanceID instanceId) { - switch (instanceId.Type) { - case InstanceType.NetNode: - ushort nodeId = instanceId.NetNode; - nodeId.ToNode().CalculateNode(nodeId); - break; - case InstanceType.NetSegment: - ushort segmentId = instanceId.NetSegment; - segmentId.ToSegment().CalculateSegment(segmentId); - break; - } - } - } } From 00f06f569982e4d659f6ac0ed31dffda6c91360d Mon Sep 17 00:00:00 2001 From: krzychu124 Date: Tue, 25 Jan 2022 00:34:53 +0100 Subject: [PATCH 3/3] inline method rename --- TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs b/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs index 26e83783f..b038b6376 100644 --- a/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs +++ b/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs @@ -32,11 +32,11 @@ public static IEnumerable Transpiler(ILGenerator il, IEnumerabl List codes = TranspilerUtil.ToCodeList(instructions); - bool compareFn(int i) => + bool predicate(int i) => codes[i].opcode == OpCodes.Blt && codes[i - 1].opcode == OpCodes.Ldfld && codes[i - 1].operand == mSize && codes[i - 2].opcode == OpCodes.Ldfld && codes[i - 2].operand == fTempSegmentBuffer; - int index = TranspilerUtil.SearchGeneric(codes, compareFn, index: 0, counter: 1); + int index = TranspilerUtil.SearchGeneric(codes, predicate, index: 0, counter: 1); index += 1; // index to insert instructions. (end of the loop) var newInstructions = new[] {