From fe93f687ae3a8bca54c63d895807cb9bad783c65 Mon Sep 17 00:00:00 2001 From: kianzarrin Date: Fri, 7 Jan 2022 19:34:17 +0200 Subject: [PATCH] Netutil cleanup (#1273) moved network extension methods to extensions folder moved iterators to iterators folder moved segment lane iterators to segment extensions created LaneUtil --- .../GetNodeSegmentIdsEnumerablePerfTests.cs | 1 + .../GetSegmentLaneIdAndSegmentPerfTests.cs | 1 + TLM/TLM/Custom/PathFinding/CustomPathFind.cs | 1 + .../AbstractGeometryObservingManager.cs | 1 + TLM/TLM/Manager/Impl/ExtNodeManager.cs | 1 + TLM/TLM/Manager/Impl/ExtPathManager.cs | 1 + TLM/TLM/Manager/Impl/ExtSegmentManager.cs | 161 ++--------------- TLM/TLM/Manager/Impl/ExtVehicleManager.cs | 1 + TLM/TLM/Manager/Impl/GeometryNotifier.cs | 1 + .../Manager/Impl/VehicleBehaviorManager.cs | 1 + TLM/TLM/Notifier.cs | 1 + .../_HumanAI/CheckTrafficLightsPatch.cs | 1 + .../Patch/_RoadBaseAI/ClickNodeButtonPatch.cs | 1 + TLM/TLM/Patch/_RoadBaseAI/UpdateLanesPatch.cs | 1 + .../UpdatePathTargetPositionsPatch.cs | 1 + TLM/TLM/Patch/_VehicleAI/VehicleAICommons.cs | 1 + .../_CarAI/CalculateSegmentPositionPatch.cs | 1 + .../_CarAI/CalculateSegmentPositionPatch2.cs | 1 + .../GetLocalizedStatusPatch.cs | 1 + .../_VehicleAI/_TrainAI/CheckNextLanePatch.cs | 1 + .../_TrainAI/ForceTrafficLightsPatch.cs | 1 + .../_TrainAI/SimulationStep2Patch.cs | 1 + .../CalculateSegmentPositionPatch2.cs | 1 + TLM/TLM/State/Asset/SegmentNetworkIDs.cs | 1 + TLM/TLM/TLM.csproj | 9 +- .../TrafficLight/Impl/CustomSegmentLights.cs | 1 + TLM/TLM/UI/Helpers/Highlight.cs | 3 +- TLM/TLM/UI/MainMenu/DebugMenu.cs | 1 + .../UI/SubTools/ManualTrafficLightsTool.cs | 1 + .../Overlay/OverlayLaneSpeedlimitHandle.cs | 3 +- .../Overlay/OverlaySegmentSpeedlimitHandle.cs | 3 +- .../SubTools/SpeedLimits/SpeedLimitsTool.cs | 1 + TLM/TLM/UI/TrafficManagerTool.cs | 1 + TLM/TLM/Util/AutoTimedTrafficLights.cs | 1 + TLM/TLM/Util/Extensions/BuildingExtensions.cs | 5 + .../Extensions/CitizenInstanceExtensions.cs | 4 + TLM/TLM/Util/Extensions/NetLaneExtensions.cs | 6 + TLM/TLM/Util/Extensions/NetNodeExtensions.cs | 9 + .../Util/Extensions/NetSegmentExtensions.cs | 167 ++++++++++++++++++ TLM/TLM/Util/GeometryUtil.cs | 1 + .../Iterators}/GetNodeSegmentIdsEnumerable.cs | 7 +- .../Iterators}/GetNodeSegmentIdsEnumerator.cs | 9 +- .../Iterators}/GetSegmentLaneIdsEnumerable.cs | 7 +- .../Iterators}/GetSegmentLaneIdsEnumerator.cs | 9 +- TLM/TLM/Util/LaneUtil.cs | 33 ++++ TLM/TLM/Util/PlaceIntersectionUtil.cs | 1 + TLM/TLM/Util/PriorityRoad.cs | 1 + TLM/TLM/Util/Record/LaneArrowsRecord.cs | 1 + TLM/TLM/Util/Record/LaneConnectionRecord.cs | 1 + TLM/TLM/Util/Record/NodeRecord.cs | 1 + TLM/TLM/Util/Record/SegmentRecord.cs | 1 + TLM/TLM/Util/Record/SpeedLimitLaneRecord.cs | 3 +- TLM/TLM/Util/Record/TrafficRulesRecord.cs | 1 + .../Record/VehicleRestrictionsLaneRecord.cs | 3 +- TLM/TLM/Util/RoundaboutMassEdit.cs | 1 + TLM/TLM/Util/SegmentLaneTraverser.cs | 1 + TLM/TLM/Util/SeparateTurningLanesUtil.cs | 1 + TLM/TLM/Util/Shortcuts.cs | 38 +--- .../Util/GetNodeSegmentIdsEnumerableTests.cs | 1 + 59 files changed, 315 insertions(+), 205 deletions(-) rename TLM/TLM/{Manager/Impl => Util/Iterators}/GetNodeSegmentIdsEnumerable.cs (93%) rename TLM/TLM/{Manager/Impl => Util/Iterators}/GetNodeSegmentIdsEnumerator.cs (93%) rename TLM/TLM/{Manager/Impl => Util/Iterators}/GetSegmentLaneIdsEnumerable.cs (92%) rename TLM/TLM/{Manager/Impl => Util/Iterators}/GetSegmentLaneIdsEnumerator.cs (92%) create mode 100644 TLM/TLM/Util/LaneUtil.cs diff --git a/TLM/Benchmarks/GetNodeSegmentIdsEnumerablePerfTests.cs b/TLM/Benchmarks/GetNodeSegmentIdsEnumerablePerfTests.cs index 69dd8ddc4..89add5e2d 100644 --- a/TLM/Benchmarks/GetNodeSegmentIdsEnumerablePerfTests.cs +++ b/TLM/Benchmarks/GetNodeSegmentIdsEnumerablePerfTests.cs @@ -1,6 +1,7 @@ using BenchmarkDotNet.Attributes; using System.Collections.Generic; using TrafficManager.Manager.Impl; +using TrafficManager.Util.Iterators; namespace Benchmarks { public class GetNodeSegmentIdsEnumerablePerfTests { diff --git a/TLM/Benchmarks/GetSegmentLaneIdAndSegmentPerfTests.cs b/TLM/Benchmarks/GetSegmentLaneIdAndSegmentPerfTests.cs index 6123c66d4..d67ca7917 100644 --- a/TLM/Benchmarks/GetSegmentLaneIdAndSegmentPerfTests.cs +++ b/TLM/Benchmarks/GetSegmentLaneIdAndSegmentPerfTests.cs @@ -1,6 +1,7 @@ using BenchmarkDotNet.Attributes; using System.Collections.Generic; using TrafficManager.Manager.Impl; +using TrafficManager.Util.Iterators; namespace Benchmarks { public class GetSegmentLaneIdAndSegmentPerfTests { diff --git a/TLM/TLM/Custom/PathFinding/CustomPathFind.cs b/TLM/TLM/Custom/PathFinding/CustomPathFind.cs index 00f0cb2ab..387ffe7ca 100644 --- a/TLM/TLM/Custom/PathFinding/CustomPathFind.cs +++ b/TLM/TLM/Custom/PathFinding/CustomPathFind.cs @@ -16,6 +16,7 @@ namespace TrafficManager.Custom.PathFinding { using TrafficManager.State; using UnityEngine; using TrafficManager.Util; + using TrafficManager.Util.Extensions; #if DEBUG using System.Collections.Generic; diff --git a/TLM/TLM/Manager/AbstractGeometryObservingManager.cs b/TLM/TLM/Manager/AbstractGeometryObservingManager.cs index 410490221..b911ce658 100644 --- a/TLM/TLM/Manager/AbstractGeometryObservingManager.cs +++ b/TLM/TLM/Manager/AbstractGeometryObservingManager.cs @@ -9,6 +9,7 @@ namespace TrafficManager.Manager { using TrafficManager.Geometry; using TrafficManager.State.ConfigData; using TrafficManager.Util; + using TrafficManager.Util.Extensions; public abstract class AbstractGeometryObservingManager : AbstractCustomManager, IObserver { private IDisposable geoUpdateUnsubscriber; diff --git a/TLM/TLM/Manager/Impl/ExtNodeManager.cs b/TLM/TLM/Manager/Impl/ExtNodeManager.cs index 09e5cbc63..1f02efad0 100644 --- a/TLM/TLM/Manager/Impl/ExtNodeManager.cs +++ b/TLM/TLM/Manager/Impl/ExtNodeManager.cs @@ -7,6 +7,7 @@ namespace TrafficManager.Manager.Impl { using TrafficManager.Util; using ColossalFramework; using TrafficManager.Util.Extensions; + using TrafficManager.Util.Iterators; public class ExtNodeManager : AbstractCustomManager, diff --git a/TLM/TLM/Manager/Impl/ExtPathManager.cs b/TLM/TLM/Manager/Impl/ExtPathManager.cs index c132c3d98..84666e674 100644 --- a/TLM/TLM/Manager/Impl/ExtPathManager.cs +++ b/TLM/TLM/Manager/Impl/ExtPathManager.cs @@ -6,6 +6,7 @@ namespace TrafficManager.Manager.Impl { using TrafficManager.API.Manager; using TrafficManager.Util; using UnityEngine; + using TrafficManager.Util.Extensions; public class ExtPathManager : AbstractCustomManager, diff --git a/TLM/TLM/Manager/Impl/ExtSegmentManager.cs b/TLM/TLM/Manager/Impl/ExtSegmentManager.cs index b87048509..6c949b4cb 100644 --- a/TLM/TLM/Manager/Impl/ExtSegmentManager.cs +++ b/TLM/TLM/Manager/Impl/ExtSegmentManager.cs @@ -8,6 +8,7 @@ namespace TrafficManager.Manager.Impl { using TrafficManager.State.ConfigData; using TrafficManager.Util; using TrafficManager.Util.Extensions; + using TrafficManager.Util.Iterators; public class ExtSegmentManager : AbstractCustomManager, @@ -32,43 +33,14 @@ private ExtSegmentManager() { /// public ExtSegment[] ExtSegments { get; } - public ushort GetHeadNode(ref NetSegment segment) { - // tail node>-------->head node - bool invert = (segment.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None; - invert = invert ^ (Singleton.instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True); - if (invert) { - return segment.m_startNode; - } else { - return segment.m_endNode; - } - } + [Obsolete] + public ushort GetHeadNode(ushort segmentId) => segmentId.ToSegment().GetHeadNode(); - public ushort GetHeadNode(ushort segmentId) => - GetHeadNode(ref segmentId.ToSegment()); - - public ushort GetTailNode(ref NetSegment segment) { - bool invert = (segment.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None; - invert = invert ^ (Singleton.instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True); - if (!invert) { - return segment.m_startNode; - } else { - return segment.m_endNode; - }//endif - } + [Obsolete] + public ushort GetTailNode(ushort segmentId) => segmentId.ToSegment().GetTailNode(); - public ushort GetTailNode(ushort segmentId) => - GetTailNode(ref segmentId.ToSegment()); - - public bool? IsStartNode(ushort segmentId, ushort nodeId) { - ref NetSegment segment = ref segmentId.ToSegment(); - if (segment.m_startNode == nodeId) { - return true; - } else if (segment.m_endNode == nodeId) { - return false; - } else { - return null; - } - } + [Obsolete] + public bool? IsStartNode(ushort segmentId, ushort nodeId) => segmentId.ToSegment().IsStartNode(nodeId); public void PublishSegmentChanges(ushort segmentId) { Log._Debug($"NetService.PublishSegmentChanges({segmentId}) called."); @@ -231,33 +203,11 @@ private bool CalculateIsHighway(NetInfo segmentInfo) { && ((RoadBaseAI)segmentInfo.m_netAI).m_highwayRules; } - public GetSegmentLaneIdsEnumerable GetSegmentLaneIdsAndLaneIndexes(ushort segmentId) { - NetManager netManager = Singleton.instance; - ref NetSegment netSegment = ref segmentId.ToSegment(); - uint initialLaneId = netSegment.m_lanes; - NetInfo netInfo = netSegment.Info; - NetLane[] laneBuffer = netManager.m_lanes.m_buffer; - if (netInfo == null) { - return new GetSegmentLaneIdsEnumerable(0, 0, laneBuffer); - } - - return new GetSegmentLaneIdsEnumerable(initialLaneId, netInfo.m_lanes.Length, laneBuffer); - } + [Obsolete] + public GetSegmentLaneIdsEnumerable GetSegmentLaneIdsAndLaneIndexes(ushort segmentId) => + segmentId.ToSegment().GetSegmentLaneIdsAndLaneIndexes(); - /// - /// Assembles a geometrically sorted list of lanes for the given segment. - /// If the parameter is set only lanes supporting traffic to flow towards the given node are added to the list, otherwise all matched lanes are added. - /// - /// segment id - /// segment data - /// reference node (optional) - /// lane type filter, lanes must match this filter mask - /// vehicle type filter, lanes must match this filter mask - /// if true, lanes are ordered from right to left (relative to the - /// segment's start node / the given node), otherwise from left to right - /// if false, no sorting takes place - /// regardless of - /// sorted list of lanes for the given segment + [Obsolete] public IList GetSortedLanes(ushort segmentId, ref NetSegment segment, bool? startNode, @@ -265,94 +215,7 @@ public IList GetSortedLanes(ushort segmentId, VehicleInfo.VehicleType? vehicleTypeFilter = null, bool reverse = false, bool sort = true) { - // TODO refactor together with getSegmentNumVehicleLanes, especially the vehicle type and lane type checks - NetManager netManager = Singleton.instance; - var laneList = new List(); - - bool inverted = (segment.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None; - - NetInfo.Direction? filterDir = null; - NetInfo.Direction sortDir = NetInfo.Direction.Forward; - - if (startNode != null) { - filterDir = (bool)startNode - ? NetInfo.Direction.Backward - : NetInfo.Direction.Forward; - filterDir = inverted - ? NetInfo.InvertDirection((NetInfo.Direction)filterDir) - : filterDir; - sortDir = NetInfo.InvertDirection((NetInfo.Direction)filterDir); - } else if (inverted) { - sortDir = NetInfo.Direction.Backward; - } - - if (reverse) { - sortDir = NetInfo.InvertDirection(sortDir); - } - - NetInfo segmentInfo = segment.Info; - uint curLaneId = segment.m_lanes; - byte laneIndex = 0; - - while (laneIndex < segmentInfo.m_lanes.Length && curLaneId != 0u) { - NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; - if ((laneTypeFilter == null || - (laneInfo.m_laneType & laneTypeFilter) != NetInfo.LaneType.None) && - (vehicleTypeFilter == null || (laneInfo.m_vehicleType & vehicleTypeFilter) != - VehicleInfo.VehicleType.None) && - (filterDir == null || - segmentInfo.m_lanes[laneIndex].m_finalDirection == filterDir)) { - laneList.Add( - new LanePos( - curLaneId, - laneIndex, - segmentInfo.m_lanes[laneIndex].m_position, - laneInfo.m_vehicleType, - laneInfo.m_laneType)); - } - - curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane; - ++laneIndex; - } - - if (sort) { - int CompareLanePositionsFun(LanePos x, LanePos y) { - bool fwd = sortDir == NetInfo.Direction.Forward; - if (Math.Abs(x.position - y.position) < 1e-12) { - if (x.position > 0) { - // mirror type-bound lanes (e.g. for coherent disply of lane-wise speed limits) - fwd = !fwd; - } - - if (x.laneType == y.laneType) { - if (x.vehicleType == y.vehicleType) { - return 0; - } - - if ((x.vehicleType < y.vehicleType) == fwd) { - return -1; - } - - return 1; - } - - if ((x.laneType < y.laneType) == fwd) { - return -1; - } - - return 1; - } - - if (x.position < y.position == fwd) { - return -1; - } - - return 1; - } - - laneList.Sort(CompareLanePositionsFun); - } - return laneList; + return segment.GetSortedLanes(startNode, laneTypeFilter, vehicleTypeFilter, reverse, sort); } protected override void InternalPrintDebugInfo() { diff --git a/TLM/TLM/Manager/Impl/ExtVehicleManager.cs b/TLM/TLM/Manager/Impl/ExtVehicleManager.cs index 487e63e49..1c07f45e8 100644 --- a/TLM/TLM/Manager/Impl/ExtVehicleManager.cs +++ b/TLM/TLM/Manager/Impl/ExtVehicleManager.cs @@ -11,6 +11,7 @@ namespace TrafficManager.Manager.Impl { using TrafficManager.State; using UnityEngine; using TrafficManager.Util; + using TrafficManager.Util.Extensions; public class ExtVehicleManager : AbstractCustomManager, diff --git a/TLM/TLM/Manager/Impl/GeometryNotifier.cs b/TLM/TLM/Manager/Impl/GeometryNotifier.cs index 96adb3fea..f815bdba1 100644 --- a/TLM/TLM/Manager/Impl/GeometryNotifier.cs +++ b/TLM/TLM/Manager/Impl/GeometryNotifier.cs @@ -6,6 +6,7 @@ namespace TrafficManager.Manager.Impl { using TrafficManager.API.Traffic.Data; using TrafficManager.API.Util; using TrafficManager.Util; + using TrafficManager.Util.Extensions; internal class GeometryNotifier : IObserver { void IObserver.OnUpdate(GeometryUpdate subject) { diff --git a/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs b/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs index a8db859c9..12ac308ee 100644 --- a/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs +++ b/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs @@ -12,6 +12,7 @@ namespace TrafficManager.Manager.Impl { using TrafficManager.UI.SubTools.SpeedLimits; using TrafficManager.Util; using UnityEngine; + using TrafficManager.Util.Extensions; public class VehicleBehaviorManager : AbstractCustomManager, IVehicleBehaviorManager { public const float MIN_SPEED = 8f * 0.2f; // 10 km/h diff --git a/TLM/TLM/Notifier.cs b/TLM/TLM/Notifier.cs index 42b1f3e8b..a8aa0a25e 100644 --- a/TLM/TLM/Notifier.cs +++ b/TLM/TLM/Notifier.cs @@ -3,6 +3,7 @@ namespace TrafficManager using System; using TrafficManager.API.Notifier; using TrafficManager.Util; + using TrafficManager.Util.Extensions; public class Notifier : INotifier { diff --git a/TLM/TLM/Patch/_CitizenAI/_HumanAI/CheckTrafficLightsPatch.cs b/TLM/TLM/Patch/_CitizenAI/_HumanAI/CheckTrafficLightsPatch.cs index aab4a8cf2..e9ceda9bd 100644 --- a/TLM/TLM/Patch/_CitizenAI/_HumanAI/CheckTrafficLightsPatch.cs +++ b/TLM/TLM/Patch/_CitizenAI/_HumanAI/CheckTrafficLightsPatch.cs @@ -7,6 +7,7 @@ namespace TrafficManager.Patch._CitizenAI._HumanAI { using Manager.Impl; using State; using State.ConfigData; + using TrafficManager.Util.Extensions; using Util; [UsedImplicitly] diff --git a/TLM/TLM/Patch/_RoadBaseAI/ClickNodeButtonPatch.cs b/TLM/TLM/Patch/_RoadBaseAI/ClickNodeButtonPatch.cs index 5047e1fbf..8e298ecc7 100644 --- a/TLM/TLM/Patch/_RoadBaseAI/ClickNodeButtonPatch.cs +++ b/TLM/TLM/Patch/_RoadBaseAI/ClickNodeButtonPatch.cs @@ -8,6 +8,7 @@ namespace TrafficManager.Patch._RoadBaseAI { using TrafficManager.UI; using TrafficManager.UI.SubTools; using TrafficManager.Util; + using TrafficManager.Util.Extensions; [UsedImplicitly] [HarmonyPatch(typeof(RoadBaseAI), nameof(RoadBaseAI.ClickNodeButton))] diff --git a/TLM/TLM/Patch/_RoadBaseAI/UpdateLanesPatch.cs b/TLM/TLM/Patch/_RoadBaseAI/UpdateLanesPatch.cs index 5bf8333ef..edc717781 100644 --- a/TLM/TLM/Patch/_RoadBaseAI/UpdateLanesPatch.cs +++ b/TLM/TLM/Patch/_RoadBaseAI/UpdateLanesPatch.cs @@ -3,6 +3,7 @@ namespace TrafficManager.Patch._RoadBaseAI { using JetBrains.Annotations; using TrafficManager.State; using TrafficManager.Util; + using TrafficManager.Util.Extensions; [HarmonyPatch(typeof(RoadBaseAI), "UpdateLanes")] [UsedImplicitly] diff --git a/TLM/TLM/Patch/_VehicleAI/UpdatePathTargetPositionsPatch.cs b/TLM/TLM/Patch/_VehicleAI/UpdatePathTargetPositionsPatch.cs index 98c848487..af8d1f5a2 100644 --- a/TLM/TLM/Patch/_VehicleAI/UpdatePathTargetPositionsPatch.cs +++ b/TLM/TLM/Patch/_VehicleAI/UpdatePathTargetPositionsPatch.cs @@ -10,6 +10,7 @@ namespace TrafficManager.Patch._VehicleAI { using Manager.Impl; using State; using State.ConfigData; + using TrafficManager.Util.Extensions; using UnityEngine; using Util; diff --git a/TLM/TLM/Patch/_VehicleAI/VehicleAICommons.cs b/TLM/TLM/Patch/_VehicleAI/VehicleAICommons.cs index 9a2e0222e..e63ad66c0 100644 --- a/TLM/TLM/Patch/_VehicleAI/VehicleAICommons.cs +++ b/TLM/TLM/Patch/_VehicleAI/VehicleAICommons.cs @@ -3,6 +3,7 @@ namespace TrafficManager.Patch._VehicleAI { using Manager.Impl; using State; using TrafficManager.Util; + using TrafficManager.Util.Extensions; using UnityEngine; public class VehicleAICommons { diff --git a/TLM/TLM/Patch/_VehicleAI/_CarAI/CalculateSegmentPositionPatch.cs b/TLM/TLM/Patch/_VehicleAI/_CarAI/CalculateSegmentPositionPatch.cs index 5777541a5..6bf9178fc 100644 --- a/TLM/TLM/Patch/_VehicleAI/_CarAI/CalculateSegmentPositionPatch.cs +++ b/TLM/TLM/Patch/_VehicleAI/_CarAI/CalculateSegmentPositionPatch.cs @@ -2,6 +2,7 @@ namespace TrafficManager.Patch._VehicleAI._CarAI { using System.Reflection; using HarmonyLib; using JetBrains.Annotations; + using TrafficManager.Util.Extensions; using UnityEngine; using Util; diff --git a/TLM/TLM/Patch/_VehicleAI/_CarAI/CalculateSegmentPositionPatch2.cs b/TLM/TLM/Patch/_VehicleAI/_CarAI/CalculateSegmentPositionPatch2.cs index 5b952664e..d0409d0be 100644 --- a/TLM/TLM/Patch/_VehicleAI/_CarAI/CalculateSegmentPositionPatch2.cs +++ b/TLM/TLM/Patch/_VehicleAI/_CarAI/CalculateSegmentPositionPatch2.cs @@ -8,6 +8,7 @@ namespace TrafficManager.Patch._VehicleAI._CarAI { using Manager.Impl; using State; using State.ConfigData; + using TrafficManager.Util.Extensions; using UnityEngine; using Util; diff --git a/TLM/TLM/Patch/_VehicleAI/_PassengerCarAI/GetLocalizedStatusPatch.cs b/TLM/TLM/Patch/_VehicleAI/_PassengerCarAI/GetLocalizedStatusPatch.cs index f6a89afdb..63c10ad47 100644 --- a/TLM/TLM/Patch/_VehicleAI/_PassengerCarAI/GetLocalizedStatusPatch.cs +++ b/TLM/TLM/Patch/_VehicleAI/_PassengerCarAI/GetLocalizedStatusPatch.cs @@ -6,6 +6,7 @@ namespace TrafficManager.Patch._VehicleAI._PassengerCarAI { using JetBrains.Annotations; using Manager.Impl; using State; + using TrafficManager.Util.Extensions; using Util; [UsedImplicitly] diff --git a/TLM/TLM/Patch/_VehicleAI/_TrainAI/CheckNextLanePatch.cs b/TLM/TLM/Patch/_VehicleAI/_TrainAI/CheckNextLanePatch.cs index 5845dfcd9..560fd0851 100644 --- a/TLM/TLM/Patch/_VehicleAI/_TrainAI/CheckNextLanePatch.cs +++ b/TLM/TLM/Patch/_VehicleAI/_TrainAI/CheckNextLanePatch.cs @@ -9,6 +9,7 @@ namespace TrafficManager.Patch._VehicleAI._TrainAI { using Manager.Impl; using State; using State.ConfigData; + using TrafficManager.Util.Extensions; using UnityEngine; using Util; diff --git a/TLM/TLM/Patch/_VehicleAI/_TrainAI/ForceTrafficLightsPatch.cs b/TLM/TLM/Patch/_VehicleAI/_TrainAI/ForceTrafficLightsPatch.cs index 81ff13b93..a244c0411 100644 --- a/TLM/TLM/Patch/_VehicleAI/_TrainAI/ForceTrafficLightsPatch.cs +++ b/TLM/TLM/Patch/_VehicleAI/_TrainAI/ForceTrafficLightsPatch.cs @@ -4,6 +4,7 @@ namespace TrafficManager.Patch._VehicleAI._TrainAI{ using JetBrains.Annotations; using Manager.Impl; using State; + using TrafficManager.Util.Extensions; using Util; [UsedImplicitly] diff --git a/TLM/TLM/Patch/_VehicleAI/_TrainAI/SimulationStep2Patch.cs b/TLM/TLM/Patch/_VehicleAI/_TrainAI/SimulationStep2Patch.cs index dfe3c1493..d44d229f0 100644 --- a/TLM/TLM/Patch/_VehicleAI/_TrainAI/SimulationStep2Patch.cs +++ b/TLM/TLM/Patch/_VehicleAI/_TrainAI/SimulationStep2Patch.cs @@ -6,6 +6,7 @@ namespace TrafficManager.Patch._VehicleAI._TrainAI { using HarmonyLib; using JetBrains.Annotations; using Manager.Impl; + using TrafficManager.Util.Extensions; using UnityEngine; using Util; diff --git a/TLM/TLM/Patch/_VehicleAI/_TramBaseAI/CalculateSegmentPositionPatch2.cs b/TLM/TLM/Patch/_VehicleAI/_TramBaseAI/CalculateSegmentPositionPatch2.cs index b7c5c32c0..11b2faa3d 100644 --- a/TLM/TLM/Patch/_VehicleAI/_TramBaseAI/CalculateSegmentPositionPatch2.cs +++ b/TLM/TLM/Patch/_VehicleAI/_TramBaseAI/CalculateSegmentPositionPatch2.cs @@ -5,6 +5,7 @@ namespace TrafficManager.Patch._VehicleAI._TramBaseAI { using JetBrains.Annotations; using Manager.Impl; using State; + using TrafficManager.Util.Extensions; using UnityEngine; using Util; diff --git a/TLM/TLM/State/Asset/SegmentNetworkIDs.cs b/TLM/TLM/State/Asset/SegmentNetworkIDs.cs index 488621fce..1db785962 100644 --- a/TLM/TLM/State/Asset/SegmentNetworkIDs.cs +++ b/TLM/TLM/State/Asset/SegmentNetworkIDs.cs @@ -4,6 +4,7 @@ namespace TrafficManager.State.Asset { using System.Linq; using CSUtil.Commons; using TrafficManager.Util; + using TrafficManager.Util.Extensions; [Serializable] public class SegmentNetworkIDs { diff --git a/TLM/TLM/TLM.csproj b/TLM/TLM/TLM.csproj index 67e150324..2c75e9526 100644 --- a/TLM/TLM/TLM.csproj +++ b/TLM/TLM/TLM.csproj @@ -146,10 +146,10 @@ - - - - + + + + @@ -424,6 +424,7 @@ + diff --git a/TLM/TLM/TrafficLight/Impl/CustomSegmentLights.cs b/TLM/TLM/TrafficLight/Impl/CustomSegmentLights.cs index 62f37badc..b6135cba3 100644 --- a/TLM/TLM/TrafficLight/Impl/CustomSegmentLights.cs +++ b/TLM/TLM/TrafficLight/Impl/CustomSegmentLights.cs @@ -14,6 +14,7 @@ namespace TrafficManager.TrafficLight.Impl { using TrafficManager.State.ConfigData; using TrafficManager.Util; using TrafficManager.Manager.Impl; + using TrafficManager.Util.Extensions; /// /// Represents the set of custom traffic lights located at a node diff --git a/TLM/TLM/UI/Helpers/Highlight.cs b/TLM/TLM/UI/Helpers/Highlight.cs index 7c111e0dc..eab5f4903 100644 --- a/TLM/TLM/UI/Helpers/Highlight.cs +++ b/TLM/TLM/UI/Helpers/Highlight.cs @@ -1,7 +1,8 @@ -namespace TrafficManager.UI.Helpers { +namespace TrafficManager.UI.Helpers { using ColossalFramework; using ColossalFramework.Math; using TrafficManager.Util; + using TrafficManager.Util.Extensions; using UnityEngine; /// diff --git a/TLM/TLM/UI/MainMenu/DebugMenu.cs b/TLM/TLM/UI/MainMenu/DebugMenu.cs index a581b7e10..a780fedce 100644 --- a/TLM/TLM/UI/MainMenu/DebugMenu.cs +++ b/TLM/TLM/UI/MainMenu/DebugMenu.cs @@ -14,6 +14,7 @@ namespace TrafficManager.UI.MainMenu { using TrafficManager.Util; using TrafficManager.Lifecycle; using TrafficManager.Manager.Impl; + using TrafficManager.Util.Extensions; #if DEBUG // whole class coverage public class DebugMenuPanel : UIPanel diff --git a/TLM/TLM/UI/SubTools/ManualTrafficLightsTool.cs b/TLM/TLM/UI/SubTools/ManualTrafficLightsTool.cs index c48735864..641f7a8d8 100644 --- a/TLM/TLM/UI/SubTools/ManualTrafficLightsTool.cs +++ b/TLM/TLM/UI/SubTools/ManualTrafficLightsTool.cs @@ -11,6 +11,7 @@ namespace TrafficManager.UI.SubTools { using TrafficManager.UI.MainMenu.OSD; using TrafficManager.UI.Textures; using TrafficManager.Util; + using TrafficManager.Util.Extensions; using UnityEngine; public class ManualTrafficLightsTool diff --git a/TLM/TLM/UI/SubTools/SpeedLimits/Overlay/OverlayLaneSpeedlimitHandle.cs b/TLM/TLM/UI/SubTools/SpeedLimits/Overlay/OverlayLaneSpeedlimitHandle.cs index c809eef38..0bc8bcec2 100644 --- a/TLM/TLM/UI/SubTools/SpeedLimits/Overlay/OverlayLaneSpeedlimitHandle.cs +++ b/TLM/TLM/UI/SubTools/SpeedLimits/Overlay/OverlayLaneSpeedlimitHandle.cs @@ -1,4 +1,4 @@ -namespace TrafficManager.UI.SubTools.SpeedLimits.Overlay { +namespace TrafficManager.UI.SubTools.SpeedLimits.Overlay { using System; using System.Collections.Generic; using ColossalFramework; @@ -6,6 +6,7 @@ using TrafficManager.Manager.Impl; using TrafficManager.State; using TrafficManager.Util; + using TrafficManager.Util.Extensions; /// /// Describes a recently rendered speed icon on the speed limits overlay for a LANE. diff --git a/TLM/TLM/UI/SubTools/SpeedLimits/Overlay/OverlaySegmentSpeedlimitHandle.cs b/TLM/TLM/UI/SubTools/SpeedLimits/Overlay/OverlaySegmentSpeedlimitHandle.cs index 3533f33d3..3d4a17391 100644 --- a/TLM/TLM/UI/SubTools/SpeedLimits/Overlay/OverlaySegmentSpeedlimitHandle.cs +++ b/TLM/TLM/UI/SubTools/SpeedLimits/Overlay/OverlaySegmentSpeedlimitHandle.cs @@ -1,4 +1,4 @@ -namespace TrafficManager.UI.SubTools.SpeedLimits.Overlay { +namespace TrafficManager.UI.SubTools.SpeedLimits.Overlay { using System; using ColossalFramework; using CSUtil.Commons; @@ -7,6 +7,7 @@ using TrafficManager.Manager.Impl; using TrafficManager.State; using TrafficManager.Util; + using TrafficManager.Util.Extensions; /// /// Describes a recently rendered speed icon on the speed limits overlay for SEGMENT. diff --git a/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs b/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs index c4cfa60a8..bbe285df6 100644 --- a/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs +++ b/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs @@ -11,6 +11,7 @@ namespace TrafficManager.UI.SubTools.SpeedLimits { using TrafficManager.UI.SubTools.PrioritySigns; using TrafficManager.UI.SubTools.SpeedLimits.Overlay; using TrafficManager.Util; + using TrafficManager.Util.Extensions; using UnityEngine; /// diff --git a/TLM/TLM/UI/TrafficManagerTool.cs b/TLM/TLM/UI/TrafficManagerTool.cs index 15471d78a..565007140 100644 --- a/TLM/TLM/UI/TrafficManagerTool.cs +++ b/TLM/TLM/UI/TrafficManagerTool.cs @@ -31,6 +31,7 @@ namespace TrafficManager.UI { using static TrafficManager.Util.SegmentTraverser; using TrafficManager.UI.Textures; using TrafficManager.State.Keybinds; + using TrafficManager.Util.Extensions; [UsedImplicitly] public class TrafficManagerTool diff --git a/TLM/TLM/Util/AutoTimedTrafficLights.cs b/TLM/TLM/Util/AutoTimedTrafficLights.cs index a13a8c1fb..60013cb8d 100644 --- a/TLM/TLM/Util/AutoTimedTrafficLights.cs +++ b/TLM/TLM/Util/AutoTimedTrafficLights.cs @@ -9,6 +9,7 @@ namespace TrafficManager.Util { using TrafficManager.API.TrafficLight; using TrafficManager.Manager.Impl; using UnityEngine; + using TrafficManager.Util.Extensions; public static class AutoTimedTrafficLights { /// diff --git a/TLM/TLM/Util/Extensions/BuildingExtensions.cs b/TLM/TLM/Util/Extensions/BuildingExtensions.cs index 09079a23c..11d071337 100644 --- a/TLM/TLM/Util/Extensions/BuildingExtensions.cs +++ b/TLM/TLM/Util/Extensions/BuildingExtensions.cs @@ -1,5 +1,10 @@ namespace TrafficManager.Util.Extensions { + using ColossalFramework; public static class BuildingExtensions { + private static Building[] _buildingBuffer = Singleton.instance.m_buildings.m_buffer; + + internal static ref Building ToBuilding(this ushort buildingId) => ref _buildingBuffer[buildingId]; + /// /// Checks if the building is Created, but neither Collapsed nor Deleted. /// diff --git a/TLM/TLM/Util/Extensions/CitizenInstanceExtensions.cs b/TLM/TLM/Util/Extensions/CitizenInstanceExtensions.cs index a68496984..75658d68c 100644 --- a/TLM/TLM/Util/Extensions/CitizenInstanceExtensions.cs +++ b/TLM/TLM/Util/Extensions/CitizenInstanceExtensions.cs @@ -1,5 +1,9 @@ namespace TrafficManager.Util.Extensions { + using ColossalFramework; public static class CitizenInstanceExtensions { + private static CitizenInstance[] _citizenInstanceBuffer = Singleton.instance.m_instances.m_buffer; + + internal static ref CitizenInstance ToCitizenInstance(this ushort citizenInstance) => ref _citizenInstanceBuffer[citizenInstance]; /// /// Checks if the citizenInstance is Created, but not Deleted. /// diff --git a/TLM/TLM/Util/Extensions/NetLaneExtensions.cs b/TLM/TLM/Util/Extensions/NetLaneExtensions.cs index 605a3d2ec..87890a002 100644 --- a/TLM/TLM/Util/Extensions/NetLaneExtensions.cs +++ b/TLM/TLM/Util/Extensions/NetLaneExtensions.cs @@ -1,5 +1,11 @@ namespace TrafficManager.Util.Extensions { + using ColossalFramework; + public static class NetLaneExtensions { + private static NetLane[] _laneBuffer = Singleton.instance.m_lanes.m_buffer; + + internal static ref NetLane ToLane(this uint laneId) => ref _laneBuffer[laneId]; + /// /// Checks if the netLane is Created, but not Deleted. /// diff --git a/TLM/TLM/Util/Extensions/NetNodeExtensions.cs b/TLM/TLM/Util/Extensions/NetNodeExtensions.cs index c53127458..f566aa112 100644 --- a/TLM/TLM/Util/Extensions/NetNodeExtensions.cs +++ b/TLM/TLM/Util/Extensions/NetNodeExtensions.cs @@ -1,5 +1,11 @@ namespace TrafficManager.Util.Extensions { + using ColossalFramework; public static class NetNodeExtensions { + private static NetNode[] _nodeBuffer = Singleton.instance.m_nodes.m_buffer; + + internal static ref NetNode ToNode(this ushort nodeId) => ref _nodeBuffer[nodeId]; + internal static bool IsJunction(this ref NetNode netNode) => netNode.m_flags.IsFlagSet(NetNode.Flags.Junction); + /// /// Checks if the netNode is Created, but neither Collapsed nor Deleted. /// @@ -9,5 +15,8 @@ public static bool IsValid(this ref NetNode netNode) => netNode.m_flags.CheckFlags( required: NetNode.Flags.Created, forbidden: NetNode.Flags.Collapsed | NetNode.Flags.Deleted); + + internal static bool IsUnderground(this ref NetNode netNode) => + netNode.m_flags.IsFlagSet(NetNode.Flags.Underground); } } diff --git a/TLM/TLM/Util/Extensions/NetSegmentExtensions.cs b/TLM/TLM/Util/Extensions/NetSegmentExtensions.cs index b6b330fb0..3b025c4ad 100644 --- a/TLM/TLM/Util/Extensions/NetSegmentExtensions.cs +++ b/TLM/TLM/Util/Extensions/NetSegmentExtensions.cs @@ -1,5 +1,48 @@ namespace TrafficManager.Util.Extensions { + using ColossalFramework; + using System; + using System.Collections.Generic; + using TrafficManager.Manager.Impl; + using TrafficManager.Util.Iterators; + using static Shortcuts; + public static class NetSegmentExtensions { + private static NetSegment[] _segBuffer = Singleton.instance.m_segments.m_buffer; + + public static ref NetSegment ToSegment(this ushort segmentId) => ref _segBuffer[segmentId]; + + public static ushort GetNodeId(this ref NetSegment segment, bool startNode) => + startNode ? segment.m_startNode : segment.m_endNode; + + public static ushort GetHeadNode(this ref NetSegment netSegment) { + // tail node>-------->head node + bool invert = netSegment.m_flags.IsFlagSet(NetSegment.Flags.Invert) ^ LHT; + if (invert) { + return netSegment.m_startNode; + } else { + return netSegment.m_endNode; + } + } + + public static ushort GetTailNode(this ref NetSegment netSegment) { + bool invert = netSegment.m_flags.IsFlagSet(NetSegment.Flags.Invert) ^ LHT; + if (!invert) { + return netSegment.m_startNode; + } else { + return netSegment.m_endNode; + }//endif + } + + public static bool? IsStartNode(this ref NetSegment netSegment, ushort nodeId) { + if (netSegment.m_startNode == nodeId) { + return true; + } else if (netSegment.m_endNode == nodeId) { + return false; + } else { + return null; + } + } + /// /// Checks if the netSegment is Created, but neither Collapsed nor Deleted. /// @@ -9,5 +52,129 @@ public static bool IsValid(this ref NetSegment netSegment) => netSegment.m_flags.CheckFlags( required: NetSegment.Flags.Created, forbidden: NetSegment.Flags.Collapsed | NetSegment.Flags.Deleted); + + public static NetInfo.Lane GetLaneInfo(this ref NetSegment netSegment, int laneIndex) => + netSegment.Info?.m_lanes?[laneIndex]; + + public static GetSegmentLaneIdsEnumerable GetSegmentLaneIdsAndLaneIndexes(this ref NetSegment netSegment) { + NetInfo netInfo = netSegment.Info; + uint initialLaneId = netSegment.m_lanes; + NetLane[] laneBuffer = NetManager.instance.m_lanes.m_buffer; + if (netInfo == null) { + return new GetSegmentLaneIdsEnumerable(0, 0, laneBuffer); + } + + return new GetSegmentLaneIdsEnumerable(initialLaneId, netInfo.m_lanes.Length, laneBuffer); + } + + /// + /// Assembles a geometrically sorted list of lanes for the given segment. + /// If the parameter is set only lanes supporting traffic to flow towards the given node are added to the list, otherwise all matched lanes are added. + /// + /// segment data + /// reference node (optional) + /// lane type filter, lanes must match this filter mask + /// vehicle type filter, lanes must match this filter mask + /// if true, lanes are ordered from right to left (relative to the + /// segment's start node / the given node), otherwise from left to right + /// if false, no sorting takes place + /// regardless of + /// sorted list of lanes for the given segment + public static IList GetSortedLanes( + this ref NetSegment netSegment, + bool? startNode, + NetInfo.LaneType? laneTypeFilter = null, + VehicleInfo.VehicleType? vehicleTypeFilter = null, + bool reverse = false, + bool sort = true) { + // TODO refactor together with getSegmentNumVehicleLanes, especially the vehicle type and lane type checks + NetManager netManager = Singleton.instance; + var laneList = new List(); + + bool inverted = (netSegment.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None; + + NetInfo.Direction? filterDir = null; + NetInfo.Direction sortDir = NetInfo.Direction.Forward; + + if (startNode != null) { + filterDir = (bool)startNode + ? NetInfo.Direction.Backward + : NetInfo.Direction.Forward; + filterDir = inverted + ? NetInfo.InvertDirection((NetInfo.Direction)filterDir) + : filterDir; + sortDir = NetInfo.InvertDirection((NetInfo.Direction)filterDir); + } else if (inverted) { + sortDir = NetInfo.Direction.Backward; + } + + if (reverse) { + sortDir = NetInfo.InvertDirection(sortDir); + } + + NetInfo segmentInfo = netSegment.Info; + uint curLaneId = netSegment.m_lanes; + byte laneIndex = 0; + + while (laneIndex < segmentInfo.m_lanes.Length && curLaneId != 0u) { + NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; + if ((laneTypeFilter == null || + (laneInfo.m_laneType & laneTypeFilter) != NetInfo.LaneType.None) && + (vehicleTypeFilter == null || (laneInfo.m_vehicleType & vehicleTypeFilter) != + VehicleInfo.VehicleType.None) && + (filterDir == null || + segmentInfo.m_lanes[laneIndex].m_finalDirection == filterDir)) { + laneList.Add( + new LanePos( + curLaneId, + laneIndex, + segmentInfo.m_lanes[laneIndex].m_position, + laneInfo.m_vehicleType, + laneInfo.m_laneType)); + } + + curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane; + ++laneIndex; + } + + if (sort) { + int CompareLanePositionsFun(LanePos x, LanePos y) { + bool fwd = sortDir == NetInfo.Direction.Forward; + if (Math.Abs(x.position - y.position) < 1e-12) { + if (x.position > 0) { + // mirror type-bound lanes (e.g. for coherent disply of lane-wise speed limits) + fwd = !fwd; + } + + if (x.laneType == y.laneType) { + if (x.vehicleType == y.vehicleType) { + return 0; + } + + if ((x.vehicleType < y.vehicleType) == fwd) { + return -1; + } + + return 1; + } + + if ((x.laneType < y.laneType) == fwd) { + return -1; + } + + return 1; + } + + if (x.position < y.position == fwd) { + return -1; + } + + return 1; + } + + laneList.Sort(CompareLanePositionsFun); + } + return laneList; + } } } diff --git a/TLM/TLM/Util/GeometryUtil.cs b/TLM/TLM/Util/GeometryUtil.cs index 872c60f87..0563afda6 100644 --- a/TLM/TLM/Util/GeometryUtil.cs +++ b/TLM/TLM/Util/GeometryUtil.cs @@ -7,6 +7,7 @@ namespace TrafficManager.Util { using TrafficManager.UI; using UnityEngine; using TrafficManager.Util; + using TrafficManager.Util.Extensions; /// /// Helper functions to handle coordinates and transformations, as well as road geometry diff --git a/TLM/TLM/Manager/Impl/GetNodeSegmentIdsEnumerable.cs b/TLM/TLM/Util/Iterators/GetNodeSegmentIdsEnumerable.cs similarity index 93% rename from TLM/TLM/Manager/Impl/GetNodeSegmentIdsEnumerable.cs rename to TLM/TLM/Util/Iterators/GetNodeSegmentIdsEnumerable.cs index da5d9a0dd..226936178 100644 --- a/TLM/TLM/Manager/Impl/GetNodeSegmentIdsEnumerable.cs +++ b/TLM/TLM/Util/Iterators/GetNodeSegmentIdsEnumerable.cs @@ -1,7 +1,8 @@ -using System.Collections; -using System.Collections.Generic; +namespace TrafficManager.Util.Iterators { + using System.Collections; + using System.Collections.Generic; + using TrafficManager.Manager.Impl; -namespace TrafficManager.Manager.Impl { /// /// Struct enumerable to be returned from the GetNodeSegmentIds method. /// This implementation is just for perf optimizations and should be handled with care since it returns a mutable struct! diff --git a/TLM/TLM/Manager/Impl/GetNodeSegmentIdsEnumerator.cs b/TLM/TLM/Util/Iterators/GetNodeSegmentIdsEnumerator.cs similarity index 93% rename from TLM/TLM/Manager/Impl/GetNodeSegmentIdsEnumerator.cs rename to TLM/TLM/Util/Iterators/GetNodeSegmentIdsEnumerator.cs index c9cc24fe8..234ce0354 100644 --- a/TLM/TLM/Manager/Impl/GetNodeSegmentIdsEnumerator.cs +++ b/TLM/TLM/Util/Iterators/GetNodeSegmentIdsEnumerator.cs @@ -1,8 +1,9 @@ -using System; -using System.Collections; -using System.Collections.Generic; +namespace TrafficManager.Util.Iterators { + using System; + using System.Collections; + using System.Collections.Generic; + using TrafficManager.Manager.Impl; -namespace TrafficManager.Manager.Impl { /// /// Mutable struct enumerator to be returned from the GetNodeSegmentIds method. /// This implementation is just for perf optimizations and should be handled with care since it is a mutable struct! diff --git a/TLM/TLM/Manager/Impl/GetSegmentLaneIdsEnumerable.cs b/TLM/TLM/Util/Iterators/GetSegmentLaneIdsEnumerable.cs similarity index 92% rename from TLM/TLM/Manager/Impl/GetSegmentLaneIdsEnumerable.cs rename to TLM/TLM/Util/Iterators/GetSegmentLaneIdsEnumerable.cs index ef23cd5b9..b304b49e3 100644 --- a/TLM/TLM/Manager/Impl/GetSegmentLaneIdsEnumerable.cs +++ b/TLM/TLM/Util/Iterators/GetSegmentLaneIdsEnumerable.cs @@ -1,7 +1,8 @@ -using System.Collections; -using System.Collections.Generic; +namespace TrafficManager.Util.Iterators { + using System.Collections; + using System.Collections.Generic; + using TrafficManager.Manager.Impl; -namespace TrafficManager.Manager.Impl { /// /// Struct enumerable to be returned from the GetSegmentLaneIds method. /// This implementation is just for perf optimizations and should be handled with care since it returns a mutable struct! diff --git a/TLM/TLM/Manager/Impl/GetSegmentLaneIdsEnumerator.cs b/TLM/TLM/Util/Iterators/GetSegmentLaneIdsEnumerator.cs similarity index 92% rename from TLM/TLM/Manager/Impl/GetSegmentLaneIdsEnumerator.cs rename to TLM/TLM/Util/Iterators/GetSegmentLaneIdsEnumerator.cs index 7eb523e43..2e06d597a 100644 --- a/TLM/TLM/Manager/Impl/GetSegmentLaneIdsEnumerator.cs +++ b/TLM/TLM/Util/Iterators/GetSegmentLaneIdsEnumerator.cs @@ -1,8 +1,9 @@ -using System; -using System.Collections; -using System.Collections.Generic; +namespace TrafficManager.Util.Iterators { + using System; + using System.Collections; + using System.Collections.Generic; + using TrafficManager.Manager.Impl; -namespace TrafficManager.Manager.Impl { /// /// Mutable struct enumerator to be returned from the GetSegmentLaneIds method. /// This implementation is just for perf optimizations and should be handled with care since it is a mutable struct! diff --git a/TLM/TLM/Util/LaneUtil.cs b/TLM/TLM/Util/LaneUtil.cs new file mode 100644 index 000000000..1f89cfc62 --- /dev/null +++ b/TLM/TLM/Util/LaneUtil.cs @@ -0,0 +1,33 @@ +namespace TrafficManager.Util { + using TrafficManager.Util.Extensions; + public static class LaneUtil { + /// + /// gets the index of lane id or -1 if lane was not found + /// + public static int GetLaneIndex(uint laneId) { + ref NetLane netLane = ref laneId.ToLane(); + ref NetSegment netSegment = ref netLane.m_segment.ToSegment(); + var lanes = netSegment.Info?.m_lanes; + if (lanes != null) { + uint curLaneId = netSegment.m_lanes; + for (int laneIndex = 0; laneIndex < lanes.Length && curLaneId != 0; ++laneIndex) { + if (curLaneId == laneId) { + return laneIndex; + } + curLaneId = curLaneId.ToLane().m_nextLane; + } + } + + return -1; + } + + /// + /// slow iteration to find lane index + /// + public static NetInfo.Lane GetLaneInfo(uint laneId) { + int laneIndex = GetLaneIndex(laneId); + ushort segmentId = laneId.ToLane().m_segment; + return segmentId.ToSegment().GetLaneInfo(laneIndex); + } + } +} \ No newline at end of file diff --git a/TLM/TLM/Util/PlaceIntersectionUtil.cs b/TLM/TLM/Util/PlaceIntersectionUtil.cs index bd364ba34..24b40e989 100644 --- a/TLM/TLM/Util/PlaceIntersectionUtil.cs +++ b/TLM/TLM/Util/PlaceIntersectionUtil.cs @@ -5,6 +5,7 @@ namespace TrafficManager.Util { using TrafficManager.State.Asset; using TrafficManager.Util; using TrafficManager.Lifecycle; + using TrafficManager.Util.Extensions; public static class PlaceIntersectionUtil { ///maps old netowkr ids to new network ids diff --git a/TLM/TLM/Util/PriorityRoad.cs b/TLM/TLM/Util/PriorityRoad.cs index c322849b5..1179d0dad 100644 --- a/TLM/TLM/Util/PriorityRoad.cs +++ b/TLM/TLM/Util/PriorityRoad.cs @@ -8,6 +8,7 @@ namespace TrafficManager.Util { using TrafficManager.Manager.Impl; using TrafficManager.State; using TrafficManager.UI.SubTools.PrioritySigns; + using TrafficManager.Util.Extensions; using TrafficManager.Util.Record; using UnityEngine; using static TrafficManager.Util.SegmentTraverser; diff --git a/TLM/TLM/Util/Record/LaneArrowsRecord.cs b/TLM/TLM/Util/Record/LaneArrowsRecord.cs index f9e635008..77af23247 100644 --- a/TLM/TLM/Util/Record/LaneArrowsRecord.cs +++ b/TLM/TLM/Util/Record/LaneArrowsRecord.cs @@ -5,6 +5,7 @@ namespace TrafficManager.Util.Record { using TrafficManager.API.Traffic.Enums; using TrafficManager.Manager.Impl; using TrafficManager.State; + using TrafficManager.Util.Extensions; using static TrafficManager.Util.Shortcuts; [Serializable] diff --git a/TLM/TLM/Util/Record/LaneConnectionRecord.cs b/TLM/TLM/Util/Record/LaneConnectionRecord.cs index 9bbc5ef99..713a9cfaa 100644 --- a/TLM/TLM/Util/Record/LaneConnectionRecord.cs +++ b/TLM/TLM/Util/Record/LaneConnectionRecord.cs @@ -5,6 +5,7 @@ namespace TrafficManager.Util.Record { using System.Linq; using TrafficManager.Manager.Impl; using TrafficManager.State; + using TrafficManager.Util.Extensions; using static TrafficManager.Util.Shortcuts; [Serializable] diff --git a/TLM/TLM/Util/Record/NodeRecord.cs b/TLM/TLM/Util/Record/NodeRecord.cs index c13376e7a..89ee3ebaa 100644 --- a/TLM/TLM/Util/Record/NodeRecord.cs +++ b/TLM/TLM/Util/Record/NodeRecord.cs @@ -4,6 +4,7 @@ namespace TrafficManager.Util.Record { using TrafficManager.Manager.Impl; using static TrafficManager.Util.Shortcuts; using TrafficManager.State; + using TrafficManager.Util.Extensions; [Serializable] public class NodeRecord : IRecordable { diff --git a/TLM/TLM/Util/Record/SegmentRecord.cs b/TLM/TLM/Util/Record/SegmentRecord.cs index 6d0a6d511..98ca575c1 100644 --- a/TLM/TLM/Util/Record/SegmentRecord.cs +++ b/TLM/TLM/Util/Record/SegmentRecord.cs @@ -4,6 +4,7 @@ namespace TrafficManager.Util.Record { using System.Linq; using TrafficManager.Manager.Impl; using TrafficManager.State; + using TrafficManager.Util.Extensions; [Serializable] public class SegmentRecord : IRecordable { diff --git a/TLM/TLM/Util/Record/SpeedLimitLaneRecord.cs b/TLM/TLM/Util/Record/SpeedLimitLaneRecord.cs index d904bab91..057b8b15e 100644 --- a/TLM/TLM/Util/Record/SpeedLimitLaneRecord.cs +++ b/TLM/TLM/Util/Record/SpeedLimitLaneRecord.cs @@ -4,6 +4,7 @@ namespace TrafficManager.Util.Record { using TrafficManager.Manager.Impl; using static TrafficManager.Util.Shortcuts; using TrafficManager.State; + using TrafficManager.Util.Extensions; [Serializable] public class SpeedLimitLaneRecord : IRecordable { @@ -33,7 +34,7 @@ public void Transfer(Dictionary map) => public void Transfer(uint laneId) { ushort segmentId = laneId.ToLane().m_segment; - var laneInfo = GetLaneInfo(segmentId, LaneIndex); + var laneInfo = segmentId.ToSegment().GetLaneInfo(LaneIndex); SpeedLimitManager.Instance.SetLaneSpeedLimit( segmentId: segmentId, laneIndex: this.LaneIndex, diff --git a/TLM/TLM/Util/Record/TrafficRulesRecord.cs b/TLM/TLM/Util/Record/TrafficRulesRecord.cs index c2f36f107..71aad0a6d 100644 --- a/TLM/TLM/Util/Record/TrafficRulesRecord.cs +++ b/TLM/TLM/Util/Record/TrafficRulesRecord.cs @@ -6,6 +6,7 @@ namespace TrafficManager.Util.Record { using TrafficManager.Manager.Impl; using static Shortcuts; using TrafficManager.State; + using TrafficManager.Util.Extensions; [Serializable] public class TrafficRulesRecord : IRecordable { diff --git a/TLM/TLM/Util/Record/VehicleRestrictionsLaneRecord.cs b/TLM/TLM/Util/Record/VehicleRestrictionsLaneRecord.cs index 9dcee194e..f7535d1d9 100644 --- a/TLM/TLM/Util/Record/VehicleRestrictionsLaneRecord.cs +++ b/TLM/TLM/Util/Record/VehicleRestrictionsLaneRecord.cs @@ -4,6 +4,7 @@ namespace TrafficManager.Util.Record { using TrafficManager.API.Traffic.Enums; using TrafficManager.Manager.Impl; using TrafficManager.State; + using TrafficManager.Util.Extensions; using static TrafficManager.Util.Shortcuts; [Serializable] @@ -37,7 +38,7 @@ public void Transfer(Dictionary map) { } public void Transfer(ushort segmentId, byte laneIndex, uint laneId) { - var laneInfo = GetLaneInfo(segmentId, laneIndex); + var laneInfo = segmentId.ToSegment().GetLaneInfo(laneIndex); var segmentInfo = segmentId.ToSegment().Info; if (allowedVehicleTypes_ == null) { VehicleRestrictionsManager.Instance.ClearVehicleRestrictions(segmentId, laneIndex, laneId); diff --git a/TLM/TLM/Util/RoundaboutMassEdit.cs b/TLM/TLM/Util/RoundaboutMassEdit.cs index 50e662255..1ace93c36 100644 --- a/TLM/TLM/Util/RoundaboutMassEdit.cs +++ b/TLM/TLM/Util/RoundaboutMassEdit.cs @@ -12,6 +12,7 @@ namespace TrafficManager.Util { using UnityEngine; using static TrafficManager.Util.Shortcuts; using static UI.SubTools.LaneConnectorTool; + using TrafficManager.Util.Extensions; public class RoundaboutMassEdit { public static RoundaboutMassEdit Instance = new RoundaboutMassEdit(); diff --git a/TLM/TLM/Util/SegmentLaneTraverser.cs b/TLM/TLM/Util/SegmentLaneTraverser.cs index a95214ceb..2e46b00c5 100644 --- a/TLM/TLM/Util/SegmentLaneTraverser.cs +++ b/TLM/TLM/Util/SegmentLaneTraverser.cs @@ -2,6 +2,7 @@ namespace TrafficManager.Util { using System; using System.Collections.Generic; using TrafficManager.Manager.Impl; + using TrafficManager.Util.Extensions; using static SegmentTraverser; public class SegmentLaneTraverser { diff --git a/TLM/TLM/Util/SeparateTurningLanesUtil.cs b/TLM/TLM/Util/SeparateTurningLanesUtil.cs index 5e8ebe402..4b5837aeb 100644 --- a/TLM/TLM/Util/SeparateTurningLanesUtil.cs +++ b/TLM/TLM/Util/SeparateTurningLanesUtil.cs @@ -9,6 +9,7 @@ namespace TrafficManager.Util { using TrafficManager.API.Traffic.Enums; using TrafficManager.Manager.Impl; using TrafficManager.State; + using TrafficManager.Util.Extensions; using UnityEngine; using static TrafficManager.Util.Shortcuts; diff --git a/TLM/TLM/Util/Shortcuts.cs b/TLM/TLM/Util/Shortcuts.cs index d8935857b..e4939434a 100644 --- a/TLM/TLM/Util/Shortcuts.cs +++ b/TLM/TLM/Util/Shortcuts.cs @@ -2,8 +2,6 @@ namespace TrafficManager.Util { using System; using System.Collections.Generic; using System.Linq; - using System.Reflection; - using System.Diagnostics; using ColossalFramework; using ColossalFramework.Math; using CSUtil.Commons; @@ -11,6 +9,7 @@ namespace TrafficManager.Util { using TrafficManager.API.Traffic.Data; using TrafficManager.API.Traffic.Enums; using TrafficManager.Manager.Impl; + using TrafficManager.Util.Extensions; using UnityEngine; using ColossalFramework.UI; @@ -42,37 +41,14 @@ internal static void Swap(this List list, int index1, int index2) { list[index1] = list[index2]; list[index2] = temp; } - - private static NetNode[] _nodeBuffer = Singleton.instance.m_nodes.m_buffer; - - private static NetSegment[] _segBuffer = Singleton.instance.m_segments.m_buffer; - - private static NetLane[] _laneBuffer = Singleton.instance.m_lanes.m_buffer; - - private static Building[] _buildingBuffer = Singleton.instance.m_buildings.m_buffer; - - private static CitizenInstance[] _citizenInstanceBuffer = Singleton.instance.m_instances.m_buffer; - private static ExtSegmentEnd[] _segEndBuff => segEndMan.ExtSegmentEnds; internal static IExtSegmentEndManager segEndMan => Constants.ManagerFactory.ExtSegmentEndManager; internal static IExtSegmentManager segMan => Constants.ManagerFactory.ExtSegmentManager; - internal static ref NetNode ToNode(this ushort nodeId) => ref _nodeBuffer[nodeId]; - - internal static ref NetLane ToLane(this uint laneId) => ref _laneBuffer[laneId]; - - internal static ref NetSegment ToSegment(this ushort segmentId) => ref _segBuffer[segmentId]; - - internal static ref Building ToBuilding(this ushort buildingId) => ref _buildingBuffer[buildingId]; - - internal static ref CitizenInstance ToCitizenInstance(this ushort citizenInstance) => ref _citizenInstanceBuffer[citizenInstance]; - - internal static bool IsUndergroundNode(this ushort node) => (_nodeBuffer[node].m_flags & NetNode.Flags.Underground) != NetNode.Flags.None; - - internal static NetInfo.Lane GetLaneInfo(ushort segmentId, int laneIndex) => - segmentId.ToSegment().Info.m_lanes[laneIndex]; + [Obsolete] + internal static bool IsUndergroundNode(this ushort node) => node.ToNode().IsUnderground(); internal static ref ExtSegmentEnd GetSegEnd(ushort segmentId, ushort nodeId) => ref _segEndBuff[segEndMan.GetIndex(segmentId, nodeId)]; @@ -80,13 +56,9 @@ internal static ref ExtSegmentEnd GetSegEnd(ushort segmentId, ushort nodeId) => internal static ref ExtSegmentEnd GetSegEnd(ushort segmentId, bool startNode) => ref _segEndBuff[segEndMan.GetIndex(segmentId, startNode)]; - internal static ushort GetNodeId(this ref NetSegment segment, bool startNode) => - startNode ? segment.m_startNode : segment.m_endNode; - - internal static bool HasJunctionFlag(ushort nodeId) => HasJunctionFlag(ref nodeId.ToNode()); + [Obsolete] + internal static bool HasJunctionFlag(ushort nodeId) => nodeId.ToNode().IsJunction(); - internal static bool HasJunctionFlag(ref NetNode node) => - (node.m_flags & NetNode.Flags.Junction) != NetNode.Flags.None; internal static Func Int = (bool b) => b ? 1 : 0; diff --git a/TLM/TMPE.UnitTest/Util/GetNodeSegmentIdsEnumerableTests.cs b/TLM/TMPE.UnitTest/Util/GetNodeSegmentIdsEnumerableTests.cs index 90349ebca..b71efecdf 100644 --- a/TLM/TMPE.UnitTest/Util/GetNodeSegmentIdsEnumerableTests.cs +++ b/TLM/TMPE.UnitTest/Util/GetNodeSegmentIdsEnumerableTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using TrafficManager.Manager.Impl; +using TrafficManager.Util.Iterators; namespace TMUnitTest.Util { [TestClass]