private void ScheduleTrip(Patron patron) { Trip last; /* Backfill the schedule until the Patron's request can be fulfilled, * if at all possible given known set of constraints. */ while ((last = _scheduledTrips .Where(t => t.IsNorthbound == patron.IsNorthbound) .OrderBy(t => t.DepartureTimeMinutes).LastOrDefault()) .CannotBeScheduled(patron, GetStopIntervalsMinutes)) { TripConstraint constraint; var nextDepartureTimeMinutes = GetNextDepartureTimeMinutes(last, patron, out constraint); // It is not possible to fulfill the Patron's itinerary given the allowable constraints. if (nextDepartureTimeMinutes == null) break; var trip = new Trip(constraint, nextDepartureTimeMinutes.Value); _scheduledTrips.Add(trip); } // Because Patron may have jumped into the queue midstream. patron.Itinerary = _scheduledTrips.First( t => t.CanBeScheduled(patron, GetStopIntervalsMinutes)); }
// ReSharper disable SuggestBaseTypeForParameter /// <summary> /// /// </summary> /// <param name="trip"></param> /// <param name="patron"></param> /// <param name="constraint"></param> /// <returns></returns> /// <remarks>This was another impacted area where not only calculating the desired /// departure time, but also knowing about the associated constraint, was desirable.</remarks> private int? GetNextDepartureTimeMinutes(Trip trip, Patron patron, out TripConstraint constraint) { // Should work for both Northbound (true/false), inverse of which is Southbound. constraint = Constraints.Single(t => t.IsNorthbound == patron.IsNorthbound); if (trip == null) return constraint.FirstDepartureTimeMinutes; var dtm = trip.DepartureTimeMinutes; // Which closing the loop the refactor should be relatively painless after all. var result = dtm + constraint.Frequencies.GetWaitTimeMinutes(dtm); return result > constraint.MaxAllowableDepartureTimeMinutes ? (int?) null : result; }