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