/* * Copyright (c) 2005-2006 Erik Tigerholm * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ using System; using System.Collections.Generic; using System.Text; namespace OpenTraffic.Model.Simulator.Queue { class Node : OpenTraffic.Model.Simulator.INodeSimulator { private bool fast = false; private OpenTraffic.Model.IntersectionNode node; private Random rand; private Dictionary> vehicles; private List links; private ILinkSimulator[] ls; public OpenTraffic.Model.IntersectionNode NetworkNode { get { return node; } } public Node(OpenTraffic.Model.IntersectionNode n, bool hetrogen) { fast = hetrogen; this.node = n; vehicles = null; initVehicles(); ls = new ILinkSimulator[n.LinksIn.Count]; int i = 0; foreach (OpenTraffic.Model.TrafficModelLink l in n.LinksIn) { ls[i++] = l.Simulator; } links = new List(); Clear(); } public static void MoveVehicleToNextLink(Vehicle v, float rate, Result.ResultData res) { v.GetLink().Simulator.Add(v, v.LastTimePassedNode + rate, rate, res); } public void Add(float time, Turning t, Vehicle v, Result.ResultData res) { v.LastTimePassedNode = time; if (t.Rate == 0) MoveVehicleToNextLink(v, t.Rate, res); else { LinkedList vList; vehicles.TryGetValue(t, out vList); if (vList == null) { vList = new LinkedList(); vehicles.Add(t, vList); } vList.AddLast(v); } } private void initVehicles() { foreach (OpenTraffic.Model.TrafficModelLink l in node.LinksIn) { foreach (Turning t in l.Turnings) { if (t.Rate != 0.0f) { vehicles = new Dictionary>(); return; } } } } public void Clear() { rand = new Random(node.Id); } public bool PreSimulate(float startTime, float stopTime, Result.ResultData result, TrafficModel m) { SimulateTurning(stopTime, result); if (!fast) { links.Clear(); for (int i = 0; i < ls.Length; i++) { ILinkSimulator s = ls[i]; if (s.PreSimulate(startTime, stopTime, result, m)) { // links.Add(s); } } } // links = null; return true; } public bool Simulate(float startTime, float stopTime, Result.ResultData result, TrafficModel m) { // if (!fast) { links = new List(); foreach (ILinkSimulator sl in this.ls) { links.Add(sl); } while (links.Count != 0) { int pos = rand.Next(links.Count); if (!links[pos].Simulate(startTime, stopTime, result, m)) { links.RemoveAt(pos); }; } } return true; } private void SimulateTurning(float stopTime, Result.ResultData result) { if (vehicles != null) { foreach (KeyValuePair> kv in vehicles) { while (kv.Value.Count != 0 && (kv.Value.First.Value.LastTimePassedNode + kv.Key.Rate) < stopTime) { MoveVehicleToNextLink(kv.Value.First.Value, kv.Key.Rate, result); kv.Value.RemoveFirst(); } } } } } }