private void ServiceFloorRequestsInDownwardDirection() { FloorRequest nextRequestBelow = GetNextRequestBelow(); if (null == nextRequestBelow) { return; } if (nextRequestBelow.Floor != CurrentFloor) { Descend(); return; } if (nextRequestBelow.Direction != Direction.Up) { Floor stopFloor = nextRequestBelow.Floor; _downDirectionQueue.Remove(nextRequestBelow); StopAtFloor(stopFloor); } if (ShouldReverseDirections()) { ReverseDirectionOfTravel(); } }
private void ServiceFloorRequestInUpwardDirection() { FloorRequest nextRequestAbove = GetNextRequestAbove(); if (null == nextRequestAbove) { return; } if (nextRequestAbove.Floor != CurrentFloor) { Ascend(); return; } if (nextRequestAbove.Direction != Direction.Down) { Floor stopFloor = nextRequestAbove.Floor; _upDirectionQueue.Remove(nextRequestAbove); StopAtFloor(stopFloor); } if (ShouldReverseDirections()) { ReverseDirectionOfTravel(); } }
private void AddFloorRequest(FloorRequest request) { _log.Info($"Elevator {Id} received floor request {request}."); StringBuilder sb = new StringBuilder($"Adding Floor Request: {request} to "); string queueContents; switch (DetermineRequestQueue(request)) { case Direction.Up: _upDirectionQueue.Add(request); sb.Append("up direction queue"); queueContents = _upDirectionQueue.ToString(); break; case Direction.Down: _downDirectionQueue.Add(request); sb.Append("down direction queue"); queueContents = _downDirectionQueue.ToString(); break; default: throw new InvalidOperationException("Invalid direction request queue!"); } sb.Append($" for elevator {Id}. Queue contains: {queueContents}."); _log.Debug(sb.ToString()); }
void Run() { // This is the main loop for the ElevatorController thread. It attempts to service // requests from the queue in order. If one can't be serviced, the thread sleeps // for 1 second, then tries again. m_running = true; while (m_running) { while (m_requests.Count > 0) { bool handled = false; lock (m_requests) { FloorRequest req = m_requests.Peek(); // Peek at next floor request int idx = FindBestElevator(req.m_floor, req.m_dir); if (idx >= 0) { m_requests.Dequeue(); // Dequeue the request and send to elevator Elevators[idx].RequestFloor(req.m_floor, req.m_dir); handled = true; } } // If none handled, sleep for a bit to allow elevators to continue their work. if (!handled) { Thread.Sleep(c_defaultRunIntervalMsecs); } } } }
private Direction DetermineRequestQueue(FloorRequest request) { if (request.Direction == Direction.None) { return(request.Floor > CurrentFloor ? Direction.Up : Direction.Down); } return(request.Direction); }
public int CompareTo(FloorRequest other) { var compareResult = Floor.CompareTo(other.Floor); if (compareResult == 0 && Direction != Direction.None && other.Direction != Direction.None) { compareResult = Direction.CompareTo(other.Direction); } return(compareResult); }
private FloorRequest GetNextRequestBelow() { FloorRequest nextRequestBelow = FloorsBelowCurrent(_downDirectionQueue)?.FirstOrDefault(); if (null == nextRequestBelow) { FloorRequest lowestUpRequest = _upDirectionQueue.Peek(); nextRequestBelow = (lowestUpRequest?.Floor <= CurrentFloor) ? lowestUpRequest : null; } return(nextRequestBelow); }
private FloorRequest GetNextRequestAbove() { var nextRequestAbove = FloorsAboveCurrent(_upDirectionQueue)?.FirstOrDefault(); if (null == nextRequestAbove) { FloorRequest highestDownRequest = _downDirectionQueue.Peek(); nextRequestAbove = (highestDownRequest?.Floor >= CurrentFloor) ? highestDownRequest : null; } return(nextRequestAbove); }
public override bool Equals(object obj) { if (obj == null) { return(ReferenceEquals(this, obj)); } FloorRequest request = obj as FloorRequest; if (null != request) { return(Equals(request)); } return(false); }
public int CompareTo(object obj) { if (obj == null) { return(1); } FloorRequest fr = obj as FloorRequest; if (fr != null) { return(CompareTo(fr)); } throw new ArgumentException($"Object with type {obj.GetType().Name} is not a FloorRequest!"); }
public int RequestElevator(FloorRequest request) { //TODO: Use extension method on IElevator[] //TODO: Find nearest elevator moving in the correct direction and request floor on that elevator // Simple algorithm: Find first idle elevator or first one traveling in the desired direction and dispatch request. // If none meet these requirements, pick one at random. // Future possible optimizations: // Find nearest elevator moving in the correct direction and request floor on that elevator // Find least busy elevator and dispatch request var firstIdleElevator = _elevators.FirstOrDefault(e => (e.IsIdle || (e.DirectionOfTravel == request.Direction))); IElevator target = firstIdleElevator != null ? firstIdleElevator : GetRandomElevator(); _log.Debug($"Dispatching floor request {request} to elevator {target.Id}."); target.RequestFloor(request); return(target.Id); }
public void RequestFloor(FloorRequest request) { AddFloorRequest(request); }
public bool Equals(FloorRequest other) { return(CompareTo(other) == 0); }