private void UnregisterAllVehicles() { VehicleStateManager vehStateManager = VehicleStateManager.Instance; while (FirstRegisteredVehicleId != 0) { vehStateManager._GetVehicleState(FirstRegisteredVehicleId).Unlink(); } }
internal int GetRegisteredVehicleCount() { ushort vehicleId = FirstRegisteredVehicleId; int ret = 0; while (vehicleId != 0) { ++ret; vehicleId = VehicleStateManager._GetVehicleState(vehicleId).NextVehicleIdOnSegment; } return(ret); }
private void Link(SegmentEnd end) { ushort oldFirstRegVehicleId = end.FirstRegisteredVehicleId; if (oldFirstRegVehicleId != 0) { VehicleStateManager._GetVehicleState(oldFirstRegVehicleId).PreviousVehicleIdOnSegment = VehicleId; NextVehicleIdOnSegment = oldFirstRegVehicleId; } end.FirstRegisteredVehicleId = VehicleId; CurrentSegmentEnd = end; }
internal void Unlink() { VehicleStateManager vehStateManager = VehicleStateManager.Instance(); if (PreviousVehicleIdOnSegment != 0) { vehStateManager._GetVehicleState(PreviousVehicleIdOnSegment).NextVehicleIdOnSegment = NextVehicleIdOnSegment; } else if (CurrentSegmentEnd != null && CurrentSegmentEnd.FirstRegisteredVehicleId == VehicleId) { CurrentSegmentEnd.FirstRegisteredVehicleId = NextVehicleIdOnSegment; } if (NextVehicleIdOnSegment != 0) { vehStateManager._GetVehicleState(NextVehicleIdOnSegment).PreviousVehicleIdOnSegment = PreviousVehicleIdOnSegment; } NextVehicleIdOnSegment = 0; PreviousVehicleIdOnSegment = 0; CurrentSegmentEnd = null; }
/// <summary> /// Calculates for each segment the number of cars going to this segment. /// We use integer arithmetic for better performance. /// </summary> public Dictionary <ushort, uint> GetVehicleMetricGoingToSegment(bool includeStopped = true, byte?laneIndex = null, bool debug = false) { #if TRACE Singleton <CodeProfiler> .instance.Start("SegmentEnd.GetVehicleMetricGoingToSegment"); #endif VehicleManager vehicleManager = Singleton <VehicleManager> .instance; NetManager netManager = Singleton <NetManager> .instance; VehicleStateManager vehStateManager = VehicleStateManager.Instance(); Dictionary <ushort, uint> ret = includeStopped ? numVehiclesGoingToSegmentId : numVehiclesFlowingToSegmentId; for (var s = 0; s < 8; s++) { ushort segmentId = netManager.m_nodes.m_buffer[NodeId].GetSegment(s); if (segmentId == 0 || segmentId == SegmentId) { continue; } if (!ret.ContainsKey(segmentId)) { continue; } ret[segmentId] = 0; } #if DEBUGMETRIC if (debug) { Log._Debug($"GetVehicleMetricGoingToSegment: Segment {SegmentId}, Node {NodeId}. Target segments: {string.Join(", ", ret.Keys.Select(x => x.ToString()).ToArray())}, Registered Vehicles: {string.Join(", ", GetRegisteredVehicles().Select(x => x.Key.ToString()).ToArray())}"); } #endif ushort vehicleId = FirstRegisteredVehicleId; int numProcessed = 0; while (vehicleId != 0) { VehicleState state = vehStateManager._GetVehicleState(vehicleId); bool breakLoop = false; state.ProcessCurrentAndNextPathPosition(ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleId], delegate(ref Vehicle vehState, ref PathUnit.Position curPos, ref PathUnit.Position nextPos) { if (!state.CheckValidity(ref vehState)) { RequestCleanup(); return; } #if DEBUGMETRIC if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: Checking vehicle {vehicleId}"); } #endif if (!ret.ContainsKey(nextPos.m_segment)) { #if DEBUGMETRIC if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: ret does not contain key for target segment {pos.TargetSegmentId}"); } #endif return; } if (!includeStopped && vehState.GetLastFrameVelocity().magnitude < TrafficPriorityManager.maxStopVelocity) { #if DEBUGMETRIC if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: Vehicle {vehicleId}: too slow"); } #endif ++numProcessed; return; } if (laneIndex != null && curPos.m_lane != laneIndex) { #if DEBUGMETRIC if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: Vehicle {vehicleId}: Lane index mismatch (expected: {laneIndex}, was: {pos.SourceLaneIndex})"); } #endif return; } if (Options.simAccuracy <= 2) { uint avgSegmentLength = (uint)netManager.m_segments.m_buffer[SegmentId].m_averageLength; uint normLength = Math.Min(100u, (uint)(state.TotalLength * 100u) / avgSegmentLength); #if DEBUGMETRIC if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: NormLength of vehicle {vehicleId}: {avgSegmentLength} -> {normLength}"); } #endif #if DEBUGMETRIC if (debug) { ret[pos.TargetSegmentId] += 1; } else { ret[pos.TargetSegmentId] = Math.Min(100u, ret[pos.TargetSegmentId] + normLength); } #else ret[nextPos.m_segment] += normLength; #endif } else { ret[nextPos.m_segment] += 10; } ++numProcessed; if ((Options.simAccuracy >= 3 && numProcessed >= 3) || (Options.simAccuracy == 2 && numProcessed >= 5) || (Options.simAccuracy == 1 && numProcessed >= 10)) { breakLoop = true; return; } #if DEBUGMETRIC if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: Vehicle {vehicleId}: *added*! Coming from segment {SegmentId}, lane {laneIndex}. Going to segment {pos.TargetSegmentId}, lane {pos.TargetLaneIndex}, minSpeed={TrafficPriority.maxStopVelocity}, speed={speed}"); } #endif }); if (breakLoop) { break; } vehicleId = state.NextVehicleIdOnSegment; } #if DEBUGMETRIC if (debug) { Log._Debug($"GetVehicleMetricGoingToSegment: Calculation completed. {string.Join(", ", ret.Select(x => x.Key.ToString() + "=" + x.Value.ToString()).ToArray())}"); } #endif #if TRACE Singleton <CodeProfiler> .instance.Stop("SegmentEnd.GetVehicleMetricGoingToSegment"); #endif return(ret); }
/// <summary> /// Calculates for each segment the number of cars going to this segment. /// We use integer arithmetic for better performance. /// </summary> public Dictionary <ushort, uint> GetVehicleMetricGoingToSegment(bool includeStopped = true, byte?laneIndex = null, bool debug = false) { VehicleManager vehicleManager = Singleton <VehicleManager> .instance; NetManager netManager = Singleton <NetManager> .instance; VehicleStateManager vehStateManager = VehicleStateManager.Instance; Dictionary <ushort, uint> ret = includeStopped ? numVehiclesGoingToSegmentId : numVehiclesFlowingToSegmentId; foreach (SegmentEndGeometry endGeo in NodeGeometry.Get(NodeId).SegmentEndGeometries) { if (endGeo == null) { continue; } if (!endGeo.IncomingOneWay && !ret.ContainsKey(endGeo.SegmentId)) { #if DEBUG Log._Debug($"SegmentEnd.GetVehicleMetricGoingToSegment: return dict does not contain entry for segment {endGeo.SegmentId}"); #endif } ret[endGeo.SegmentId] = 0; } #if DEBUGMETRIC if (debug) { Log._Debug($"GetVehicleMetricGoingToSegment: Segment {SegmentId}, Node {NodeId}. Target segments: {string.Join(", ", ret.Keys.Select(x => x.ToString()).ToArray())}"); } #endif ushort vehicleId = FirstRegisteredVehicleId; int numProcessed = 0; while (vehicleId != 0) { VehicleState state = vehStateManager._GetVehicleState(vehicleId); bool breakLoop = false; state.ProcessCurrentAndNextPathPosition(ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleId], delegate(ref Vehicle vehState, ref PathUnit.Position curPos, ref PathUnit.Position nextPos) { if (!state.CheckValidity(ref vehState)) { RequestCleanup(); return; } #if DEBUGMETRIC2 if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: Checking vehicle {vehicleId}"); } #endif if (!ret.ContainsKey(nextPos.m_segment)) { #if DEBUGMETRIC2 if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: ret does not contain key for target segment {nextPos.m_segment}"); } #endif return; } if (!includeStopped && vehState.GetLastFrameVelocity().sqrMagnitude < TrafficPriorityManager.MAX_SQR_STOP_VELOCITY) { #if DEBUGMETRIC2 if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: Vehicle {vehicleId}: too slow"); } #endif ++numProcessed; return; } if (laneIndex != null && curPos.m_lane != laneIndex) { #if DEBUGMETRIC2 if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: Vehicle {vehicleId}: Lane index mismatch (expected: {laneIndex}, was: {curPos.m_lane})"); } #endif return; } if (Options.simAccuracy <= 2) { uint avgSegmentLength = (uint)netManager.m_segments.m_buffer[SegmentId].m_averageLength; uint normLength = 100u; if (avgSegmentLength > 0) { normLength = Math.Min(100u, (uint)(state.TotalLength * 100u) / avgSegmentLength); } #if DEBUGMETRIC if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: NormLength of vehicle {vehicleId}: {avgSegmentLength} -> {normLength}"); } #endif ret[nextPos.m_segment] += normLength; } else { ret[nextPos.m_segment] += 10; } ++ret[nextPos.m_segment]; ++numProcessed; if ((Options.simAccuracy >= 3 && numProcessed >= 3) || (Options.simAccuracy == 2 && numProcessed >= 5) || (Options.simAccuracy == 1 && numProcessed >= 10)) { breakLoop = true; return; } #if DEBUGMETRIC2 if (debug) { Log._Debug($" GetVehicleMetricGoingToSegment: Vehicle {vehicleId}: *added*! Coming from segment {SegmentId}, lane {laneIndex}. Going to segment {nextPos.m_segment}, lane {nextPos.m_lane}"); } #endif }); if (breakLoop) { break; } vehicleId = state.NextVehicleIdOnSegment; } #if DEBUGMETRIC if (debug) { Log._Debug($"GetVehicleMetricGoingToSegment: Calculation completed. {string.Join(", ", ret.Select(x => x.Key.ToString() + "=" + x.Value.ToString()).ToArray())}"); } #endif return(ret); }