+ /**
+ * Executes all events until a given condition is met. The simulation process can be constrained by a real world timestamp.
+ *
+ * @param condition the condition until which the events are be processed
+ * @param stopMillis the System.currentTimeMillis() when simulation definitely needs to stop. A value of -1 means no timeout.
+ * @return State of the event execution
+ * @formatter:off
+ * <code>NOTHING_DONE</code> if the {@link Timeline} was already empty
+ * <code>EXEC_OUT_OF_TIME</code> if the given maximum time was reached
+ * <code>EXEC_UNTIL_CONDITION</code> if the condition was met
+ * <code>EXEC_UNTIL_EMPTY</code> if events were executed until the {@link Timeline} was empty
+ * @formatter:on
+ * @author Christian Femers, Fabian Stemmler
+ */
+ public ExecutionResult executeUntil(BooleanSupplier condition, long stopMillis)
+ {
+ if (events.isEmpty())
+ {
+ lastTimeUpdated = getSimulationTime();
+ return ExecutionResult.NOTHING_DONE;
+ }
+ int checkStop = 0;
+ InnerEvent first = events.peek();
+ while (hasNext() && !condition.getAsBoolean())
+ {
+ events.remove();
+ lastTimeUpdated = first.getTiming();
+ first.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 setTimeFunction(LongSupplier time)
+ {
+ this.time = time;
+ }
+