⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simsystem.java

📁 一个用于排队系统仿真的开源软件,有非常形象的图象仿真过程!
💻 JAVA
字号:
/**
 * The simjava package is a support library for discrete
 * event simulations.
 */

package jmt.engine.simEngine;


import java.text.NumberFormat;
import java.util.Enumeration;
import java.util.Vector;

/**
 * This is the system class which manages the simulation. All
 * the members of this class are static, so there is no need to
 * create an instance of this class.
 */
public class SimSystem {

	private static boolean DEBUG = false;


	// Private data members
	static private Vector entities;  // The current entity list

    //TODO: verificare quale classe funziona meglio per la future event queue
//	static private EventQueue future;   // The future event queue
	static private NewEvQueue future;   // The future event queue
//	static private SuperEventQueue future; // The future event queue


	static private EventQueue deferred; // The deferred event queue

    static private double clock;     // Holds the current global simulation time
	static private boolean running;  // Tells whether the run() member been called yet
	static private NumberFormat nf;


    //STE
    //temp variable used by runTick
    //static private SimEvent event = null;


    //NEW
    //@author Stefano Omini

    //if true a timer has been defined on the simulation
    static private boolean hasTimer = false;

    //if true, max simulation time has been reached and simulation must be aborted
    static private boolean timeout = false;

    //true if the simulation has been finished and therefore SimSystem must be stopped
    static private boolean simStopped = false;


    //end NEW


    //NEW
    //@author Stefano Omini

    /**
     * Sets timeout property
     * @param simTimeout True if max time has been reached
     */
    static public void setTimeout(boolean simTimeout) {
        timeout = simTimeout;
        hasTimer = true;
    }
    //end NEW


	//
	// Public library interface
	//

	// Initializes system
	/** Initializes the system, this function works as a
	 * constructor, and should be called at the start of any simulation
	 * program. It comes in several flavours depending on what context
	 * the simulation is running.<P>
	 * This is the simplest, and should be used for standalone simulations
	 * It sets up trace output to a file in the current directory called
	 * `tracefile'
	 */
	static public void initialize() {

		entities = new Vector();

        //TODO: verificare quale classe funziona meglio per la future event queue

//		future = new EventQueue();
		future = new NewEvQueue();
//      future = new SuperEventQueue();

		deferred = new EventQueue();

        clock = 0.0;
		running = false;

		// Set the default number format
		nf = NumberFormat.getInstance();
		nf.setMaximumFractionDigits(4);
		nf.setMinimumFractionDigits(2);

	}

	/** Returns the number format used for generating
	 * times in trace lines
	 */
	static public NumberFormat getNumberFormat() {
		return nf;
	}

	// The two standard predicates
	/** A standard predicate that matches any event. */
	static public SimAnyP SIM_ANY = new SimAnyP();
	/** A standard predicate that does not match any events. */
	static public SimNoneP SIM_NONE = new SimNoneP();


    // Public access methods

    /** Get the current simulation time.
	 * @return The simulation time
	 */
	static public double clock() {
		return clock;
	}

	/** A different name for <tt>SimSystem.clock()</tt>.
	 * @return The current simulation time
	 */
	static public double getClock() {
		return clock;
	}

	/** Gets the current number of entities in the simulation
	 * @return A count of entities
	 */
	static public int getNumEntities() {
		return entities.size();
	}


	/** Finds an entity by its id number.
	 * @param id The entity's unique id number
	 * @return A reference to the entity, or null if it could not be found
	 */
	static final public SimEntity getEntity(int id) {
		return (SimEntity) entities.elementAt(id);
	}

	/** Finds an entity by its name.
	 * @param name The entity's name
	 * @return A reference to the entity, or null if it could not be found
	 */
	static public SimEntity getEntity(String name) {
		Enumeration e;
		SimEntity ent, found = null;

		for (e = entities.elements(); e.hasMoreElements();) {
			ent = (SimEntity) e.nextElement();
			if (name.compareTo(ent.getName()) == 0)
				found = ent;
		}
		if (found == null)
			System.out.println("SimSystem: could not find entity " + name);
		return found;
	}

	/** Finds out an entity unique id number from its name.
	 * @param name The entity's name
	 * @return The entity's unique id number, or -1 if it could not be found
	 */
	static public int getEntityId(String name) {
		return entities.indexOf(getEntity(name));
	}

