// import java.util.PriorityQueue; must be somewhere above this /** Simulation framework * @author Douglas W. Jones * @version 2019-03-08 */ class Simulation { // this interface is so we can schedule events with lambda expressions public interface Action { void trigger( float time ); } // Events are scheduled on the event set private static class Event { final float time; // the simulated time of the event final Action act; // the action to trigger at that time Event( float t, Action a ) { time = t; act = a; } } // the central organizing data structure of the simulation private static final PriorityQueue eventSet = new PriorityQueue ( ( Event e1, Event e2 ) -> Float.compare( e1.time, e2.time ) ); /** schedule a new event * @param t the time at which the event should occur * @param a the Action that should occur at that time * A typical call will look like this * Simulation.schedule( someTime, (float t)->codeToRunAt( t ) ); * That is, the Action will be constructed by a lambda expression */ public static void schedule( float t, Action a ) { eventSet.add( new Event( t, a ) ); } /** run a simulation * Call this after scheduling at least one event. * The simulation will run until either there are no more events or * some event terminates the program. * From this point on, a typical simulation program will be event driven * with the ordering of computations determined by chronological ordering * of scheduled events. */ public static void run() { while (!eventSet.isEmpty()) { Event e = eventSet.remove(); e.act.trigger( e.time ); } } }