LiftState class
This commit is contained in:
parent
1a89549de6
commit
820687f59b
2 changed files with 89 additions and 34 deletions
|
@ -1,7 +1,5 @@
|
|||
package lift;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
enum Direction {
|
||||
UP,
|
||||
DOWN,
|
||||
|
@ -9,20 +7,12 @@ enum Direction {
|
|||
|
||||
/** Lift monitor. Handles lift motion and various state. */
|
||||
public class LiftMonitor {
|
||||
/** the floor the lift is currently on */
|
||||
private int floor;
|
||||
/** Number of floors */
|
||||
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 */
|
||||
private PassengerQueue waitEntry;
|
||||
/** number of passengers (in lift) waiting to leave at the various floors */
|
||||
private PassengerQueue waitExit;
|
||||
/** number of passengers currently in the lift */
|
||||
private int load;
|
||||
/** view object passed from main */
|
||||
private LiftView view;
|
||||
/** State (open/closed) of door on current floor */
|
||||
|
@ -31,20 +21,19 @@ public class LiftMonitor {
|
|||
private int passengersEntering;
|
||||
/** Counter of number of passengers currently exiting the elevator */
|
||||
private int passengersExiting;
|
||||
/** Lift state */
|
||||
private LiftState liftState;
|
||||
|
||||
/** Create new LiftMonitor */
|
||||
public LiftMonitor(LiftView v, int floors) {
|
||||
floor = 0;
|
||||
nfloors = floors;
|
||||
moving = true;
|
||||
direction = Direction.UP;
|
||||
door = new Door();
|
||||
waitEntry = new PassengerQueue(nfloors);
|
||||
waitExit = new PassengerQueue(nfloors);
|
||||
load = 0;
|
||||
view = v;
|
||||
passengersEntering = 0;
|
||||
passengersExiting = 0;
|
||||
liftState = new LiftState(0, Direction.UP);
|
||||
}
|
||||
|
||||
/** Increases the number of waiting passengers on given floor */
|
||||
|
@ -56,8 +45,8 @@ public class LiftMonitor {
|
|||
/** Handles passengers waiting to enter arriving lift */
|
||||
public synchronized void enterLift(int passengerFloor,
|
||||
int passengerDestination) {
|
||||
while (floor != passengerFloor || load == 4 || moving ||
|
||||
passengersEntering == 4) {
|
||||
while (liftState.getFloor() != passengerFloor || liftState.getLoad() == 4 ||
|
||||
liftState.isMoving() || passengersEntering == 4) {
|
||||
try {
|
||||
wait();
|
||||
} 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);
|
||||
load++;
|
||||
liftState.incLoad();
|
||||
passengersEntering++;
|
||||
notifyAll();
|
||||
}
|
||||
|
@ -80,7 +70,7 @@ public class LiftMonitor {
|
|||
|
||||
/** Handles passengers waiting to exit lift */
|
||||
public synchronized void exitLift(int passengerDestination) {
|
||||
while (floor != passengerDestination) {
|
||||
while (liftState.getFloor() != passengerDestination) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -88,7 +78,7 @@ public class LiftMonitor {
|
|||
}
|
||||
}
|
||||
waitExit.dec(passengerDestination);
|
||||
load--;
|
||||
liftState.decLoad();
|
||||
passengersExiting++;
|
||||
notifyAll();
|
||||
}
|
||||
|
@ -114,13 +104,15 @@ public class LiftMonitor {
|
|||
}
|
||||
|
||||
/** Stops the elevator to allow passengers to enter or exit */
|
||||
while (waitEntry.get(floor) > 0 && load != 4 || waitExit.get(floor) > 0 ||
|
||||
passengersEntering > 0 || passengersExiting > 0) {
|
||||
while (waitEntry.get(liftState.getFloor()) > 0 &&
|
||||
liftState.getLoad() != 4 ||
|
||||
waitExit.get(liftState.getFloor()) > 0 || passengersEntering > 0 ||
|
||||
passengersExiting > 0) {
|
||||
if (!door.isOpen()) {
|
||||
view.openDoors(floor);
|
||||
view.openDoors(liftState.getFloor());
|
||||
door.open();
|
||||
}
|
||||
moving = false;
|
||||
liftState.setMoving(false);
|
||||
notifyAll();
|
||||
try {
|
||||
wait();
|
||||
|
@ -129,13 +121,13 @@ public class LiftMonitor {
|
|||
}
|
||||
}
|
||||
|
||||
if (!moving)
|
||||
if (!liftState.isMoving())
|
||||
view.closeDoors();
|
||||
|
||||
if (door.isOpen())
|
||||
door.close();
|
||||
|
||||
moving = true;
|
||||
liftState.setMoving(true);
|
||||
|
||||
calculateDirection();
|
||||
|
||||
|
@ -143,14 +135,16 @@ public class LiftMonitor {
|
|||
* Sends the elevators current position and next position to the LiftThread
|
||||
*/
|
||||
int[] movingPositions = new int[2];
|
||||
movingPositions[0] = floor;
|
||||
movingPositions[1] = floor + (direction == Direction.UP ? 1 : -1);
|
||||
movingPositions[0] = liftState.getFloor();
|
||||
movingPositions[1] = liftState.getFloor() +
|
||||
(liftState.getDirection() == Direction.UP ? 1 : -1);
|
||||
return movingPositions;
|
||||
}
|
||||
|
||||
/** Moves the elevator in the given direction */
|
||||
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
|
||||
*/
|
||||
private void calculateDirection() {
|
||||
boolean noPassengersAbove = (waitEntry.totalAbove(floor) == 0 && waitExit.totalAbove(floor) == 0);
|
||||
boolean noPassengersBelow = (waitEntry.totalBelow(floor) == 0 && waitExit.totalBelow(floor) == 0);
|
||||
int floor = liftState.getFloor();
|
||||
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
|
||||
liftState.setDirection(
|
||||
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
|
||||
liftState.setDirection(Direction.DOWN); // Always go down if at the top
|
||||
// floor or no passengers above
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
55
lift/src/lift/LiftState.java
Normal file
55
lift/src/lift/LiftState.java
Normal 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--;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue