It is intended for those interested in how the simulation package works. For information on using the packages see the simjava tutorial and simanim guide and simdiag guide.
The next aim was to produce a package to provide an animation of a design model for minimal effort.
The final aim (for version 1.2 at least) was to produce program modules for displaying results.
These aims were realised in three separate java packages, simjava, simanim and simdiag. simjava may be used independently of the others. simanim depends on and augments simjava, and the javabeans in simdiag are currently driven from simanim, but could be hived off and used independently if required.
simjava-1.2/ index.html -- Top level html file makefile -- Top level makefile makefile.config -- included by all makefiles eduni/ -- Source code for packages simanim/ simdiag/ simjava/ classes/ eduni/ -- Packages named eduni/* simanim/ simdiag/ simjava/ jars/ -- Default location for jars simjava.jar -- Bundles all packages examples/ README.txt -- More info on examples doc/ -- Reference documents + guidesThe packages are named "eduni.simjava" "eduni.simanim" "eduni.simdiag" to avoid name conflicts with other packages.
The run() method is implemented as follows:-
static public void run() { run_start(); while(run_tick()) { } run_stop(); }
run_tick() runs a single simulation tick. It sets all runnable entities running, waits for them all to grind to a halt, then pops an event off the future queue.
Sim_system is an entirely static class, so doesn't need to be instantiated to be used.
static void hold(int src, double delay) { Sim_event e = new Sim_event(Sim_event.HOLD_DONE,clock+delay,src); future.add(e); ((Sim_entity)entities.elementAt(src)).set_state(Sim_entity.HOLDING); }This creates a new event (of type HOLD_DONE), with the timestamp of current time + 123.0, adds it to the future event queue, and sets the state of the calling Sim_entity to HOLDING.
Sim_entity.sim_hold() then notifies Sim_system that it's about to stop and waits on its restart semaphore.
The figure below shows the interactions:-
A Sim_system method connects ports together.
static public void link_ports(String ent1, String port1, String ent2, String port2)
Anim_applet Anim_param Param_type_list Anim_entity Anim_port Sim_anim Anim_event Param_typeThe important classes in the simanim package are Anim_applet and Sim_anim. Anim_entity, Anim_port and Anim_event store animation-specific details for the corresponding simjava classes Sim_entity, Sim_port and Sim_event. Anim_param, Param_type and Param_type_list store displayed parameters and types.
public abstract class Anim_applet extends Applet implements Runnable, ActionListener, AdjustmentListener, Traceable { ... public void anim_init() {} public abstract void anim_layout(); public final void init() {} } public class Sim_anim extends Canvas implements Sim_output, Traceable { ... public void animate(Thread simThread) {...} public void println(String msg) {...} }
The user's applet derives from Anim_applet, and provides versions of anim_init to create buttons and anim_layout to build the simulation. Anim_applet's init method creates the panel, creates an instance of Sim_anim, creates the control buttons, and calls the user's anim_init().
Sim_anim's animate() method controls the running of the simulation. The three Sim_system methods used are:-
Sim_system.run_start(); running = Sim_system.run_tick(); Sim_system.run_stop();
The standard Sim_system.link_ports() calls the Sim_anim version:-
public void link_ports(String e1, String p1, String e2, String p2)
As the simulation runs, the interface between the user's simulation code and simanim is through the trace generated.
Where the simulation code calls:
sim_trace(1, "P BUSY");This calls:
Sim_entity.sim_trace(1,"P BUSY");which calls
Sim_system.trace(entityid,"P BUSY");which calls
Sim_anim.println("u:sender at 1.23 : P BUSY");which constructs an Anim_event from this, adds it to the events list and forwards the trace to any trace event listeners.
The standard generator of EventObjects is the Sim_anim class, which generates a stream of events from the trace produced by the user's simulation. These may be connected to the input of any number of TimingDiagram objects in order to display the trace as a timing diagram. The trace stream may also be saved to a file using the TraceSaver class.
The figure below shows Sim_anim connected to a TimingDiagram which is in turn connected to a TraceSaver which stores the trace in a file.
These connections were made by calling addTraceListener() from anim_init():
// Add a timing diagram TimingWindow tw = new TimingWindow(); trace_out.addTraceListener( tw.getDiag() ); // Add a trace saver tw.getDiag().addTraceListener( new TraceSaver("tracefile") ); tw.start();See the example for all the code. The trace file is split into sections to denote the data types, names of bars to display, and finally the events themselves. An example is shown below:
$types State IDLE BUSY SEND RECV $bars p[0] State p[1] State $events u:p[0] at 1.234: P IDLE u:p[1] at 4.567: P BUSY ...This declares the type State to have one of the four values listed, says there are to be two bars on the timing diagram (named p[0] and p[1]) both of type State, then lists the timestamped events. The format of the event is
u:entity name at timestamp: P parameter value
The Graph object implements the GraphListener interface in order to update its display:-
public interface GraphListener extends EventListener { void handleGraph(GraphEventObject teo); }The GraphEventObjects are:-