Skip to content

Commit

Permalink
NetUtil extended
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorPhilipp committed Apr 9, 2017
2 parents 63e3586 + e7e7f80 commit a4382a0
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 12 deletions.
17 changes: 17 additions & 0 deletions TLM/TLM/Util/LogicUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TrafficManager.Util {
public static class LogicUtil {
public static bool CheckFlags(uint flags, uint flagMask, uint? expectedResult=null) {
uint res = flags & flagMask;
if (expectedResult == null) {
return res != 0;
} else {
return (res & (uint)expectedResult) == (uint)expectedResult;
}
}
}
}
120 changes: 108 additions & 12 deletions TLM/TLM/Util/NetUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,8 @@ public static class NetUtil {
public delegate void NetLaneHandler(uint laneId, ref NetLane lane);
public delegate void NetSegmentLaneHandler(uint laneId, ref NetLane lane, NetInfo.Lane laneInfo, ushort segmentId, ref NetSegment segment, byte laneIndex);

static bool IsSegmentValid(ref NetSegment segment) {
return (segment.m_flags & (NetSegment.Flags.Created | NetSegment.Flags.Deleted)) == NetSegment.Flags.Created;
}

public static bool IsSegmentValid(ushort segmentId) {
return IsSegmentValid(ref Singleton<NetManager>.instance.m_segments.m_buffer[segmentId]);
return CheckSegmentFlags(segmentId, NetSegment.Flags.Created | NetSegment.Flags.Deleted, NetSegment.Flags.Created);
}

public static void ProcessSegment(ushort segmentId, NetSegmentHandler handler) {
Expand All @@ -28,12 +24,8 @@ public static void ProcessSegment(ushort segmentId, ref NetSegment segment, NetS
handler(segmentId, ref segment);
}

static bool IsNodeValid(ref NetNode node) {
return (node.m_flags & (NetNode.Flags.Created | NetNode.Flags.Deleted)) == NetNode.Flags.Created;
}

public static bool IsNodeValid(ushort nodeId) {
return IsNodeValid(ref Singleton<NetManager>.instance.m_nodes.m_buffer[nodeId]);
return CheckNodeFlags(nodeId, NetNode.Flags.Created | NetNode.Flags.Deleted, NetNode.Flags.Created);
}

public static void ProcessNode(ushort nodeId, NetNodeHandler handler) {
Expand All @@ -44,15 +36,24 @@ public static void ProcessNode(ushort nodeId, ref NetNode node, NetNodeHandler h
handler(nodeId, ref node);
}

[Obsolete]
static bool IsLaneValid(ref NetLane lane) {
if ((lane.m_flags & (uint)(NetLane.Flags.Created | NetLane.Flags.Deleted)) != (uint)NetLane.Flags.Created) {
return false;
}
return IsSegmentValid(lane.m_segment);
}

public static bool IsLaneValid(uint laneId) {
return IsLaneValid(ref Singleton<NetManager>.instance.m_lanes.m_buffer[laneId]);
if (!CheckLaneFlags(laneId, NetLane.Flags.Created | NetLane.Flags.Deleted, NetLane.Flags.Created)) {
return false;
}

bool ret = false;
ProcessLane(laneId, delegate(uint lId, ref NetLane lane) {
ret = IsSegmentValid(lane.m_segment);
});
return ret;
}

public static void ProcessLane(uint laneId, NetLaneHandler handler) {
Expand Down Expand Up @@ -96,5 +97,100 @@ public static NetInfo.Direction GetSegmentEndDirection(ushort segmentId, ref Net

return dir;
}

public static bool CheckNodeFlags(ushort nodeId, NetNode.Flags flagMask, NetNode.Flags? expectedResult=null) {
bool ret = false;
ProcessNode(nodeId, delegate (ushort nId, ref NetNode node) {
ret = LogicUtil.CheckFlags((uint)node.m_flags, (uint)flagMask, (uint?)expectedResult);
});
return ret;
}

public static bool CheckSegmentFlags(ushort segmentId, NetSegment.Flags flagMask, NetSegment.Flags? expectedResult=null) {
bool ret = false;
ProcessSegment(segmentId, delegate (ushort sId, ref NetSegment segment) {
ret = LogicUtil.CheckFlags((uint)segment.m_flags, (uint)flagMask, (uint?)expectedResult);
});
return ret;
}

public static bool CheckLaneFlags(uint laneId, NetLane.Flags flagMask, NetLane.Flags? expectedResult=null) {
bool ret = false;
ProcessLane(laneId, delegate (uint lId, ref NetLane lane) {
ret = LogicUtil.CheckFlags((uint)lane.m_flags, (uint)flagMask, (uint?)expectedResult);
});
return ret;
}

public struct LanePos {
public uint laneId;
public byte laneIndex;
public float position;

public LanePos(uint laneId, byte laneIndex, float position) {
this.laneId = laneId;
this.laneIndex = laneIndex;
this.position = position;
}
}

/// <summary>
/// Assembles a geometrically sorted list of lanes for the given segment.
/// If the <paramref name="startNode"/> parameter is set only lanes supporting traffic to flow towards the given node are added to the list, otherwise all matched lanes are added.
/// </summary>
/// <param name="segmentId">segment id</param>
/// <param name="segment">segment data</param>
/// <param name="startNode">reference node (optional)</param>
/// <param name="laneTypeFilter">lane type filter, lanes must match this filter mask</param>
/// <param name="vehicleTypeFilter">vehicle type filter, lanes must match this filter mask</param>
/// <param name="reverse">if true, lanes are ordered from right to left (relative to the segment's start node / the given node), otherwise from left to right</param>
/// <returns>sorted list of lanes for the given segment</returns>
public static IList<LanePos> GetSortedVehicleLanes(ushort segmentId, ref NetSegment segment, bool? startNode, NetInfo.LaneType? laneTypeFilter = null, VehicleInfo.VehicleType? vehicleTypeFilter = null, bool reverse = false) { // TODO refactor together with getSegmentNumVehicleLanes, especially the vehicle type and lane type checks
NetManager netManager = Singleton<NetManager>.instance;
var laneList = new List<LanePos>();

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));
}

curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane;
++laneIndex;
}

laneList.Sort(delegate (LanePos x, LanePos y) {
if (x.position == y.position) {
return 0;
}

if ((x.position < y.position) == (sortDir == NetInfo.Direction.Forward)) {
return -1;
}
return 1;
});
return laneList;
}
}
}

0 comments on commit a4382a0

Please sign in to comment.