ift630_sts2/src/main/java/usherbrooke/ift630/Bus.java

148 lines
3.9 KiB
Java

package usherbrooke.ift630;
import java.util.ArrayList;
public class Bus extends Thread {
private ArrayList<Passenger> passengers;
private ArrayList<Stop> 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<Passenger> getNextStopPassengers() {
ArrayList<Passenger> res = new ArrayList<Passenger>();
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<Stop> 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<Passenger>();
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<Passenger> 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);
}
}