| Lift.java |
1 package elevator;
2
3 /*
4 * Copyright (C) 2000 by ETHZ/INF/CS
5 * All rights reserved
6 *
7 * @version $Id$
8 * @author Roger Karrer
9 */
10
11 import java.util.Enumeration;
12 import java.util.Vector;
13
14 // class that implements the elevator threads
15 class Lift extends Thread {
16
17 // used for assigning unique ids to the elevators
18 private static int count = 0;
19
20 public static final int IDLE = 0;
21 public static final int UP = 1;
22 public static final int DOWN = 2;
23
24 private int travelDir; // one of IDLE, UP, or DOWN
25 private int currentFloor;
26 // holds the number of people who want to get off on each floor
27 private int[] peopleFor;
28 // Values in pickupOn can be IDLE, UP, DOWN, and UP|DOWN, which indicate
29 // which calls the elevator should respond to on each floor. IDLE means
30 // don't pick up on that floor
31 private int[] pickupOn;
32 private int firstFloor, lastFloor;
33 // reference to the shared control object
34 private Controls controls;
35
36 // Create a new elevator that can travel from floor 1 to floor numFloors.
37 // The elevator starts on floor 1, and is initially idle with no passengers.
38 // c is a reference to the shared control object
39 // The thread starts itself
40 public Lift(int numFloors, Controls c) {
41 super("Lift " + count++);
42 controls = c;
43 firstFloor = 1;
44 lastFloor = numFloors;
45 travelDir = IDLE;
46 currentFloor = firstFloor;
47 pickupOn = new int[numFloors+1];
48 peopleFor = new int[numFloors+1];
49 for (int i = 0; i <= numFloors; i++) {
50 pickupOn[i] = IDLE;
51 peopleFor[i] = 0;
52 }
53 start();
54 }
55
56 // Body of the thread. If the elevator is idle, it checks for calls
57 // every tenth of a second. If it is moving, it takes 1 second to
58 // move between floors.
59 public void run() {
60 int numIterations = 100;
61 int i = 0;
62 while(i < numIterations) {
63 if (travelDir == IDLE) {
64 try { sleep(100); } catch(InterruptedException e) {}
65 doIdle();
66 }
67 else {
68 try { sleep(1000); } catch(InterruptedException e) {}
69 doMoving();
70 }
71 i++;
72 }
73 }
74
75 // IDLE
76 // First check to see if there is an up or down call on what ever floor
77 // the elevator is idle on. If there isn't one, then check the other floors.
78 private void doIdle() {
79 boolean foundFloor = false;
80 int targetFloor = -1;
81
82 if (controls.claimUp(getName(), currentFloor)) {
83 // System.out.println("Lift::doIdle - could claim upcall on current floor"); // CARE
84 foundFloor = true;
85 targetFloor = currentFloor;
86 travelDir = UP;
87 addPeople(controls.getUpPeople(currentFloor));
88 }
89 else if (controls.claimDown(getName(), currentFloor)) {
90 // System.out.println("Lift::doIdle - could claim downcall on current floor"); // CARE
91 foundFloor = true;
92 targetFloor = currentFloor;
93 travelDir = DOWN;
94 addPeople(controls.getDownPeople(currentFloor));
95 }
96
97 // System.out.println("Lift::doIdle - lookuing for calls on other floors"); // CARE
98 for (int floor = firstFloor; !foundFloor && floor <= lastFloor; floor++) {
99 // System.out.println("Lift::doIdle - checking floor " + floor); // CARE
100 if (controls.claimUp(getName(), floor)) {
101 // System.out.println("Lift::doIdle - success with claimUp " + floor); // CARE
102 foundFloor = true;
103 targetFloor = floor;
104 pickupOn[floor] |= UP;
105 travelDir = (targetFloor > currentFloor) ? UP : DOWN;
106 }
107 else if (controls.claimDown(getName(), floor)) {
108 // System.out.println("Lift::doIdle - success with claimDown " + floor); // CARE
109 foundFloor = true;
110 targetFloor = floor;
111 pickupOn[floor] |= DOWN;
112 travelDir = (targetFloor > currentFloor) ? UP : DOWN;
113 }
114 }
115
116 if (foundFloor) {
117 System.out.println(getName() + " is now moving " +
118 ((travelDir==UP)?"UP":"DOWN"));
119 }
120 }
121
122 // MOVING
123 // First change floor (up or down as appropriate)
124 // Drop off passengers if we have to
125 // Then pick up passengers if we have to
126 private void doMoving() {
127 currentFloor += (travelDir == UP) ? 1 : -1;
128 int oldDir = travelDir;
129
130 if (travelDir == UP && currentFloor == lastFloor) travelDir = DOWN;
131 if (travelDir == DOWN && currentFloor == firstFloor) travelDir = UP;
132 System.out.println(getName() + " now on " + currentFloor);
133
134 if (peopleFor[currentFloor] > 0) {
135 System.out.println(getName() + " delivering " +
136 peopleFor[currentFloor] + " passengers on " +
137 currentFloor);
138 peopleFor[currentFloor] = 0;
139 }
140
141 // Pickup people who want to go up if:
142 // 1) we previous claimed an up call on this floor, or
143 // 2) we are travelling up and there is an unclaimed up call on this
144 // floor
145 if (((pickupOn[currentFloor] & UP) != 0) ||
146 (travelDir == UP && controls.claimUp(getName(), currentFloor))) {
147 addPeople(controls.getUpPeople(currentFloor));
148 pickupOn[currentFloor] &= ~UP;
149 }
150
151 // Pickup people who want to go down if:
152 // 1) we previous claimed an down call on this floor, or
153 // 2) we are travelling down and there is an unclaimed down call on this
154 // floor
155 if (((pickupOn[currentFloor] & DOWN) != 0) ||
156 (travelDir == DOWN && controls.claimDown(getName(), currentFloor))) {
157 addPeople(controls.getDownPeople(currentFloor));
158 pickupOn[currentFloor] &= ~DOWN;
159 }
160
161 if (travelDir == UP) {
162 // If we are travelling up, and there are people who want to get off
163 // on a floor above this one, continue to go up.
164 if (stopsAbove()) ;
165 else {
166 // If we are travelling up, but no one wants to get off above this
167 // floor, but they do want to get off below this one, start
168 // moving down
169 if (stopsBelow()) travelDir = DOWN;
170 // Otherwise, no one is the elevator, so become idle
171 else travelDir = IDLE;
172 }
173 }
174 else {
175 // If we are travelling down, and there are people who want to get off
176 // on a floor below this one, continue to go down.
177 if (stopsBelow()) ;
178 else {
179 // If we are travelling down, but no one wants to get off below this
180 // floor, but they do want to get off above this one, start
181 // moving up
182 if (stopsAbove()) travelDir = UP;
183 // Otherwise, no one is the elevator, so become idle
184 else travelDir = IDLE;
185 }
186 }
187
188 // Print out are new direction
189 if (oldDir != travelDir) {
190 System.out.print(getName());
191 if (travelDir == IDLE) System.out.println(" becoming IDLE");
192 else if (travelDir == UP) System.out.println(" changing to UP");
193 else if (travelDir == DOWN) System.out.println(" changing to DOWN");
194 }
195 }
196
197 // Returns true if there are passengers in the elevator who want to stop
198 // on a floor above currentFloor, or we claimed a call on a floor below
199 // currentFloor
200 private boolean stopsAbove() {
201 boolean above = false;
202 for (int i = currentFloor + 1; !above && i <= lastFloor; i++)
203 above = (pickupOn[i] != IDLE) || (peopleFor[i] != 0);
204 return above;
205 }
206
207 // Returns true if there are passengers in the elevator who want to stop
208 // on a floor below currentFloor, or we claiemda call on a floor above
209 // currentFloor
210 private boolean stopsBelow() {
211 boolean below = false;
212 for (int i = currentFloor - 1; !below && (i >= firstFloor); i--)
213 below = (pickupOn[i] != IDLE) || (peopleFor[i] != 0);
214 return below;
215 }
216
217 // Updates peopleFor based on the Vector of destination floors received
218 // from the control object
219 private void addPeople(Vector people) {
220 System.out.println(getName() + " picking up " + people.size() +
221 " passengers on " + currentFloor);
222 for (Enumeration e = people.elements(); e.hasMoreElements(); ) {
223 int toFloor = ((Integer) e.nextElement()).intValue();
224 peopleFor[toFloor] += 1;
225 }
226 }
227 }
228
229
230
231
232
233
234 | Lift.java |