Skip to content

Commit 0131e7f

Browse files
authored
Merge pull request #638 from kianzarrin/623-reset-lane-arrows
Added interface to reset lane arrows back to default. Ignores lanes with outgoing lane connections. I remove lane flags, call NetAI to recalculate lanes and finally push lane changes. UI to delete lane arrows : select lane arrow tool -> select segment end -> press Reset all button [hot key is del].
2 parents 630a26b + 3d1b176 commit 0131e7f

File tree

9 files changed

+175
-30
lines changed

9 files changed

+175
-30
lines changed

TLM/TLM/Manager/Impl/LaneArrowManager.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace TrafficManager.Manager.Impl {
1111
using TrafficManager.State;
1212
using TrafficManager.Util;
1313
using UnityEngine;
14+
using static TrafficManager.Util.Shortcuts;
1415

1516
public class LaneArrowManager
1617
: AbstractGeometryObservingManager,
@@ -54,7 +55,7 @@ public LaneArrows GetFinalLaneArrows(uint laneId) {
5455
public bool SetLaneArrows(uint laneId,
5556
LaneArrows flags,
5657
bool overrideHighwayArrows = false) {
57-
if (Flags.setLaneArrowFlags(laneId, flags, overrideHighwayArrows)) {
58+
if (Flags.SetLaneArrowFlags(laneId, flags, overrideHighwayArrows)) {
5859
OnLaneChange(laneId);
5960
return true;
6061
}
@@ -111,6 +112,43 @@ public bool ToggleLaneArrows(uint laneId,
111112
return false;
112113
}
113114

115+
/// <summary>
116+
/// Resets lane arrows to their default value for the given segment end.
117+
/// </summary>
118+
/// <param name="segmentId">segment to reset</param>
119+
/// <param name="startNode">determines the segment end to reset. if <c>null</c>
120+
/// both ends are reset</param>
121+
public void ResetLaneArrows(ushort segmentId, bool? startNode = null) {
122+
foreach (var lane in netService.GetSortedLanes(
123+
segmentId,
124+
ref GetSeg(segmentId),
125+
startNode,
126+
LANE_TYPES,
127+
VEHICLE_TYPES)) {
128+
ResetLaneArrows(lane.laneId);
129+
}
130+
}
131+
132+
/// <summary>
133+
/// Resets lane arrows to their default value for the given lane
134+
/// </summary>
135+
public void ResetLaneArrows(uint laneId) {
136+
if (Flags.ResetLaneArrowFlags(laneId)) {
137+
RecalculateFlags(laneId);
138+
OnLaneChange(laneId);
139+
}
140+
}
141+
142+
private static void RecalculateFlags(uint laneId) {
143+
NetLane[] laneBuffer = NetManager.instance.m_lanes.m_buffer;
144+
ushort segmentId = laneBuffer[laneId].m_segment;
145+
NetAI ai = GetSeg(segmentId).Info.m_netAI;
146+
#if DEBUGFLAGS
147+
Log._Debug($"Flags.RecalculateFlags: Recalculateing lane arrows of segment {segmentId}.");
148+
#endif
149+
ai.UpdateLanes(segmentId, ref GetSeg(segmentId), true);
150+
}
151+
114152
private void OnLaneChange(uint laneId) {
115153
Services.NetService.ProcessLane(
116154
laneId,
@@ -126,7 +164,7 @@ private void OnLaneChange(uint laneId) {
126164
}
127165

128166
protected override void HandleInvalidSegment(ref ExtSegment seg) {
129-
Flags.resetSegmentArrowFlags(seg.segmentId);
167+
Flags.ResetSegmentArrowFlags(seg.segmentId);
130168
}
131169

132170
protected override void HandleValidSegment(ref ExtSegment seg) { }

TLM/TLM/Manager/Impl/LaneConnectionManager.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace TrafficManager.Manager.Impl {
1111
using TrafficManager.State.ConfigData;
1212
using TrafficManager.State;
1313
using UnityEngine;
14+
using static TrafficManager.Util.Shortcuts;
1415

1516
public class LaneConnectionManager
1617
: AbstractGeometryObservingManager,
@@ -60,6 +61,35 @@ public bool AreLanesConnected(uint sourceLaneId, uint targetLaneId, bool sourceS
6061
&& connectedLanes.Any(laneId => laneId == targetLaneId);
6162
}
6263

64+
65+
/// <summary>
66+
/// determines whether or not the input lane is heading toward a start node.
67+
/// </summary>
68+
/// <returns>true if heading toward and start node.</returns>
69+
private bool IsHeadingTowardsStartNode(uint sourceLaneId) {
70+
NetLane[] laneBuffer = NetManager.instance.m_lanes.m_buffer;
71+
ushort segmentId = laneBuffer[sourceLaneId].m_segment;
72+
NetSegment segment = GetSeg(segmentId);
73+
uint laneId = segment.m_lanes;
74+
bool inverted = (segment.m_flags & NetSegment.Flags.Invert) != 0;
75+
76+
foreach (var laneInfo in segment.Info.m_lanes) {
77+
if (laneId == sourceLaneId) {
78+
return (laneInfo.m_direction == NetInfo.Direction.Forward) ^ !inverted;
79+
}
80+
laneId = laneBuffer[laneId].m_nextLane;
81+
}
82+
throw new Exception($"Unreachable code. sourceLaneId:{sourceLaneId}, segmentId:{segmentId} ");
83+
}
84+
85+
public bool HasConnections(uint sourceLaneId) {
86+
if (!Options.laneConnectorEnabled) {
87+
return false;
88+
}
89+
return HasConnections(sourceLaneId, IsHeadingTowardsStartNode(sourceLaneId));
90+
}
91+
92+
6393
/// <summary>
6494
/// Determines if the given lane has outgoing connections
6595
/// </summary>

TLM/TLM/Manager/Impl/RoutingManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2166,7 +2166,7 @@ protected override void HandleInvalidSegment(ref ExtSegment seg) {
21662166
Log._Debug($"RoutingManager.HandleInvalidSegment({seg.segmentId}) called.");
21672167
}
21682168

2169-
Flags.removeHighwayLaneArrowFlagsAtSegment(seg.segmentId);
2169+
Flags.RemoveHighwayLaneArrowFlagsAtSegment(seg.segmentId);
21702170
ResetRoutingData(seg.segmentId);
21712171
}
21722172

TLM/TLM/Manager/Impl/SpeedLimitManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ public void ClearCurrentSpeedLimits(NetInfo info) {
395395
continue;
396396
}
397397

398-
Flags.removeLaneSpeedLimit(laneId);
398+
Flags.RemoveLaneSpeedLimit(laneId);
399399
}
400400
}
401401

TLM/TLM/Manager/Impl/TrafficLightManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ public bool LoadData(string data) {
257257
continue;
258258
}
259259

260-
Flags.setNodeTrafficLight(nodeId, flag > 0);
260+
Flags.SetNodeTrafficLight(nodeId, flag > 0);
261261
} catch (Exception e) {
262262
// ignore as it's probably bad save data.
263263
Log.Error($"Error setting the NodeTrafficLights: " + e.ToString());

TLM/TLM/Manager/Impl/VehicleRestrictionsManager.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ internal bool SetAllowedVehicleTypes(ushort segmentId,
378378
allowedTypes &= GetBaseMask(
379379
segmentInfo.m_lanes[laneIndex],
380380
VehicleRestrictionsMode.Configured); // ensure default base mask
381-
Flags.setLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, allowedTypes);
381+
Flags.SetLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, allowedTypes);
382382

383383
NotifyStartEndNode(segmentId);
384384

@@ -424,7 +424,7 @@ public void AddAllowedType(ushort segmentId,
424424
allowedTypes &= GetBaseMask(
425425
segmentInfo.m_lanes[laneIndex],
426426
VehicleRestrictionsMode.Configured); // ensure default base mask
427-
Flags.setLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, allowedTypes);
427+
Flags.SetLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, allowedTypes);
428428
NotifyStartEndNode(segmentId);
429429

430430
if (OptionsManager.Instance.MayPublishSegmentChanges()) {
@@ -467,7 +467,7 @@ public void RemoveAllowedType(ushort segmentId,
467467
allowedTypes &= GetBaseMask(
468468
segmentInfo.m_lanes[laneIndex],
469469
VehicleRestrictionsMode.Configured); // ensure default base mask
470-
Flags.setLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, allowedTypes);
470+
Flags.SetLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, allowedTypes);
471471
NotifyStartEndNode(segmentId);
472472

473473
if (OptionsManager.Instance.MayPublishSegmentChanges()) {
@@ -744,7 +744,7 @@ public void NotifyStartEndNode(ushort segmentId) {
744744
}
745745

746746
protected override void HandleInvalidSegment(ref ExtSegment seg) {
747-
Flags.resetSegmentVehicleRestrictions(seg.segmentId);
747+
Flags.ResetSegmentVehicleRestrictions(seg.segmentId);
748748
ClearCache(seg.segmentId);
749749
}
750750

@@ -773,7 +773,7 @@ public bool LoadData(List<Configuration.LaneVehicleTypes> data) {
773773
$"{laneVehicleTypes.vehicleTypes}, masked = {maskedType}");
774774
#endif
775775
if (maskedType != baseMask) {
776-
Flags.setLaneAllowedVehicleTypes(laneVehicleTypes.laneId, maskedType);
776+
Flags.SetLaneAllowedVehicleTypes(laneVehicleTypes.laneId, maskedType);
777777
} else {
778778
#if DEBUGLOAD
779779
Log._Debug($"Masked type does not differ from base type. Ignoring.");

TLM/TLM/State/Flags.cs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// #define DEBUGFLAGS
1+
// #define DEBUGFLAGS
22

33
namespace TrafficManager.State {
44
using ColossalFramework;
@@ -10,6 +10,7 @@ namespace TrafficManager.State {
1010
using TrafficManager.API.Traffic.Enums;
1111
using TrafficManager.Manager.Impl;
1212
using TrafficManager.State.ConfigData;
13+
using static TrafficManager.Util.Shortcuts;
1314

1415
[Obsolete]
1516
public class Flags {
@@ -166,7 +167,7 @@ public static bool MayHaveTrafficLight(ushort nodeId) {
166167
}
167168

168169
[Obsolete]
169-
public static bool setNodeTrafficLight(ushort nodeId, bool flag) {
170+
public static bool SetNodeTrafficLight(ushort nodeId, bool flag) {
170171
if (nodeId <= 0) {
171172
return false;
172173
}
@@ -206,7 +207,7 @@ public static bool setNodeTrafficLight(ushort nodeId, bool flag) {
206207
[Obsolete]
207208
[UsedImplicitly]
208209
// Not used
209-
internal static bool isNodeTrafficLight(ushort nodeId) {
210+
internal static bool IsNodeTrafficLight(ushort nodeId) {
210211
if (nodeId <= 0) {
211212
return false;
212213
}
@@ -513,7 +514,7 @@ public static void SetLaneSpeedLimit(uint laneId, float? speedLimit) {
513514
}
514515
}
515516

516-
public static void removeLaneSpeedLimit(uint laneId) {
517+
public static void RemoveLaneSpeedLimit(uint laneId) {
517518
SetLaneSpeedLimit(laneId, null);
518519
}
519520

@@ -614,7 +615,7 @@ public static void SetLaneSpeedLimit(ushort segmentId,
614615
}
615616
}
616617

617-
public static void setLaneAllowedVehicleTypes(uint laneId, ExtVehicleType vehicleTypes) {
618+
public static void SetLaneAllowedVehicleTypes(uint laneId, ExtVehicleType vehicleTypes) {
618619
if (laneId <= 0) {
619620
return;
620621
}
@@ -642,7 +643,7 @@ public static void setLaneAllowedVehicleTypes(uint laneId, ExtVehicleType vehicl
642643

643644
while (laneIndex < segmentInfo.m_lanes.Length && curLaneId != 0u) {
644645
if (curLaneId == laneId) {
645-
setLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, vehicleTypes);
646+
SetLaneAllowedVehicleTypes(segmentId, laneIndex, laneId, vehicleTypes);
646647
return;
647648
}
648649

@@ -651,7 +652,7 @@ public static void setLaneAllowedVehicleTypes(uint laneId, ExtVehicleType vehicl
651652
}
652653
}
653654

654-
public static void setLaneAllowedVehicleTypes(ushort segmentId,
655+
public static void SetLaneAllowedVehicleTypes(ushort segmentId,
655656
uint laneIndex,
656657
uint laneId,
657658
ExtVehicleType vehicleTypes)
@@ -696,7 +697,7 @@ public static void setLaneAllowedVehicleTypes(ushort segmentId,
696697
laneAllowedVehicleTypesArray[segmentId][laneIndex] = vehicleTypes;
697698
}
698699

699-
public static void resetSegmentVehicleRestrictions(ushort segmentId) {
700+
public static void ResetSegmentVehicleRestrictions(ushort segmentId) {
700701
if (segmentId <= 0) {
701702
return;
702703
}
@@ -707,7 +708,7 @@ public static void resetSegmentVehicleRestrictions(ushort segmentId) {
707708
laneAllowedVehicleTypesArray[segmentId] = null;
708709
}
709710

710-
public static void resetSegmentArrowFlags(ushort segmentId) {
711+
public static void ResetSegmentArrowFlags(ushort segmentId) {
711712
if (segmentId <= 0) {
712713
return;
713714
}
@@ -732,7 +733,24 @@ public static void resetSegmentArrowFlags(ushort segmentId) {
732733
}
733734
}
734735

735-
public static bool setLaneArrowFlags(uint laneId,
736+
/// <summary>
737+
/// removes the custom lane arrow flags. requires post recalculation.
738+
/// </summary>
739+
/// <param name="laneId"></param>
740+
/// <returns><c>true</c>on success, <c>false</c> otherwise</returns>
741+
public static bool ResetLaneArrowFlags(uint laneId) {
742+
#if DEBUGFLAGS
743+
Log._Debug($"Flags.resetLaneArrowFlags: Resetting lane arrows of lane {laneId}.");
744+
#endif
745+
if (LaneConnectionManager.Instance.HasConnections(laneId)) {
746+
return false;
747+
}
748+
749+
laneArrowFlags[laneId] = null;
750+
return true;
751+
}
752+
753+
public static bool SetLaneArrowFlags(uint laneId,
736754
LaneArrows flags,
737755
bool overrideHighwayArrows = false) {
738756
#if DEBUGFLAGS
@@ -1079,7 +1097,7 @@ public static void RemoveLaneArrowFlags(uint laneId) {
10791097
}
10801098
}
10811099

1082-
internal static void removeHighwayLaneArrowFlagsAtSegment(ushort segmentId) {
1100+
internal static void RemoveHighwayLaneArrowFlagsAtSegment(ushort segmentId) {
10831101
NetSegment[] segmentsBuffer = Singleton<NetManager>.instance.m_segments.m_buffer;
10841102

10851103
if ((segmentsBuffer[segmentId].m_flags &

0 commit comments

Comments
 (0)