// This includes actors with no input ports and those
// whose input ports have consumption rates of zero.
Iterator actors = actorList.iterator();
while (actors.hasNext()) {
Actor actor = (Actor) actors.next();
int firingsRemaining = ((Integer) firingsRemainingVector
.get(actor)).intValue();
if (firingsRemaining == 0) {
unscheduledActorList.remove(actor);
continue;
}
int inputCount = _countUnfulfilledInputs(actor, actorList, true);
if (inputCount == 0) {
/**************************************************
* > NEW! *
**************************************************/
// Changed from addFirst to addLast, this does not really
// matter since this is are all the sources that have
// no input requirements to be fired.
readyToScheduleActorList.addLast(actor);
/**************************************************
* > NEW! *
**************************************************/
}
if (_debugging && VERBOSE) {
_debug("Actor " + ((ComponentEntity) actor).getName()
+ " has " + inputCount + " unfulfilledInputs.");
}
}
// Simulate production of initial tokens.
actors = actorList.iterator();
while (actors.hasNext()) {
Actor actor = (Actor) actors.next();
Iterator outputPorts = actor.outputPortList().iterator();
while (outputPorts.hasNext()) {
IOPort outputPort = (IOPort) outputPorts.next();
int count = DFUtilities.getTokenInitProduction(outputPort);
if (_debugging && VERBOSE) {
_debug("Simulating " + count + " initial tokens "
+ "created on " + outputPort);
}
if (count > 0) {
/**************************************************
* > NEW! *
**************************************************/
_simulateTokensCreatedLast(outputPort, count,
actorList, readyToScheduleActorList);
/**************************************************
* < NEW! *
**************************************************/
}
}
}
// Simulate a number of tokens initially present on each
// external input port.
for (Iterator inputPorts = container.inputPortList().iterator(); inputPorts
.hasNext();) {
IOPort port = (IOPort) inputPorts.next();
int count = ((Integer) externalRates.get(port)).intValue();
if (count > 0) {
_simulateExternalInputs(port, count, actorList,
readyToScheduleActorList);
}
}
/**************************************************
* > NEW! *
**************************************************/
// We copy all the initial ready actors into the parallelLevel
// to keep track of when we finalize processing every level.
for (actors = readyToScheduleActorList.iterator(); actors.hasNext();) {
// Changed from addFirst to addLast, this does not really
// matter since this is are all the sources that have
// no input requirements to be fired.
parallelLevel.addLast(actors.next());
}
/**************************************************
* > NEW! *
**************************************************/
// While we have actors left, pick one that is ready and fire it.
while (readyToScheduleActorList.size() > 0) {
if (_debugging && VERBOSE) {
_debug("Actors that can be scheduled:");
for (Iterator readyActors = readyToScheduleActorList
.iterator(); readyActors.hasNext();) {
Entity readyActor = (Entity) readyActors.next();
_debug(readyActor.getFullName());
}
_debug("Actors with firings left:");
for (Iterator remainingActors = unscheduledActorList
.iterator(); remainingActors.hasNext();) {
Entity remainingActor = (Entity) remainingActors.next();
_debug(remainingActor.getFullName());
}
}
// Pick an actor that is ready to fire.
Actor currentActor = (Actor) readyToScheduleActorList
.getFirst();
// Remove it from the list of actors we are waiting to fire.
while (readyToScheduleActorList.remove(currentActor)) {
}
/**************************************************
* > NEW! *
**************************************************/
// Remove it from the parallelLevel.
while (parallelLevel.remove(currentActor)) {
;
}
/**************************************************
* < NEW! *
**************************************************/
// Determine the number of times currentActor can fire.
int numberOfFirings = _computeMaximumFirings(currentActor);
// We should never schedule something more than the number
// of times expected by the balance equations. This might
// happen because we assume an infinite number of tokens
// are waiting on external ports.
int firingsRemaining = ((Integer) firingsRemainingVector
.get(currentActor)).intValue();
if (numberOfFirings > firingsRemaining) {
numberOfFirings = firingsRemaining;
}
if (_debugging && VERBOSE) {
_debug("Scheduling actor " + currentActor.getName() + " "
+ numberOfFirings + " times.");
}
// Update the firingsRemainingVector for this actor.
firingsRemaining -= numberOfFirings;
firingsRemainingVector.put(currentActor, Integer
.valueOf(firingsRemaining));
if (_debugging && VERBOSE) {
_debug(currentActor.getName() + " should fire "
+ firingsRemaining + " more times.");
}
// Simulate the tokens that are consumed by the actors
// input ports.
_simulateInputConsumption(currentActor, numberOfFirings);
// Add it to the schedule numberOfFirings times.
Firing firing = new Firing();
firing.setActor(currentActor);
firing.setIterationCount(numberOfFirings);
/**************************************************
* > NEW! *
**************************************************/
// newSchedule to auxSchedule
auxSchedule.add(firing);
/**************************************************
* < NEW! *
**************************************************/
// Get all its outputPorts
// and simulate the proper production of tokens.
for (Iterator outputPorts = currentActor.outputPortList()
.iterator(); outputPorts.hasNext();) {
IOPort outputPort = (IOPort) outputPorts.next();
int count = DFUtilities.getTokenProductionRate(outputPort);