Something went wrong on our end
-
Brutzman, Don authoredBrutzman, Don authored
TwoCraneBerths.java 6.57 KiB
package SimkitOpenDis7Examples;
import java.util.SortedSet;
import java.util.TreeSet;
import simkit.Priority;
import simkit.SimEntityBase;
/**
* Model two crane berths
* @author abuss@nps.edu
*/
public class TwoCraneBerths extends SimEntityBase
{
/**
* Queue of Ships waiting to go into the berth
*/
protected SortedSet<Ship> queue;
/**
* Contains 0, 1, or two Ships being unloaded
*/
protected SortedSet<Ship> berth;
/**
* Time in the system for each Ship
*/
protected double timeInSystem;
/**
* Delay in the queue for each Ship
*/
protected double delayInQueue;
/**
* Instantiate queue and berth containers
*/
public TwoCraneBerths() {
this.queue = new TreeSet<>();
this.berth = new TreeSet<>();
}
/**
* Clear queue and berth containers
*/
@Override
public void reset() {
super.reset();
queue.clear();
berth.clear();
timeInSystem = Double.NaN; // Not a Number
delayInQueue = Double.NaN; // Not a Number
}
/**
* Only PropertyChangeEvents
*/
public void doRun()
{
firePropertyChange("queue", getQueue());
firePropertyChange("berth", getBerth());
firePropertyChange("timeInSystem", getTimeInSystem());
firePropertyChange("delayInQueue", getDelayInQueue());
}
/**
* Add the given Ship to queue<br>
* If berths is empty, schedule StartUnloadingTwoCranes<br>
* If berths has 1 Ship, schedule SwitchToOneCrane
*
* @param ship Given Ship arriving to harbor
*/
public void doArrival(Ship ship) {
ship.stampTime();
SortedSet<Ship> oldQueue = getQueue();
queue.add(ship);
firePropertyChange("queue", oldQueue, getQueue());
if (berth.isEmpty()) {
waitDelay("StartUnloadingTwoCranes", 0.0, Priority.HIGH);
}
if (berth.size() == 1) {
waitDelay("SwitchToOneCrane", 0.0);
}
}
/**
* Remove the first Ship from queue<br>
* DelayInQueue is elapsedTime of that Ship<br>
* Add the ship to berth container<br>
* Schedule EndUnloadingTwoCranes at half the remaining time
*/
public void doStartUnloadingTwoCranes() {
SortedSet<Ship> oldQueue = getQueue();
Ship ship = queue.first();
queue.remove(ship);
firePropertyChange("queue", oldQueue, getQueue());
delayInQueue = ship.getElapsedTime();
firePropertyChange("delayInQueue", getDelayInQueue());
ship.stampTime();
SortedSet<Ship> oldBerth = getBerth();
berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth());
waitDelay("EndUnloadingTwoCranes", 0.5 * ship.getRemainingUnloadingTime());
}
/**
* Remove the (one) Ship from berth<br>
* TimeInSystem is the age of the Ship
*/
public void doEndUnloadingTwoCranes() {
SortedSet<Ship> oldBerth = getBerth();
Ship ship = berth.first();
berth.remove(ship);
firePropertyChange("berth", oldBerth, getBerth());
timeInSystem = ship.getAge();
firePropertyChange("timeInSystem", getTimeInSystem());
}
/**
* This event is when a Ship arrives to find only one other Ship being
* unloaded.<br>
* Credit the ship in the berth with work at a rate of 2 (since 2 cranes
* have been unloading it<br>
* Interrupt EndUnloadingTwoCranes<br>
* Schedule EndUnloadingOneCrane with the Ship already in the berth<br>
* Schedule StartUnloadingOneCrane
*/
public void doSwitchToOneCrane() {
Ship ship = berth.first();
ship.work(2.0);
ship.stampTime();
interrupt("EndUnloadingTwoCranes");
waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship);
waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH);
}
/**
* Pop the first Ship from the queue<br>
* delayInQueue is elapsedTime (from Arrival event)<br>
* Add that Ship to berth container<br>
* Schedule EndUnloadingOneCrane with that Ship
*/
public void doStartUnloadingOneCrane() {
SortedSet<Ship> oldQueue = getQueue();
Ship ship = queue.first();
queue.remove(ship);
firePropertyChange("queue", oldQueue, getQueue());
delayInQueue = ship.getElapsedTime();
firePropertyChange("delayInQueue", getDelayInQueue());
ship.stampTime();
SortedSet<Ship> oldBerth = getBerth();
berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth());
waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship);
}
/**
* Remove given Ship from berth<br>
* If Ships in queue, schedule StartUnloadingOneCrane<br>
* If queue is empty, schedule SwitchToTwoCranes<br>
* timeInSystem is age of Ship
*
* @param ship Given Ship
*/
public void doEndUnloadingOneCrane(Ship ship) {
SortedSet<Ship> oldBerth = getBerth();
berth.remove(ship);
firePropertyChange("berth", oldBerth, getBerth());
if (queue.size() > 0) {
waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH);
}
if (queue.isEmpty() && berth.size() == 1) {
waitDelay("SwitchToTwoCranes", 0.0);
}
timeInSystem = ship.getAge();
firePropertyChange("timeInSystem", getTimeInSystem());
}
/**
* Credit the work of the remaining Ship in berth at unit rate<br>
* Interrupt EndUnloadingOneCrane<br>
* Schedule EndUnloadingTwoCranes at double the rate (i.e., half the remaining time)
*/
public void doSwitchToTwoCranes() {
Ship ship = berth.first();
ship.work(1.0);
ship.stampTime();
interrupt("EndUnloadingOneCrane", ship);
waitDelay("EndUnloadingTwoCranes",
0.5 * ship.getRemainingUnloadingTime());
}
/**
* Get tree of sorted Ship set queue
* @return Shallow copy of queue
*/
public SortedSet<Ship> getQueue() {
return new TreeSet<>(queue);
}
/**
* Get tree of sorted Ship set berths
* @return Shallow copy of berth
*/
public SortedSet<Ship> getBerth() {
return new TreeSet<>(berth);
}
/**
* accessor method to get a state variable
* @return The timeInSystem
*/
public double getTimeInSystem() {
return timeInSystem;
}
/**
* accessor method to get a state variable
* @return The delayInQueue
*/
public double getDelayInQueue() {
return delayInQueue;
}
}