// Simulation.java import java.util.PriorityQueue; /** Simulation framework *

This discrete-event simulation framework allows users to create * {@link Event} objects, {@link schedule} them at future times, and then * {@link run} the simulation by triggering the events in chronological order. * Triggering an event may cause additional events to be scheduled, so that * a small finite set of initial events may to a simulation that runs on * indefinitely until some event terminates the simulation. * @author Douglas W. Jones * @version 2019-04-12 */ public class Simulation { /** Users create subclasses of Event for each scheduled action *

Typically, users create anonymous subclasses when they schedule * new events. See the documentation of {@link schedule} for * an example. */ public static abstract class Event { // the time of the simulated event protected float time; /** Constructing an event sets its time * @param t the time of the event */ public Event( float t ) { time = t; } /** The action taken by the event *

Users must create a subclass of {@link Event} for each specific * action to be taken in the simulation. Generally, the only thing * in the subclass will be a new trigger method. *

Inside the trigger method, the variable time * refers to the current simulation time. Code in the * trigger method may do anything, including calling * {@link schedule} to schedule future events. */ abstract void trigger(); } // 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 *

A typical call will look like this, creating a new instance of an * anonymous subclass of {@link Simulation.Event} as it schedules the * new event: *

     *  Simulation.schedule(
     *      new Simulation.Event( theEventTime ) {
     *          void trigger() {
     *              WhateverActionThisEventDoes();
     *          }
     *      }
     *  );
     *  @param e the time at which the event should occur
     *
*/ public static void schedule( Event e ) { eventSet.add( e ); } /** run a simulation *

Call this after scheduling at least one {@link Event}. *

The simulation will run until either there are no more events or * some event terminates the program. * From the point where run is called onward, * 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.trigger(); } } }