package usherbrooke.ift630; import java.util.ArrayList; public class Bus extends Thread { private ArrayList passengers; private ArrayList stops; private String name; private int id; private int maxCapacity; private int currentCapacity; private int timeBetweenStops; private int timeEmbark; private Stop nextStop; private int timeEmbark() { return (int) (Math.random() * timeEmbark); } private int timeBetweenStops() { return (int) (Math.random() * timeBetweenStops); } private boolean askStop() { boolean res = false; for (Passenger p : passengers){ if (p.getDest() == nextStop) { res = true; Logger.getInstance().print(id, "Stop asked"); break; } } return res; } private Stop goToNextStop() { // if no reason to stop, skip current stop do { try { nextStop = stops.remove(0); } catch (IndexOutOfBoundsException e) { nextStop = null; } } while ((getNextStopPassengers().isEmpty() || currentCapacity >= maxCapacity) && askStop()); try { Thread.sleep(timeBetweenStops() * 1000); } catch (InterruptedException e) { } return nextStop; } // TODO what private ArrayList getNextStopPassengers() { ArrayList res = new ArrayList(); if (nextStop != null) for (Passenger p : passengers) { if (p.getDest() == nextStop) { res.add(p); } } return res; } @Override public void run() { try { while (nextStop != null) { disembarkPassengers(); embarkPassengers(); nextStop = goToNextStop(); } } catch (Exception e) { Logger.getInstance().print(id, "[BUS] exception: " + e.getMessage()); } Logger.getInstance().print(id, "[BUS] exiting!"); } Bus(ArrayList s, int id, int timeStop, int timeEmbark, int maxCapacity) { this.timeBetweenStops = timeStop; this.timeEmbark = timeEmbark; this.name = "Bus n°" + id; this.id = id; this.passengers = new ArrayList(); this.stops = s; this.nextStop = stops.remove(0); this.currentCapacity = 0; this.maxCapacity = maxCapacity; } public synchronized void disembarkPassengers() { synchronized (nextStop.getMutex()) { for (Passenger p : passengers) { Logger.getInstance().print(id, "\t[BUS] " + p.getName() + " disembarked " + name); if (p.getDest() == nextStop) { p.disembark(); currentCapacity--; } } } } public synchronized void embarkPassengers() { synchronized (nextStop.getMutex()) { try { ArrayList list = nextStop.getPassengerByDest(stops); Logger.getInstance().print(id, "[BUS] hop into " + name + " at stop " + nextStop.getName() + "!"); Thread.sleep(timeEmbark() * 1000); if (currentCapacity >= maxCapacity) throw new OverCapacityException("Over bus capacity."); for (Passenger p : list) { passengers.add(p); nextStop.removePassenger(p); currentCapacity++; Logger.getInstance().print(id, "\t[BUS] " + p.getName() + " embarked in " + name + " at " + nextStop.getName()); } } catch (IndexOutOfBoundsException | OverCapacityException | InterruptedException e) { Logger.getInstance().print(id, "Exception: " + e.getMessage()); } } } public void printDetails(int indent) { Logger.getInstance().print(id, "\t".repeat(indent) + "---".repeat(3) + " Bus details " + "---".repeat(3)); Logger.getInstance().print(id, "\t".repeat(indent) + name); Logger.getInstance().print(id, "\t".repeat(indent) + "time between stops: " + timeBetweenStops); Logger.getInstance().print(id, "\t".repeat(indent) + "max capacity: " + maxCapacity); Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + nextStop.getName()); Logger.getInstance().print(id, "\t".repeat(indent) + "stops: "); nextStop.printDetails(indent + 1); for (Stop s : stops) { s.printDetails(indent + 1); } } public void printDetails() { printDetails(0); } }