	/** Adds a new entity to the simulation.
	 * This is now done automatically in the SimEntity constructor,
	 * so there is no need to call this explicitly.
	 * @param e A reference to the new entity
	 */
	static public void add(SimEntity e) {
		SimEvent evt;
		if (running()) {
			/* Post an event to make this entity */
			evt = new SimEvent(SimEvent.CREATE, clock, e.getId(), 0, 0, e);
			future.add(evt);
		} else {
			if (e.getId() == -1) {

                //-1 is the default value written by the constructor.
                // Now a new ID is set

                // Only add once!
				e.setId(entities.size());
				entities.addElement(e);
			}
		}
	}

	/** Adds a new entity to the simulation, when the simulation is running.
	 * Note this is an internal method and should not be called from
	 * user simulations. Use <tt>add()</tt> instead to add entities
	 * on the fly.
	 * @param e A reference to the new entity
	 */
	static synchronized void addEntityDynamically(SimEntity e) {
		e.setId(entities.size());
		if (e == null) {
			System.out.println("Adding null entity :(");
		} else {
			System.out.println("Adding: " + e.getName());
		}
		entities.addElement(e);
		e.start();
	}


	/**
     * Starts the simulation running, by calling the start() method of each entity.
     * Of course this should be called after all the entities have been setup and added,
     * and their ports linked.
	 */
	static public void runStart() {
		Enumeration e;
		SimEntity ent;
		running = true;
		// Start all the entities' threads
		if (DEBUG)
			System.out.println("SimSystem: Starting entities");
		for (e = entities.elements(); e.hasMoreElements();) {
			ent = (SimEntity) e.nextElement();
			ent.start();
		}
	}

	/**
     * Runs one tick of the simulation: the system looks for events in the future queue.
     * @return <tt>false</tt> if there are no more future events to be processed
	 */
	static public boolean runTick() throws jmt.common.exception.NetException {

        //NEW
        //@author Stefano Omini

        if (timeout) {
            //time has expired: simulation must be aborted
            return false;
        }


        // If there are more future events then deals with them
        SimEvent event;

        if (future.size() > 0) {
			event = future.pop();

			processEvent(event);
			double now = event.eventTime();
			// Checks if next events are at same time...
			boolean trymore = (future.size() > 0);
			while (trymore) {
				event = future.top();
				if (event.eventTime() == now) {
					processEvent(future.pop());
					trymore = (future.size() > 0);
				} else
					trymore = false;
			}
		} else {
			running = false;
			//System.out.println("SimSystem: No more future events");

		}
		return running;
	}


	/** Stops the simulation, by calling the poison() method of each SimEntity.
	 */
	static public void runStop() {
		Enumeration e;
		SimEntity ent;
		// Attempt to kill all the entity threads
		for (e = entities.elements(); e.hasMoreElements();) {
			ent = (SimEntity) e.nextElement();
			ent.poison();
		}
		if (DEBUG)
			System.out.println("Exiting SimSystem.run()");
	}


    //TODO: usato solo per debug
	/** Starts the simulation running. This should be called after
	 * all the entities have been setup and added, and their ports linked.
     * <br>
     * The simulation goes on until runTick() becomes false (there are no more
     * future events to be processed).
     * Then the runStop() method is called.
	 */
	static public void run() throws jmt.common.exception.NetException {
		//Now the main loop
		//System.out.println("SimSystem: Entering main loop");
		runStart();
		while (runTick()) {
		}
		runStop();
	}

	//
	// Package level methods
	//

	static boolean running() {
		return running;
	}


	// Entity service methods

	// Called by an entity just before it becomes non-RUNNABLE
//	static void paused() {
//		onestopped.v();
//	}

	static synchronized void hold(int src, double delay) {
		SimEvent e = new SimEvent(SimEvent.HOLD_DONE, clock + delay, src);
		future.add(e);
	}

	static synchronized void send(int src, int dest, double delay, int tag, Object data) {
		SimEvent e = new SimEvent(SimEvent.SEND, clock + delay, src, dest, tag, data);
		future.add(e);
	}

	static synchronized void wait(int src) {

	}

	static synchronized int waiting(int d, SimPredicate p) {
		int w = 0;
		SimEvent event;
		//DEK (Federico Granata) 25-11-2003
		for (int i = 0; i < deferred.size(); i++) {
			event = (SimEvent) deferred.elementAt(i);
			if (event.getDest() == d)
				if (p.match(event))
					w++;
		}
		return w;

		/* old
		for (e = deferred.elements(); e.hasMoreElements();) {
			ev = (SimEvent) e.nextElement();
			if (ev.getDest() == d) {
				//	trcout.println("t: in waiting, - event from "+ev.getSrc()+" to "+
				//	       ev.getDest() + " type:"+ev.type()+" time:"+ev.eventTime());

				if (p.match(ev))
					w++;
			}
		}
		return w;*/
		//end DEK (Federico Granata) 25-11-2003
	}

