public void ProcessQueuedShipment() { try { if (_queueShipment.Count() > 0) { while (_queueShipment.Count() > 0) { Shipment shipment = _queueShipment.Dequeue(); var station = LookupCache.GetInstance().GetStation(shipment.SourceStation.StationId); station.DeliverShipmentToStation(shipment); StationShipmentEventArgs args = new StationShipmentEventArgs(shipment.SourceStation.StationId, shipment.DestinationStation.StationId); args.Message = shipment + " Shipment queued at " + shipment.SourceStation; args.DeliveredShipment = shipment; OnShipmentQueued(this, args); } } _queueShipmentSynchronizer.WaitOne(); ProcessQueuedShipment(); } catch (Exception) { throw; } }
private void QueueArrivedShipment(object sender, StationShipmentEventArgs eventArgs) { try { Station sourceStation = LookupCache.GetInstance().GetStation(eventArgs.SourceStationNumber); Station destinationStation = LookupCache.GetInstance().GetStation(eventArgs.DestinationStationNumber); Shipment shipment = new Shipment(sourceStation, destinationStation); _queueShipment.Enqueue(shipment); _queueShipmentSynchronizer.Set(); } catch (Exception) { throw; } }
public void Start() { Random randomStationNumberGenerator = new Random(); // Start trains at random stations foreach (var train in LookupCache.GetInstance().GetTrains()) { int stationId = randomStationNumberGenerator.Next(1, LookupCache.GetInstance().StationCount() + 1); TrainTrack trainTrack = LookupCache.GetInstance().GetNextTrack(stationId); TrainCurrentLocation trainCurrentLocation = new TrainCurrentLocation(); trainCurrentLocation.Train = train; trainCurrentLocation.Track = trainTrack; trainCurrentLocation.DistanceLeft = trainCurrentLocation.Track.TrackLength; trainCurrentLocation.Train.CurrentRunningStatus = TrainRunningStatus.Waiting; _lstTrainsToStart.Add(trainCurrentLocation); } }
private void ProcessShipmentAtStation() { _signalEvent.WaitOne(); // Process Running Trains List <TrainCurrentLocation> lstToMovetoUnLoadingQueue = new List <TrainCurrentLocation>(); foreach (var train in _dicTrainCurrentLocations.Keys) { var trainCurrentLocation = _dicTrainCurrentLocations[train]; if (train.CurrentRunningStatus == TrainRunningStatus.Running && trainCurrentLocation.DistanceLeft <= 0) { lstToMovetoUnLoadingQueue.Add(trainCurrentLocation); } else if (train.CurrentRunningStatus == TrainRunningStatus.Running) { trainCurrentLocation.DistanceLeft -= train.SpeedFactor; if (trainCurrentLocation.DistanceLeft <= 0) { trainCurrentLocation.DistanceLeft = 0; } else { TrainProcessEventArgs args = new TrainProcessEventArgs(); args.Message = trainCurrentLocation.Train + " has to travel distance : " + trainCurrentLocation.DistanceLeft; args.TrainId = trainCurrentLocation.Train.ToString(); args.TrackId = trainCurrentLocation.Track.ToString(); OnTrainProgressed(this, args); } } } List <TrainCurrentLocation> lstToAddToLoadingTrainsQueue = new List <TrainCurrentLocation>(); // Unloading shipment foreach (var trainCurrentLocation in _lstOfTrainsForUnloading) { if (trainCurrentLocation.Train.IsAnyShipmentForStation(trainCurrentLocation.Track.DestinationStationId)) { var shipment = trainCurrentLocation.Train.UnloadShipment(trainCurrentLocation.Track.DestinationStationId); TrainProcessEventArgs args = new TrainProcessEventArgs(); args.Message = "<<" + shipment + " shipment unloaded at " + shipment.DestinationStation; args.TrainId = trainCurrentLocation.Train.ToString(); args.TrackId = trainCurrentLocation.Track.ToString(); args.DeliveredShipment = shipment; OnTrainShipmentUnloadEvent(this, args); } else { trainCurrentLocation.Train.CurrentRunningStatus = TrainRunningStatus.LoadingShipment; TrainProcessEventArgs args = new TrainProcessEventArgs(); args.Message = "There is no shipment to unload at Station" + trainCurrentLocation.Track.DestinationStationId; args.TrainId = trainCurrentLocation.Train.ToString(); args.TrackId = trainCurrentLocation.Track.ToString(); OnTrainOtherEvent(this, args); lstToAddToLoadingTrainsQueue.Add(trainCurrentLocation); } } List <TrainCurrentLocation> lstToAddToWaitingTrainsQueue = new List <TrainCurrentLocation>(); // loading shipment foreach (var trainCurrentLocation in _lstOfTrainsForLoading) { Station station = LookupCache.GetInstance().GetStation(trainCurrentLocation.Track.DestinationStationId); if (!station.IsStationShipmentEmpty() && !trainCurrentLocation.Train.IsShipmentCapacityFull()) { Shipment shipment = station.DeliverShipmentToTrain(); trainCurrentLocation.Train.LoadShipment(shipment); TrainProcessEventArgs args = new TrainProcessEventArgs(); args.Message = ">> " + shipment + " loaded from " + shipment.DestinationStation; args.TrainId = trainCurrentLocation.Train.ToString(); args.TrackId = trainCurrentLocation.Track.ToString(); args.DeliveredShipment = shipment; OnTrainShipmentLoadEvent(this, args); } else if (station.IsStationShipmentEmpty()) { TrainProcessEventArgs args = new TrainProcessEventArgs(); args.Message = station + " has no items to load into train"; args.TrainId = trainCurrentLocation.Train.ToString(); args.TrackId = trainCurrentLocation.Track.ToString(); OnTrainOtherEvent(this, args); lstToAddToWaitingTrainsQueue.Add(trainCurrentLocation); trainCurrentLocation.Train.CurrentRunningStatus = TrainRunningStatus.Stopped; } else if (trainCurrentLocation.Train.IsShipmentCapacityFull()) { TrainProcessEventArgs args = new TrainProcessEventArgs(); args.Message = "Train shipment capacity is full now."; args.TrainId = trainCurrentLocation.Train.ToString(); args.TrackId = trainCurrentLocation.Track.ToString(); OnTrainOtherEvent(this, args); lstToAddToWaitingTrainsQueue.Add(trainCurrentLocation); trainCurrentLocation.Train.CurrentRunningStatus = TrainRunningStatus.Stopped; } } List <TrainCurrentLocation> _listToRemoveFromWaiting = new List <TrainCurrentLocation>(); // check track token to start. foreach (var trainCurrentLocation in _lstTrainsToStart) { if (trainCurrentLocation.Train.CurrentRunningStatus == TrainRunningStatus.Stopped) { var track = LookupCache.GetInstance().GetNextTrack(trainCurrentLocation.Track.DestinationStationId); trainCurrentLocation.Track = track; trainCurrentLocation.DistanceLeft = trainCurrentLocation.Track.TrackLength; trainCurrentLocation.Train.CurrentRunningStatus = TrainRunningStatus.Waiting; } if (trainCurrentLocation.Train.CurrentRunningStatus == TrainRunningStatus.Waiting) { if (TrackTokenController.GetInstance().CheckTrackTokenAvailability(trainCurrentLocation.Track.SourceStationId, trainCurrentLocation.Track.DestinationStationId)) { TrackTokenController.GetInstance().AcquireTrackToken(trainCurrentLocation.Track.SourceStationId, trainCurrentLocation.Track.DestinationStationId, trainCurrentLocation.Train.TrainId); trainCurrentLocation.Train.CurrentRunningStatus = TrainRunningStatus.Running; _dicTrainCurrentLocations.Add(trainCurrentLocation.Train, trainCurrentLocation); TrainProcessEventArgs args = new TrainProcessEventArgs(); args.Message = "Train departured from Station" + trainCurrentLocation.Track.SourceStationId; args.TrainId = trainCurrentLocation.Train.ToString(); args.TrackId = trainCurrentLocation.Track.ToString(); OnTrainOtherEvent(this, args); _listToRemoveFromWaiting.Add(trainCurrentLocation); } else { TrainProcessEventArgs args = new TrainProcessEventArgs(); args.Message = "Train waiting for track " + trainCurrentLocation.Track + " to be free."; args.TrainId = trainCurrentLocation.Train.ToString(); args.TrackId = trainCurrentLocation.Track.ToString(); OnTrainOtherEvent(this, args); } } } // Remove from waiting list. foreach (var train in _listToRemoveFromWaiting) { if (_lstTrainsToStart.Contains(train)) { _lstTrainsToStart.Remove(train); } } // Move from running to unloading foreach (var trainCurrentLocation in lstToMovetoUnLoadingQueue) { if (_dicTrainCurrentLocations.ContainsKey(trainCurrentLocation.Train)) { TrackTokenController.GetInstance().ReleaseTrackToken(trainCurrentLocation.Track.SourceStationId, trainCurrentLocation.Track.DestinationStationId); _dicTrainCurrentLocations.Remove(trainCurrentLocation.Train); _lstOfTrainsForUnloading.Add(trainCurrentLocation); TrainProcessEventArgs args = new TrainProcessEventArgs(); args.TrainId = trainCurrentLocation.Train.ToString(); args.TrackId = trainCurrentLocation.Track.ToString(); OnTrainArrivedAtStation(this, args); } } // Move from unloading to loading foreach (var trainCurrentLocation in lstToAddToLoadingTrainsQueue) { if (_lstOfTrainsForUnloading.Contains(trainCurrentLocation)) { _lstOfTrainsForUnloading.Remove(trainCurrentLocation); _lstOfTrainsForLoading.Add(trainCurrentLocation); } } // Move from loading to waiting foreach (var trainCurrentLocation in lstToAddToWaitingTrainsQueue) { if (_lstOfTrainsForLoading.Contains(trainCurrentLocation)) { _lstOfTrainsForLoading.Remove(trainCurrentLocation); _lstTrainsToStart.Add(trainCurrentLocation); } } ProcessShipmentAtStation(); }