LiftState class

This commit is contained in:
Imbus 2024-09-26 03:20:34 +02:00
parent 1a89549de6
commit 820687f59b
2 changed files with 89 additions and 34 deletions

View file

@ -1,7 +1,5 @@
package lift; package lift;
import java.util.Arrays;
enum Direction { enum Direction {
UP, UP,
DOWN, DOWN,
@ -9,20 +7,12 @@ enum Direction {
/** Lift monitor. Handles lift motion and various state. */ /** Lift monitor. Handles lift motion and various state. */
public class LiftMonitor { public class LiftMonitor {
/** the floor the lift is currently on */
private int floor;
/** Number of floors */ /** Number of floors */
private int nfloors; private int nfloors;
/** true if the lift is moving, false if standing still with doors open */
private boolean moving;
/** Current direction of the lift */
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 PassengerQueue waitEntry; private PassengerQueue 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 PassengerQueue waitExit; private PassengerQueue waitExit;
/** number of passengers currently in the lift */
private int load;
/** view object passed from main */ /** view object passed from main */
private LiftView view; private LiftView view;
/** State (open/closed) of door on current floor */ /** State (open/closed) of door on current floor */
@ -31,20 +21,19 @@ public class LiftMonitor {
private int passengersEntering; private int passengersEntering;
/** Counter of number of passengers currently exiting the elevator */ /** Counter of number of passengers currently exiting the elevator */
private int passengersExiting; private int passengersExiting;
/** Lift state */
private LiftState liftState;
/** Create new LiftMonitor */ /** Create new LiftMonitor */
public LiftMonitor(LiftView v, int floors) { public LiftMonitor(LiftView v, int floors) {
floor = 0;
nfloors = floors; nfloors = floors;
moving = true;
direction = Direction.UP;
door = new Door(); door = new Door();
waitEntry = new PassengerQueue(nfloors); waitEntry = new PassengerQueue(nfloors);
waitExit = new PassengerQueue(nfloors); waitExit = new PassengerQueue(nfloors);
load = 0;
view = v; view = v;
passengersEntering = 0; passengersEntering = 0;
passengersExiting = 0; passengersExiting = 0;
liftState = new LiftState(0, Direction.UP);
} }
/** Increases the number of waiting passengers on given floor */ /** Increases the number of waiting passengers on given floor */
@ -55,9 +44,9 @@ public class LiftMonitor {
/** Handles passengers waiting to enter arriving lift */ /** Handles passengers waiting to enter arriving lift */
public synchronized void enterLift(int passengerFloor, public synchronized void enterLift(int passengerFloor,
int passengerDestination) { int passengerDestination) {
while (floor != passengerFloor || load == 4 || moving || while (liftState.getFloor() != passengerFloor || liftState.getLoad() == 4 ||
passengersEntering == 4) { liftState.isMoving() || passengersEntering == 4) {
try { try {
wait(); wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -65,9 +54,10 @@ public class LiftMonitor {
} }
} }
waitEntry.dec(floor); waitEntry.dec(
liftState.getFloor()); // In practice, passengerFloor == floor here
waitExit.inc(passengerDestination); waitExit.inc(passengerDestination);
load++; liftState.incLoad();
passengersEntering++; passengersEntering++;
notifyAll(); notifyAll();
} }
@ -80,7 +70,7 @@ public class LiftMonitor {
/** Handles passengers waiting to exit lift */ /** Handles passengers waiting to exit lift */
public synchronized void exitLift(int passengerDestination) { public synchronized void exitLift(int passengerDestination) {
while (floor != passengerDestination) { while (liftState.getFloor() != passengerDestination) {
try { try {
wait(); wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -88,7 +78,7 @@ public class LiftMonitor {
} }
} }
waitExit.dec(passengerDestination); waitExit.dec(passengerDestination);
load--; liftState.decLoad();
passengersExiting++; passengersExiting++;
notifyAll(); notifyAll();
} }
@ -114,13 +104,15 @@ 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.get(floor) > 0 && load != 4 || waitExit.get(floor) > 0 || while (waitEntry.get(liftState.getFloor()) > 0 &&
passengersEntering > 0 || passengersExiting > 0) { liftState.getLoad() != 4 ||
waitExit.get(liftState.getFloor()) > 0 || passengersEntering > 0 ||
passengersExiting > 0) {
if (!door.isOpen()) { if (!door.isOpen()) {
view.openDoors(floor); view.openDoors(liftState.getFloor());
door.open(); door.open();
} }
moving = false; liftState.setMoving(false);
notifyAll(); notifyAll();
try { try {
wait(); wait();
@ -129,13 +121,13 @@ public class LiftMonitor {
} }
} }
if (!moving) if (!liftState.isMoving())
view.closeDoors(); view.closeDoors();
if (door.isOpen()) if (door.isOpen())
door.close(); door.close();
moving = true; liftState.setMoving(true);
calculateDirection(); calculateDirection();
@ -143,14 +135,16 @@ public class LiftMonitor {
* Sends the elevators current position and next position to the LiftThread * Sends the elevators current position and next position to the LiftThread
*/ */
int[] movingPositions = new int[2]; int[] movingPositions = new int[2];
movingPositions[0] = floor; movingPositions[0] = liftState.getFloor();
movingPositions[1] = floor + (direction == Direction.UP ? 1 : -1); movingPositions[1] = liftState.getFloor() +
(liftState.getDirection() == Direction.UP ? 1 : -1);
return movingPositions; return movingPositions;
} }
/** Moves the elevator in the given direction */ /** Moves the elevator in the given direction */
public synchronized void incrementFloor() { public synchronized void incrementFloor() {
floor = floor + (direction == Direction.UP ? 1 : -1); liftState.setFloor(liftState.getFloor() +
(liftState.getDirection() == Direction.UP ? 1 : -1));
} }
/** /**
@ -159,13 +153,19 @@ 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() {
boolean noPassengersAbove = (waitEntry.totalAbove(floor) == 0 && waitExit.totalAbove(floor) == 0); int floor = liftState.getFloor();
boolean noPassengersBelow = (waitEntry.totalBelow(floor) == 0 && waitExit.totalBelow(floor) == 0); boolean noPassengersAbove =
(waitEntry.totalAbove(floor) == 0 && waitExit.totalAbove(floor) == 0);
boolean noPassengersBelow =
(waitEntry.totalBelow(floor) == 0 && waitExit.totalBelow(floor) == 0);
if (floor == 0 || noPassengersBelow) { if (floor == 0 || noPassengersBelow) {
direction = Direction.UP; // Always go up if at ground floor or no passengers below liftState.setDirection(
Direction
.UP); // Always go up if at ground floor or no passengers below
} else if (floor == nfloors - 1 || noPassengersAbove) { } else if (floor == nfloors - 1 || noPassengersAbove) {
direction = Direction.DOWN; // Always go down if at the top floor or no passengers above liftState.setDirection(Direction.DOWN); // Always go down if at the top
// floor or no passengers above
} }
} }
} }

View file

@ -0,0 +1,55 @@
package lift;
public class LiftState {
private int floor;
private Direction direction;
private boolean moving;
private int load;
public LiftState(int initialFloor, Direction initialDirection) {
this.floor = initialFloor;
this.direction = initialDirection;
this.moving = true;
this.load = 0;
}
public int getFloor() {
return floor;
}
public void setFloor(int floor) {
this.floor = floor;
}
public Direction getDirection() {
return direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
public boolean isMoving() {
return moving;
}
public void setMoving(boolean moving) {
this.moving = moving;
}
public int getLoad() {
return load;
}
public void setLoad(int load) {
this.load = load;
}
public void incLoad() {
this.load++;
}
public void decLoad() {
this.load--;
}
}