/// <summary> /// Constructor /// </summary> /// <param name="ourExit"></param> public IntersectionMonitor(ITraversableWaypoint ourExit, ArbiterIntersection ai, VehicleState ourState, IConnectAreaWaypoints desired) { // set intersection this.Intersection = ai; // create monitors this.AllMonitors = new List<IIntersectionQueueable>(); this.PriorityMonitors = new List<IIntersectionQueueable>(); this.IntersectionPriorityQueue = new List<IIntersectionQueueable>(); this.InsideIntersectionVehicles = new List<IntersectionVehicleMonitor>(); this.NonStopPriorityAreas = new List<IDominantMonitor>(); this.PreviouslyWaiting = new List<IDominantMonitor>(); this.AllMonitors = new List<IIntersectionQueueable>(); this.cooldownTimer = new Stopwatch(); #region Stopped Exits // get ours IIntersectionQueueable ourMonitor = null; // get stopped exits foreach(ArbiterStoppedExit ase in ai.StoppedExits) { // add a monitor SubmissiveEntryMonitor sem = new SubmissiveEntryMonitor(this, ase.Waypoint, ase.Waypoint.Equals(ourExit)); // add to monitors PriorityMonitors.Add(sem); // check not our if(!sem.IsOurs) { // initial update sem.Update(ourState); // check if add first if(!sem.Clear(ourState)) IntersectionPriorityQueue.Add(sem); } else { // set ours ourMonitor = sem; this.OurMonitor = ourMonitor; } } // check if our monitor exists if (ourMonitor != null) { // add ours this.IntersectionPriorityQueue.Add(ourMonitor); } #endregion #region Priority Areas Over Interconnect // check contains priority lane for this if (ai.PriorityLanes.ContainsKey(desired.ToInterconnect)) { // loop through all other priority monitors over this interconnect foreach (IntersectionInvolved ii in ai.PriorityLanes[desired.ToInterconnect]) { // check area type if lane if (ii.Area is ArbiterLane) { // add lane to non stop priority areas this.NonStopPriorityAreas.Add(new DominantLaneEntryMonitor(this, ii)); } // otherwise is zone else if (ii.Area is ArbiterZone) { // add lane to non stop priority areas this.NonStopPriorityAreas.Add( new DominantZoneEntryMonitor((ArbiterPerimeterWaypoint)ii.Exit, ((ArbiterInterconnect)desired), false, this, ii)); } else { throw new ArgumentException("unknown intersection involved area", "ii"); } } } // otherwise be like, wtf? else { ArbiterOutput.Output("Exception: intersection: " + this.Intersection.ToString() + " priority lanes does not contain interconnect: " + desired.ToString() + " returning can go"); //ArbiterOutput.Output("Error in intersection monitor!!!!!!!!!@Q!!, desired interconnect: " + desired.ToInterconnect.ToString() + " not found in intersection: " + ai.ToString() + ", not setting any dominant monitors"); } #endregion #region Entry Area if (desired.FinalGeneric is ArbiterWaypoint) { this.EntryAreaMonitor = new LaneEntryAreaMonitor((ArbiterWaypoint)desired.FinalGeneric); } else if (desired.FinalGeneric is ArbiterPerimeterWaypoint) { this.EntryAreaMonitor = new ZoneAreaEntryMonitor((ArbiterPerimeterWaypoint)desired.FinalGeneric, (ArbiterInterconnect)desired, false, this, new IntersectionInvolved(ourExit, ((ArbiterPerimeterWaypoint)desired.FinalGeneric).Perimeter.Zone, ((ArbiterInterconnect)desired).TurnDirection)); } else { throw new Exception("unhandled desired interconnect final type"); } #endregion #region Our Monitor // check ours if (ourExit is ArbiterWaypoint) { this.OurMonitor = new DominantLaneEntryMonitor(this, new IntersectionInvolved(ourExit, ((ArbiterWaypoint)ourExit).Lane, desired is ArbiterInterconnect ? ((ArbiterInterconnect)desired).TurnDirection : ArbiterTurnDirection.Straight)); } else if (ourExit is ArbiterPerimeterWaypoint) { // add lane to non stop priority areas this.OurMonitor = new DominantZoneEntryMonitor((ArbiterPerimeterWaypoint)desired.InitialGeneric, ((ArbiterInterconnect)desired), true, this, new IntersectionInvolved(ourExit, ((ArbiterPerimeterWaypoint)desired.InitialGeneric).Perimeter.Zone, ((ArbiterInterconnect)desired).TurnDirection)); } #endregion // add to all this.AllMonitors.AddRange(this.PriorityMonitors); foreach (IIntersectionQueueable iiq in this.NonStopPriorityAreas) this.AllMonitors.Add(iiq); this.AllMonitors.Add(this.EntryAreaMonitor); // update all this.Update(ourState); // check if we need to populate previously waiting if(this.OurMonitor is IDominantMonitor) { // cast our IDominantMonitor ours = (IDominantMonitor)this.OurMonitor; // loop through to determine those previously waiting foreach (IDominantMonitor idm in this.NonStopPriorityAreas) { if(idm.Waypoint != null && !idm.Waypoint.IsStop && idm.WaitingTimerRunning) this.PreviouslyWaiting.Add(idm); } } }
/// <summary> /// Constructor /// </summary> /// <param name="ourExit"></param> public IntersectionMonitor(ITraversableWaypoint ourExit, ArbiterIntersection ai, VehicleState ourState, IConnectAreaWaypoints desired) { // set intersection this.Intersection = ai; // create monitors this.AllMonitors = new List <IIntersectionQueueable>(); this.PriorityMonitors = new List <IIntersectionQueueable>(); this.IntersectionPriorityQueue = new List <IIntersectionQueueable>(); this.InsideIntersectionVehicles = new List <IntersectionVehicleMonitor>(); this.NonStopPriorityAreas = new List <IDominantMonitor>(); this.PreviouslyWaiting = new List <IDominantMonitor>(); this.AllMonitors = new List <IIntersectionQueueable>(); this.cooldownTimer = new Stopwatch(); #region Stopped Exits // get ours IIntersectionQueueable ourMonitor = null; // get stopped exits foreach (ArbiterStoppedExit ase in ai.StoppedExits) { // add a monitor SubmissiveEntryMonitor sem = new SubmissiveEntryMonitor(this, ase.Waypoint, ase.Waypoint.Equals(ourExit)); // add to monitors PriorityMonitors.Add(sem); // check not our if (!sem.IsOurs) { // initial update sem.Update(ourState); // check if add first if (!sem.Clear(ourState)) { IntersectionPriorityQueue.Add(sem); } } else { // set ours ourMonitor = sem; this.OurMonitor = ourMonitor; } } // check if our monitor exists if (ourMonitor != null) { // add ours this.IntersectionPriorityQueue.Add(ourMonitor); } #endregion #region Priority Areas Over Interconnect // check contains priority lane for this if (ai.PriorityLanes.ContainsKey(desired.ToInterconnect)) { // loop through all other priority monitors over this interconnect foreach (IntersectionInvolved ii in ai.PriorityLanes[desired.ToInterconnect]) { // check area type if lane if (ii.Area is ArbiterLane) { // add lane to non stop priority areas this.NonStopPriorityAreas.Add(new DominantLaneEntryMonitor(this, ii)); } // otherwise is zone else if (ii.Area is ArbiterZone) { // add lane to non stop priority areas this.NonStopPriorityAreas.Add( new DominantZoneEntryMonitor((ArbiterPerimeterWaypoint)ii.Exit, ((ArbiterInterconnect)desired), false, this, ii)); } else { throw new ArgumentException("unknown intersection involved area", "ii"); } } } // otherwise be like, wtf? else { ArbiterOutput.Output("Exception: intersection: " + this.Intersection.ToString() + " priority lanes does not contain interconnect: " + desired.ToString() + " returning can go"); //ArbiterOutput.Output("Error in intersection monitor!!!!!!!!!@Q!!, desired interconnect: " + desired.ToInterconnect.ToString() + " not found in intersection: " + ai.ToString() + ", not setting any dominant monitors"); } #endregion #region Entry Area if (desired.FinalGeneric is ArbiterWaypoint) { this.EntryAreaMonitor = new LaneEntryAreaMonitor((ArbiterWaypoint)desired.FinalGeneric); } else if (desired.FinalGeneric is ArbiterPerimeterWaypoint) { this.EntryAreaMonitor = new ZoneAreaEntryMonitor((ArbiterPerimeterWaypoint)desired.FinalGeneric, (ArbiterInterconnect)desired, false, this, new IntersectionInvolved(ourExit, ((ArbiterPerimeterWaypoint)desired.FinalGeneric).Perimeter.Zone, ((ArbiterInterconnect)desired).TurnDirection)); } else { throw new Exception("unhandled desired interconnect final type"); } #endregion #region Our Monitor // check ours if (ourExit is ArbiterWaypoint) { this.OurMonitor = new DominantLaneEntryMonitor(this, new IntersectionInvolved(ourExit, ((ArbiterWaypoint)ourExit).Lane, desired is ArbiterInterconnect ? ((ArbiterInterconnect)desired).TurnDirection : ArbiterTurnDirection.Straight)); } else if (ourExit is ArbiterPerimeterWaypoint) { // add lane to non stop priority areas this.OurMonitor = new DominantZoneEntryMonitor((ArbiterPerimeterWaypoint)desired.InitialGeneric, ((ArbiterInterconnect)desired), true, this, new IntersectionInvolved(ourExit, ((ArbiterPerimeterWaypoint)desired.InitialGeneric).Perimeter.Zone, ((ArbiterInterconnect)desired).TurnDirection)); } #endregion // add to all this.AllMonitors.AddRange(this.PriorityMonitors); foreach (IIntersectionQueueable iiq in this.NonStopPriorityAreas) { this.AllMonitors.Add(iiq); } this.AllMonitors.Add(this.EntryAreaMonitor); // update all this.Update(ourState); // check if we need to populate previously waiting if (this.OurMonitor is IDominantMonitor) { // cast our IDominantMonitor ours = (IDominantMonitor)this.OurMonitor; // loop through to determine those previously waiting foreach (IDominantMonitor idm in this.NonStopPriorityAreas) { if (idm.Waypoint != null && !idm.Waypoint.IsStop && idm.WaitingTimerRunning) { this.PreviouslyWaiting.Add(idm); } } } }