package desmoj.extensions.verkettung;
import desmoj.core.dist.NumericalDist;
import desmoj.core.simulator.Entity;
import desmoj.core.simulator.Event;
import desmoj.core.simulator.Model;
import desmoj.core.simulator.TimeSpan;
import desmoj.extensions.verkettung.abstractions.HasPredecessor;
import desmoj.extensions.verkettung.abstractions.HasSuccessor;
import desmoj.extensions.verkettung.abstractions.Station;
/**
* The source creates new Entities and send them to the successor. The Sink inherits all behavior from the station except the possible restriction of
* the buffer queue. The user has to override the createEntity Method the create the Entity the source should send to the succsessor.
*
* @author Christian Mentz
*
* @param <E>
* The Entitiy which is created by the source
*/
public abstract class Source<E extends Entity> extends Station<E> implements HasSuccessor<E> {
class SourceDummyEntity extends Entity {
public SourceDummyEntity() {
super(Source.this.getModel(), "SourceDummyEntity", false);
}
}
private Event<? super E> successorEvent;
private boolean started;
/**
* This Constructor sets the given times, initializes the queues and fills the free service capacity queue. If a given int is lower than zero the
* Source assumes that there is no resriction. This applies to incomingBufferQueueCapacity, maxEntitiesToHandle, parallelHandledEntities
*
* @param maxEntitiesToHandle
* the number of max entities the station can handle
* @param parallelHandledEntities
* the number of max parallel entities a station can handle
* @param setupTime
* the time the station needs to set up
* @param serviceTime
* the time the station needs for the service
* @param recoveryTime
* the time the station needs tor recover
* @param transportTime
* the time the station needs to transport the entitiy to the next station
* @param owner
* the model owner
* @param name
* the name of the station
* @param showInReport
* should this construct be in the report
* @param showInTrace
* should this construct be in the trace
*/
public Source(int maxEntitiesToProduce, int parallelProducedEntities, NumericalDist<?> setupTime,
NumericalDist<?> productionTime, NumericalDist<?> recoveryTime, NumericalDist<?> transportTime,
Model owner, String name, boolean showInReport, boolean showInTrace) {
super(Integer.MAX_VALUE, maxEntitiesToProduce, parallelProducedEntities, setupTime, productionTime,
recoveryTime, transportTime, owner, name, showInReport, showInTrace);
}
/**
* Used to run through the Station class to generate proper statistics.
*
* @return a dummy entity
*/
@SuppressWarnings("unchecked")
private E createDummyEntity() {
return (E) new SourceDummyEntity();
}
protected abstract E createEntity();
/**
* schedules the succsessor event with a the created entitiy and the defined transport time
*/
@Override
protected void onServiceFinisched(E who) {
try {
successorEvent.clone().schedule(createEntity(), getTransportTime());
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
insertIncomingEntityIntoQueue(createDummyEntity());
};
@Override
public void setSuccessor(Event<? super E> eventToScheduleWhenFinished) {
successorEvent = eventToScheduleWhenFinished;
}
@Override
public void setSuccessor(HasPredecessor<? super E> successor) {
setSuccessor(successor.getStartEvent());
}
/**
* The source starts with creating entities if this method is not called previously.
*/
public void startCreatingEntities() {
if (started) {
sendWarning("SourceOld already started!", "Source : " + getName()
+ " Method: startCreatingEntities()",
"the source has already started to create entities",
"dont call this method more than once on a single object");
}
started = true;
for (int i = 0; i < getRemainingServiceCapacity(); i++) {
getStartEvent().schedule(createDummyEntity(), new TimeSpan(0));
}
}
}