/* Author: Jeff Dalton * Updated: Fri Nov 24 16:29:56 2000 by Jeff Dalton * Copyright: (c) 2000, AIAI, University of Edinburgh */ package ix.examples; import java.util.*; import ix.util.*; import ix.util.lisp.*; /** * A simple example using an I-X framework. This example shows one * way to extend PicoISim to create a simulator that treats each tick * of simulated time as one second of real time. */ public class PicoISimTest2 extends PicoISim { /** * Main program. */ public static void main(String[] argv) { // Create the simulator. final IX_Simulator sim = new TestSimulator(); sim.setStopWhenIdle(false); sim.setListener(new IX_SystemListener()); // Schedule some initial events. sim.schedule(new SimEvent("return", "foo", 15)); sim.schedule(new SimEvent("return", "pre-foo", 10)); // Start the simulation. sim.start(); // While the simulation is running, the user can schedule // a new event by hitting return. new Thread() { public void run() { while (true) { Util.readLine(System.in); sim.schedule(new SimEvent("return", "ok", 0)); } } }.start(); } // Define a subclass instead of specifying a TestSimController // when creating a new IX_Simulator and instead of calling // addSimEventHandlers() to add the event handlers. static class TestSimulator extends IX_Simulator { TestSimulator() { super(new TestSimController(), null); } Object[] makeBuiltinSimEventHandlers() { return new Object[] { new SimEventHandler("return") { void handleIssue(Issue i) { system.notifyListener(i.object); } } }; } } static class TestSimController extends SimController { TestSimController() {} boolean simulateIfPossible(SimEvent e) { // Here's our difference from the inherited method: // wait for the time difference between the current // simulated time and the est of the event (if that // est is later) in a way that also allows an external // event (message) to get in. long real_t = System.currentTimeMillis(); long sim_t = getSimTime(); if (e.est > sim_t) { long sim_delay = e.est - sim_t; long real_delay = sim_delay; Debug.noteln("... sleeping " + real_delay + " seconds ..."); if (q.waitForMessage(real_delay * 1000)) { // The simulator's received a message that might // schedule an event that should happen before // this one. // Figure out how much simulated time has passed. long real_delta = System.currentTimeMillis() - real_t; long sim_delta = Math.round(real_delta / 1000); Debug.noteln("But something happened after " + sim_delta); setSimTime(sim_t + sim_delta); // Return false indicate no simulation occurred // The simulator will then process the message. return false; } // else no message and we can simulate the event } return super.simulateIfPossible(e); } } }