	static synchronized void select(int src, SimPredicate p) {
		Enumeration e;
		SimEvent ev = null;
		boolean found = false;

		// retrieve + remove event with dest == src
		for (e = deferred.elements(); (e.hasMoreElements()) && !found;) {
			ev = (SimEvent) e.nextElement();
			if (ev.getDest() == src) {
				if (p.match(ev)) {
					deferred.removeElement(ev);
					found = true;
				}
			}
		}
		if (found) {
			((SimEntity) entities.elementAt(src)).setEvbuf((SimEvent) ev.clone());

		} else {
			((SimEntity) entities.elementAt(src)).setEvbuf(null);

		}
	}

	static synchronized void cancel(int src, SimPredicate p) {
		Enumeration e;
		SimEvent ev = null;
		boolean found = false;

		// retrieves + remove event with dest == src
		for (e = future.elements(); (e.hasMoreElements()) && !found;) {
			ev = (SimEvent) e.nextElement();
			if (ev.getSrc() == src) {
				if (p.match(ev)) {
					future.removeElement(ev);
					found = true;
				}
			}
		}
		if (found) {
			((SimEntity) entities.elementAt(src)).setEvbuf((SimEvent) ev.clone());

		} else {
			((SimEntity) entities.elementAt(src)).setEvbuf(null);

		}
	}

	static synchronized void putback(SimEvent ev) {
		deferred.add(ev);
	}

	//
	// Private internal methods
	//

	static private void processEvent(SimEvent e) throws jmt.common.exception.NetException {
		int dest, src;
		SimEntity destEnt;

		//System.out.println("SimSystem: Processing event");
		// Update the system's clock
		if (e.eventTime() < clock) {
			throw new jmt.common.exception.NetException("SimSystem: Error - past event detected! \n" +
			        "Time: " + clock + ", event time: " + e.eventTime() +
			        ", event type: " + e.getType() + future);
		}
		clock = e.eventTime();

		// Ok now process it
		switch (e.getType()) {

            case (SimEvent.SEND):
				// Checks for matching wait
				dest = e.getDest();
				if (dest < 0)
					throw new jmt.common.exception.NetException("SimSystem: Error - attempt to send to a null entity");
				else {
					destEnt = (SimEntity) entities.elementAt(dest);
					if (destEnt.getState() == SimEntity.WAITING) {
						SimPredicate p = destEnt.getWaitingPred();

						if (p == null) {
                            //the entity was waiting for a generic predicate
							destEnt.setEvbuf((SimEvent) e.clone());
							destEnt.setState(SimEntity.RUNNABLE);
							try {
								destEnt.execute();
							} catch (jmt.common.exception.NetException e1) {
								abort();
								throw e1;
							}
						} else {
							//the entity was waiting for events with a specified predicate
                            //this event matches with such predicate??
                            if (destEnt.getWaitingPred().match(e)) {
								p = null;
								destEnt.setEvbuf((SimEvent) e.clone());
								destEnt.setState(SimEntity.RUNNABLE);
								try {
									destEnt.execute();
								} catch (jmt.common.exception.NetException e1) {
									abort();
									throw e1;
								}
							} else {
								//the event doesn't match with the predicate, so it's put in the deferred queue
                                destEnt.simPutback(e);
							}
						}
					} else {
						//if the entity is not WAITING the event is put in the deferred queue
                        deferred.add(e);
					}
				}
				break;

            case (SimEvent.ENULL):
                            throw new jmt.common.exception.NetException("SimSystem: Error - event has a null type");

            case (SimEvent.CREATE):
                SimEntity newe = (SimEntity) e.getData();
                addEntityDynamically(newe);
                break;


            case (SimEvent.HOLD_DONE):
                src = e.getSrc();
                if (src < 0)
                    throw new jmt.common.exception.NetException("SimSystem: Error - NULL entity holding");
                else {
					((SimEntity) entities.elementAt(src)).setState(SimEntity.RUNNABLE);
					((SimEntity) entities.elementAt(src)).restart();
				}
				break;
		}
	}

	/**
     * Aborts the simulation!
	 *
	 */
	static public void abort() {
		running = false;
		if (DEBUG) {
            System.out.println("Simulation Aborted");
        }
	}


    //NEW
    //@author Stefano Omini

    /**
     * By using this method, the simulation can be aborted or stopped even if there
     * are still events in the future events queue.
     * @param simStopped true to stop SimSystem
     */
    public static void setSimStopped(boolean simStopped) {
        SimSystem.simStopped = simStopped;
    }

    //end NEW


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -