private void ApplyVehicleTypeToTrailers() { VehicleManager vehManager = Singleton <VehicleManager> .instance; VehicleStateManager vehStateManager = VehicleStateManager.Instance(); #if DEBUG //Log._Debug($"Applying VehicleType to trailes of vehicle {VehicleId} to {VehicleType}."); #endif // apply vehicle type to all leading/trailing vehicles ushort otherVehicleId = vehManager.m_vehicles.m_buffer[VehicleId].m_leadingVehicle; while (otherVehicleId != 0) { #if DEBUG //Log._Debug($" Setting VehicleType of leader {otherVehicleId} to {VehicleType}."); #endif VehicleState otherState = vehStateManager._GetVehicleState(otherVehicleId); otherState.Valid = true; otherState.VehicleType = VehicleType; otherVehicleId = vehManager.m_vehicles.m_buffer[otherVehicleId].m_leadingVehicle; } otherVehicleId = vehManager.m_vehicles.m_buffer[VehicleId].m_trailingVehicle; while (otherVehicleId != 0) { #if DEBUG //Log._Debug($" Setting VehicleType of trailer {otherVehicleId} to {VehicleType}."); #endif VehicleState otherState = vehStateManager._GetVehicleState(otherVehicleId); otherState.Valid = true; otherState.VehicleType = VehicleType; otherVehicleId = vehManager.m_vehicles.m_buffer[otherVehicleId].m_trailingVehicle; } }
internal void SimulationStep() { if (cleanupRequested) { VehicleManager vehManager = Singleton <VehicleManager> .instance; VehicleStateManager vehStateManager = VehicleStateManager.Instance(); #if DEBUG //Log._Debug($"Cleanup of SegmentEnd {SegmentId} @ {NodeId} requested. Performing cleanup now."); #endif ushort vehicleId = FirstRegisteredVehicleId; while (vehicleId != 0) { VehicleState state = vehStateManager._GetVehicleState(vehicleId); bool removeVehicle = false; if (!state.Valid) { removeVehicle = true; } ushort nextVehicleId = state.NextVehicleIdOnSegment; if (removeVehicle) { state.Unlink(); } vehicleId = nextVehicleId; } cleanupRequested = false; } Housekeeping(); }
private void UnregisterAllVehicles() { VehicleStateManager vehStateManager = VehicleStateManager.Instance(); while (FirstRegisteredVehicleId != 0) { vehStateManager._GetVehicleState(FirstRegisteredVehicleId).Unlink(); } }
private void Link(SegmentEnd end) { ushort oldFirstRegVehicleId = end.FirstRegisteredVehicleId; if (oldFirstRegVehicleId != 0) { VehicleStateManager.Instance()._GetVehicleState(oldFirstRegVehicleId).PreviousVehicleIdOnSegment = VehicleId; NextVehicleIdOnSegment = oldFirstRegVehicleId; } end.FirstRegisteredVehicleId = VehicleId; CurrentSegmentEnd = end; }
internal int GetRegisteredVehicleCount() { VehicleStateManager vehStateManager = VehicleStateManager.Instance(); ushort vehicleId = FirstRegisteredVehicleId; int ret = 0; while (vehicleId != 0) { ++ret; vehicleId = vehStateManager._GetVehicleState(vehicleId).NextVehicleIdOnSegment; } return(ret); }
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); }