private PriorityQueue<InnerEvent> events;
private LongSupplier time;
private long lastTimeUpdated = 0;
+ private long eventCounter = 0;
private final List<Consumer<TimelineEvent>> eventAddedListener;
return ExecutionResult.NOTHING_DONE;
}
int checkStop = 0;
- InnerEvent first = events.peek();
while (hasNext() && !condition.getAsBoolean())
{
- events.remove();
- lastTimeUpdated = first.getTiming();
- first.run();
+ InnerEvent event;
+ synchronized (events)
+ {
+ event = events.remove();
+ }
+ lastTimeUpdated = event.getTiming();
+ event.run();
// Don't check after every run
checkStop = (checkStop + 1) % 10;
if (checkStop == 0 && System.currentTimeMillis() >= stopMillis)
return ExecutionResult.EXEC_OUT_OF_TIME;
- first = events.peek();
}
lastTimeUpdated = getSimulationTime();
return hasNext() ? ExecutionResult.EXEC_UNTIL_EMPTY : ExecutionResult.EXEC_UNTIL_CONDITION;
*/
public void reset()
{
- events.clear();
+ synchronized (events)
+ {
+ events.clear();
+ }
lastTimeUpdated = 0;
}
{
long timing = getSimulationTime() + relativeTiming;
TimelineEvent event = new TimelineEvent(timing);
- events.add(new InnerEvent(function, event));
+ synchronized (events)
+ {
+ events.add(new InnerEvent(function, event, eventCounter++));
+ }
eventAddedListener.forEach(l -> l.accept(event));
}
{
private final TimelineEventHandler function;
private final TimelineEvent event;
+ private final long id;
/**
* Creates an {@link InnerEvent}
* @param function {@link TimelineEventHandler} to be executed when the {@link InnerEvent} occurs
* @param timing Point in the MI simulation {@link Timeline}, at which the {@link InnerEvent} is executed;
*/
- InnerEvent(TimelineEventHandler function, TimelineEvent event)
+ InnerEvent(TimelineEventHandler function, TimelineEvent event, long id)
{
this.function = function;
this.event = event;
+ this.id = id;
}
public long getTiming()
@Override
public int compareTo(InnerEvent o)
{
- return timeCmp(getTiming(), o.getTiming());
+ int c1;
+ return (c1 = timeCmp(getTiming(), o.getTiming())) == 0 ? timeCmp(id, o.id) : c1;
}
}
- static int timeCmp(long a, long b)
+ public static int timeCmp(long a, long b)
{
return Long.signum(a - b);
}
@Override
public String toString()
{
- return String.format("Simulation time: %s, Last update: %d, Events: %s", getSimulationTime(), lastTimeUpdated, events.toString());
+ String eventsString;
+ synchronized (events)
+ {
+ eventsString = events.toString();
+ }
+ return String.format("Simulation time: %s, Last update: %d, Events: %s", getSimulationTime(), lastTimeUpdated, eventsString);
}
public enum ExecutionResult