Lift better abstractions
This commit is contained in:
parent
09cd85f364
commit
2c50014eaf
3 changed files with 103 additions and 39 deletions
|
@ -1,25 +1,46 @@
|
|||
package lift;
|
||||
|
||||
class Door {
|
||||
private boolean open;
|
||||
private boolean open;
|
||||
private int passengersEntering;
|
||||
private int passengersExiting;
|
||||
|
||||
/** Create a new closed door */
|
||||
public Door() {
|
||||
open = false;
|
||||
}
|
||||
/** Create a new closed door */
|
||||
public Door() {
|
||||
open = false;
|
||||
passengersEntering = 0;
|
||||
passengersExiting = 0;
|
||||
}
|
||||
|
||||
/** Returns true if door is open */
|
||||
public boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
/** Returns true if door is open */
|
||||
public boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
/** Open the door */
|
||||
public void open() {
|
||||
open = true;
|
||||
}
|
||||
/** Open the door */
|
||||
public void open() {
|
||||
open = true;
|
||||
}
|
||||
|
||||
/** Close the door */
|
||||
public void close() {
|
||||
open = false;
|
||||
}
|
||||
|
||||
public int getEntering() {
|
||||
return passengersEntering;
|
||||
}
|
||||
|
||||
public void setEntering(int passengers) {
|
||||
this.passengersEntering = passengers;
|
||||
}
|
||||
|
||||
public int getExiting() {
|
||||
return passengersExiting;
|
||||
}
|
||||
|
||||
public void setExiting(int passengers) {
|
||||
this.passengersExiting = passengers;
|
||||
}
|
||||
|
||||
/** Close the door */
|
||||
public void close() {
|
||||
open = false;
|
||||
}
|
||||
}
|
|
@ -18,9 +18,9 @@ public class LiftMonitor {
|
|||
/** Current direction of the lift */
|
||||
private Direction direction;
|
||||
/** number of passengers waiting to enter the lift at the various floors */
|
||||
private int[] waitEntry;
|
||||
// private int[] waitEntry;
|
||||
/** number of passengers (in lift) waiting to leave at the various floors */
|
||||
private int[] waitExit;
|
||||
// private int[] waitExit;
|
||||
/** number of passengers currently in the lift */
|
||||
private int load;
|
||||
/** view object passed from main */
|
||||
|
@ -32,6 +32,9 @@ public class LiftMonitor {
|
|||
/** Counter of number of passengers currently exiting the elevator */
|
||||
private int passengersExiting;
|
||||
|
||||
private PassengerQueue waitEntry;
|
||||
private PassengerQueue waitExit;
|
||||
|
||||
/** Create new LiftMonitor */
|
||||
public LiftMonitor(LiftView v, int floors) {
|
||||
floor = 0;
|
||||
|
@ -39,8 +42,8 @@ public class LiftMonitor {
|
|||
moving = true;
|
||||
direction = Direction.UP;
|
||||
door = new Door();
|
||||
waitEntry = new int[nfloors];
|
||||
waitExit = new int[nfloors];
|
||||
waitEntry = new PassengerQueue(nfloors);
|
||||
waitExit = new PassengerQueue(nfloors);
|
||||
load = 0;
|
||||
view = v;
|
||||
passengersEntering = 0;
|
||||
|
@ -49,7 +52,7 @@ public class LiftMonitor {
|
|||
|
||||
/** Increases the number of waiting passengers on given floor */
|
||||
public synchronized void increaseWaitEntry(int passengerFloor) {
|
||||
waitEntry[passengerFloor]++;
|
||||
waitEntry.inc(passengerFloor);
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
|
@ -64,8 +67,9 @@ public class LiftMonitor {
|
|||
throw new Error("Monitor.enterLift interrupted " + e);
|
||||
}
|
||||
}
|
||||
waitEntry[floor]--;
|
||||
waitExit[passengerDestination]++;
|
||||
|
||||
waitEntry.dec(floor);
|
||||
waitExit.inc(passengerDestination);
|
||||
load++;
|
||||
passengersEntering++;
|
||||
notifyAll();
|
||||
|
@ -86,7 +90,7 @@ public class LiftMonitor {
|
|||
throw new Error("Monitor.exitLift interrupted " + e);
|
||||
}
|
||||
}
|
||||
waitExit[passengerDestination]--;
|
||||
waitExit.dec(passengerDestination);
|
||||
load--;
|
||||
passengersExiting++;
|
||||
notifyAll();
|
||||
|
@ -104,9 +108,7 @@ public class LiftMonitor {
|
|||
* on any floor.
|
||||
*/
|
||||
public synchronized int[] liftContinue() {
|
||||
|
||||
while (Arrays.stream(waitEntry).sum() == 0 &&
|
||||
Arrays.stream(waitExit).sum() == 0) {
|
||||
while (waitEntry.isEmpty() && waitExit.isEmpty()) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -115,7 +117,7 @@ public class LiftMonitor {
|
|||
}
|
||||
|
||||
/** Stops the elevator to allow passengers to enter or exit */
|
||||
while (waitEntry[floor] > 0 && load != 4 || waitExit[floor] > 0 ||
|
||||
while (waitEntry.get(floor) > 0 && load != 4 || waitExit.get(floor) > 0 ||
|
||||
passengersEntering > 0 || passengersExiting > 0) {
|
||||
if (!door.isOpen()) {
|
||||
view.openDoors(floor);
|
||||
|
@ -160,16 +162,13 @@ public class LiftMonitor {
|
|||
* to enter or exit on floors either above or below the elevator
|
||||
*/
|
||||
private void calculateDirection() {
|
||||
if (Arrays.stream(waitEntry, floor, nfloors).sum() == 0 &&
|
||||
Arrays.stream(waitExit, floor, nfloors).sum() == 0 && floor != 0) {
|
||||
direction = Direction.DOWN;
|
||||
} else if (Arrays.stream(waitEntry, 0, floor + 1).sum() == 0 &&
|
||||
Arrays.stream(waitExit, 0, floor + 1).sum() == 0 && floor != 6) {
|
||||
direction = Direction.UP;
|
||||
} else if (floor == nfloors - 1) {
|
||||
direction = Direction.DOWN;
|
||||
} else if (floor == 0) {
|
||||
direction = Direction.UP;
|
||||
boolean noPassengersAbove = (waitEntry.totalAbove(floor) == 0 && waitExit.totalAbove(floor) == 0);
|
||||
boolean noPassengersBelow = (waitEntry.totalBelow(floor) == 0 && waitExit.totalBelow(floor) == 0);
|
||||
|
||||
if (floor == 0 || noPassengersBelow) {
|
||||
direction = Direction.UP; // Always go up if at ground floor or no passengers below
|
||||
} else if (floor == nfloors - 1 || noPassengersAbove) {
|
||||
direction = Direction.DOWN; // Always go down if at the top floor or no passengers above
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
44
lift/src/lift/PassengerQueue.java
Normal file
44
lift/src/lift/PassengerQueue.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package lift;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class PassengerQueue {
|
||||
private int[] waitRecord;
|
||||
|
||||
public PassengerQueue(int nfloors) {
|
||||
this.waitRecord = new int[nfloors];
|
||||
}
|
||||
|
||||
public void inc(int floor) {
|
||||
this.waitRecord[floor]++;
|
||||
}
|
||||
|
||||
public void dec(int floor) {
|
||||
this.waitRecord[floor]--;
|
||||
}
|
||||
|
||||
public int get(int floor) {
|
||||
return this.waitRecord[floor];
|
||||
}
|
||||
|
||||
public void set(int floor, int value) {
|
||||
this.waitRecord[floor] = value;
|
||||
}
|
||||
|
||||
public int total() {
|
||||
return Arrays.stream(this.waitRecord).sum();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.total() == 0;
|
||||
}
|
||||
|
||||
public int totalBelow(int floor) {
|
||||
return Arrays.stream(this.waitRecord).limit(floor).sum();
|
||||
}
|
||||
|
||||
public int totalAbove(int floor) {
|
||||
return Arrays.stream(this.waitRecord).skip(floor + 1).sum();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue