/// <summary> /// Builds Creates Path for TransportLineAI /// </summary> /// <param name="path"></param> /// <param name="startPosA"></param> /// <param name="startPosB"></param> /// <param name="endPosA"></param> /// <param name="endPosB"></param> /// <param name="vehicleType"></param> /// <param name="skipQueue"></param> /// <returns>bool</returns> public bool CreateTransportLinePath( out uint path, PathUnit.Position startPosA, PathUnit.Position startPosB, PathUnit.Position endPosA, PathUnit.Position endPosB, VehicleInfo.VehicleType vehicleType, bool skipQueue) { PathCreationArgs args = new PathCreationArgs { extPathType = ExtPathType.None, extVehicleType = ExtVehicleManager.ConvertToExtVehicleType(vehicleType), vehicleId = 0, spawned = true, buildIndex = Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA = startPosA, startPosB = startPosB, endPosA = endPosA, endPosB = endPosB, vehiclePosition = default,
/// <summary> /// Calculates for each segment the number of cars going to this segment. /// We use integer arithmetic for better performance. /// </summary> public IDictionary <ushort, uint>[] MeasureOutgoingVehicles( bool includeStopped = true, bool logDebug = false) { // VehicleManager vehicleManager = Singleton<VehicleManager>.instance; // NetManager netManager = Singleton<NetManager>.instance; ExtVehicleManager vehStateManager = ExtVehicleManager.Instance; IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager; // TODO pre-calculate this uint avgSegLen = (uint)SegmentId.ToSegment().m_averageLength; Dictionary <ushort, uint>[] ret = includeStopped ? numVehiclesGoingToSegmentId : numVehiclesMovingToSegmentId; // reset for (byte laneIndex = 0; laneIndex < ret.Length; ++laneIndex) { IDictionary <ushort, uint> laneMetrics = ret[laneIndex]; foreach (ushort key in laneMetrics.Keys.ToList()) { laneMetrics[key] = 0; } } Log._DebugIf( logDebug, () => $"GetVehicleMetricGoingToSegment: Segment {SegmentId}, Node {NodeId}, " + $"includeStopped={includeStopped}."); int endIndex = segEndMan.GetIndex(SegmentId, StartNode); ushort vehicleId = segEndMan.ExtSegmentEnds[endIndex].firstVehicleId; int numProcessed = 0; int numIter = 0; var maxVehicleCount = VehicleManager.instance.m_vehicles.m_buffer.Length; while (vehicleId != 0) { ref Vehicle vehicle = ref vehicleId.ToVehicle(); MeasureOutgoingVehicle( logDebug, ret, includeStopped, avgSegLen, vehicleId, ref vehicle, ref vehStateManager.ExtVehicles[vehicleId], ref numProcessed); if ((Options.simulationAccuracy <= SimulationAccuracy.Low && numProcessed >= 3) || (Options.simulationAccuracy == SimulationAccuracy.Medium && numProcessed >= 5) || (Options.simulationAccuracy == SimulationAccuracy.High && numProcessed >= 10)) { break; } vehicleId = vehStateManager.ExtVehicles[vehicleId].nextVehicleIdOnSegment; if (++numIter > maxVehicleCount) { CODebugBase <LogChannel> .Error( LogChannel.Core, $"Invalid list detected!\n{Environment.StackTrace}"); break; } }
/// <summary> /// Calculates for each segment the number of cars going to this segment. /// We use integer arithmetic for better performance. /// </summary> public IDictionary <ushort, uint>[] MeasureOutgoingVehicles( bool includeStopped = true, bool logDebug = false) { // VehicleManager vehicleManager = Singleton<VehicleManager>.instance; // NetManager netManager = Singleton<NetManager>.instance; ExtVehicleManager vehStateManager = ExtVehicleManager.Instance; IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager; // TODO pre-calculate this uint avgSegLen = (uint)SegmentId.ToSegment().m_averageLength; IDictionary <ushort, uint>[] ret = includeStopped ? numVehiclesGoingToSegmentId : numVehiclesMovingToSegmentId; // reset for (byte laneIndex = 0; laneIndex < ret.Length; ++laneIndex) { IDictionary <ushort, uint> laneMetrics = ret[laneIndex]; foreach (KeyValuePair <ushort, uint> e in laneMetrics) { laneMetrics[e.Key] = 0; } } Log._DebugIf( logDebug, () => $"GetVehicleMetricGoingToSegment: Segment {SegmentId}, Node {NodeId}, " + $"includeStopped={includeStopped}."); int endIndex = segEndMan.GetIndex(SegmentId, StartNode); ushort vehicleId = segEndMan.ExtSegmentEnds[endIndex].firstVehicleId; int numProcessed = 0; int numIter = 0; while (vehicleId != 0) { Constants.ServiceFactory.VehicleService.ProcessVehicle( vehicleId, (ushort vId, ref Vehicle veh) => { MeasureOutgoingVehicle( logDebug, ret, includeStopped, avgSegLen, vehicleId, ref veh, ref vehStateManager.ExtVehicles[vehicleId], ref numProcessed); return(true); }); if ((Options.simulationAccuracy <= SimulationAccuracy.Low && numProcessed >= 3) || (Options.simulationAccuracy == SimulationAccuracy.Medium && numProcessed >= 5) || (Options.simulationAccuracy == SimulationAccuracy.High && numProcessed >= 10)) { break; } vehicleId = vehStateManager.ExtVehicles[vehicleId].nextVehicleIdOnSegment; if (++numIter > Constants.ServiceFactory.VehicleService.MaxVehicleCount) { CODebugBase <LogChannel> .Error( LogChannel.Core, $"Invalid list detected!\n{Environment.StackTrace}"); break; } } if (logDebug) { string SelectFun(IDictionary <ushort, uint> e) => "[" + string.Join( ", ", e.Select(x => x.Key.ToString() + "=" + x.Value.ToString()).ToArray()) + "]"; string result = string.Join(", ", ret.Select(SelectFun).ToArray()); Log._Debug("GetVehicleMetricGoingToSegment: Calculation completed. " + result); } return(ret); }
/// <summary> /// Calculates for each segment the number of cars going to this segment. /// We use integer arithmetic for better performance. /// </summary> public IDictionary <ushort, uint>[] MeasureOutgoingVehicles(bool includeStopped = true, bool debug = false) { //VehicleManager vehicleManager = Singleton<VehicleManager>.instance; //NetManager netManager = Singleton<NetManager>.instance; ExtVehicleManager vehStateManager = ExtVehicleManager.Instance; IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager; // TODO pre-calculate this uint avgSegLen = 0; Constants.ServiceFactory.NetService.ProcessSegment(SegmentId, delegate(ushort segmentId, ref NetSegment segment) { avgSegLen = (uint)segment.m_averageLength; return(true); }); IDictionary <ushort, uint>[] ret = includeStopped ? numVehiclesGoingToSegmentId : numVehiclesMovingToSegmentId; // reset for (byte laneIndex = 0; laneIndex < ret.Length; ++laneIndex) { IDictionary <ushort, uint> laneMetrics = ret[laneIndex]; foreach (KeyValuePair <ushort, uint> e in laneMetrics) { laneMetrics[e.Key] = 0; } } #if DEBUGMETRIC if (debug) { Log._Debug($"GetVehicleMetricGoingToSegment: Segment {SegmentId}, Node {NodeId}, includeStopped={includeStopped}."); } #endif int endIndex = segEndMan.GetIndex(SegmentId, StartNode); ushort vehicleId = segEndMan.ExtSegmentEnds[endIndex].firstVehicleId; int numProcessed = 0; int numIter = 0; while (vehicleId != 0) { Constants.ServiceFactory.VehicleService.ProcessVehicle(vehicleId, delegate(ushort vId, ref Vehicle veh) { MeasureOutgoingVehicle(debug, ret, includeStopped, avgSegLen, vehicleId, ref veh, ref vehStateManager.ExtVehicles[vehicleId], ref numProcessed); return(true); }); vehicleId = vehStateManager.ExtVehicles[vehicleId].nextVehicleIdOnSegment; if (++numIter > Constants.ServiceFactory.VehicleService.MaxVehicleCount) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } #if DEBUGMETRIC if (debug) { Log._Debug($"GetVehicleMetricGoingToSegment: Calculation completed. {string.Join(", ", ret.Select(e => "[" + string.Join(", ", e.Select(x => x.Key.ToString() + "=" + x.Value.ToString()).ToArray()) + "]").ToArray())}"); } #endif return(ret); }