namespace OpenTraffic.Model.Simulator.Queue { using System.Collections.Generic; using OpenTraffic.Model.Result; class FastLink : Link { public FastLink(OpenTraffic.Model.TrafficModelLink link, bool giveaway, bool oneClass, bool shockwave) : base(link, giveaway, oneClass, shockwave) { } public override bool PreSimulate(float startTime, float stopTime, ResultData result, TrafficModel model) { cachedNumberFreeSlots = FreeSlots; updateShockwave(startTime); if (startTime > nextSwitch) { estimatedFlow = this.carPassedFlowEstimated / (startTime - (nextSwitch - timeStep)); nextSwitch = startTime + timeStep; carPassedFlowEstimated = 0; } MoveAllVehiclesToQueuePart(startTime, stopTime, result); bool ok = numberVehiclesInQueue > 0; if (ok) { maxCarsToLeave += trafficModelLink.SaturationExitFlow * (stopTime - startTime); } else { maxCarsToLeave = 0; } return false; } public override bool Simulate(float startTime, float stopTime, ResultData result, TrafficModel model) { if (queue.Count == 0) return false; if (IsFull()) return false; if (queue.Count == 1) { KeyValuePair kv; IEnumerator> q = queue.GetEnumerator(); q.MoveNext(); kv = q.Current; q = null; Turning t = kv.Key; FastLink l = (FastLink)t.Origin.Simulator; while (l.HasWaitingVehicles(stopTime, kv.Value)) { l.MoveVehicleToNextLinkFromQueue(t, startTime, result, queue); if (IsFull()) return false; } } else { List possible = new List(); foreach (KeyValuePair kv in queue) { Turning t = kv.Key; FastLink l = (FastLink)t.Origin.Simulator; if (l.HasWaitingVehicles(stopTime, kv.Value)) { possible.Add(t); } } if (possible.Count == 0) return false; while (true) { Turning t = possible[rand.Next(possible.Count)]; FastLink l = (FastLink)t.Origin.Simulator; l.MoveVehicleToNextLinkFromQueue(t, startTime, result, queue); TurnQueue q; queue.TryGetValue(t, out q); if (!l.HasWaitingVehicles(stopTime, q)) possible.Remove(t); if (possible.Count == 0 || IsFull()) return false; } } return false; } public bool HasWaitingVehicles(float stopTime, TurnQueue q) { // First car not yet reached flare(?) if (q == null) return false; if (giveaway && maxCarsToLeave < 1) return false; return q.HasWaitingVehicles(stopTime, vehicleLeft + vehicleLookBack); } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")] protected override TurnQueue GetQueue(Turning t) { FastLink fl = (FastLink)t.Destination.Simulator; TurnQueue q = null; if (fl.queue.TryGetValue(t, out q)) return q; q = new TurnQueue(t); fl.queue.Add(t, q); return q; } } }