View Javadoc

1   /*
2    * @(#)Simulator.java Aug 18, 2003
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
9    */
10  package nl.tudelft.simulation.dsol.simulators;
11  
12  import java.rmi.RemoteException;
13  
14  import nl.tudelft.simulation.dsol.SimRuntimeException;
15  import nl.tudelft.simulation.dsol.experiment.Replication;
16  import nl.tudelft.simulation.event.Event;
17  import nl.tudelft.simulation.event.EventProducer;
18  import nl.tudelft.simulation.jstats.statistics.StatisticsObject;
19  import nl.tudelft.simulation.language.concurrent.WorkerThread;
20  import nl.tudelft.simulation.logger.Logger;
21  
22  /***
23   * The Simulator class is an abstract implementation of the SimulatorInterface.
24   * <p>
25   * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
26   * University of Technology </a>, the Netherlands. <br>
27   * See for project information <a href="http://www.simulation.tudelft.nl">
28   * www.simulation.tudelft.nl </a> <br>
29   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
30   * License (GPL) </a>, no warranty <br>
31   * 
32   * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
33   *         Jacobs </a>
34   * @version 1.13 2004-03-18
35   * @since 1.0
36   */
37  public abstract class Simulator extends EventProducer implements
38  		SimulatorInterface, Runnable
39  {
40  
41  	/***
42  	 * simulatorTime represents the simulationTime
43  	 * 
44  	 * @uml.property name="simulatorTime"
45  	 */
46  	protected double simulatorTime = Double.NaN;
47  
48  	/***
49  	 * running represents the binary state of the simulator
50  	 * 
51  	 * @uml.property name="running"
52  	 */
53  	protected boolean running = false;
54  
55  	/***
56  	 * replication represents the currently active replication
57  	 * 
58  	 * @uml.property name="replication"
59  	 */
60  	protected Replication replication = null;
61  
62  
63  	/*** a worker */
64  	protected WorkerThread worker = null;
65  
66  	/*** the simulatorSemaphore */
67  	protected Object semaphore = new Object();
68  
69  	/***
70  	 * constructs a new Simulator
71  	 */
72  	public Simulator()
73  	{
74  		this.worker = new WorkerThread(this.getClass().getName(), this);
75  	}
76  
77  	/***
78  	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface
79  	 *      #getSimulatorTime()
80  	 * 
81  	 * @uml.property name="simulatorTime"
82  	 */
83  	public double getSimulatorTime()
84  	{
85  		return this.simulatorTime;
86  	}
87  
88  	/***
89  	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface
90  	 *      #getReplication()
91  	 * 
92  	 * @uml.property name="replication"
93  	 */
94  	public Replication getReplication()
95  	{
96  		return this.replication;
97  	}
98  
99  
100 	/***
101 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface
102 	 *      #initialize(Replication)
103 	 */
104 	public void initialize(final Replication replication)
105 			throws RemoteException, SimRuntimeException
106 	{
107 		if (replication == null)
108 		{
109 			throw new IllegalArgumentException("replication == null ?");
110 		}
111 		if (this.isRunning())
112 		{
113 			throw new SimRuntimeException(
114 					"Cannot initialize a running simulator");
115 		}
116 		synchronized (this.semaphore)
117 		{
118 			this.removeAllListeners(StatisticsObject.class);
119 			this.replication = replication;
120 			this.simulatorTime = 0.0;
121 			this.fireEvent(SimulatorInterface.START_REPLICATION_EVENT, null,
122 					((SimulatorInterface) this).getSimulatorTime());
123 			this.fireEvent(SimulatorInterface.TIME_CHANGED_EVENT,
124 					this.simulatorTime, this.simulatorTime);
125 			Logger.finer(this, "initialize", "OK");
126 		}
127 	}
128 
129 	/***
130 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#isRunning()
131 	 * 
132 	 * @uml.property name="running"
133 	 */
134 	public boolean isRunning()
135 	{
136 		return this.running;
137 	}
138 
139 	/***
140 	 * The run method defines the actual time step mechanism of the simulator.
141 	 * The implementation of this method depends on the formalism. Where
142 	 * discrete event formalisms loop over an eventlist continuous simulators
143 	 * take pre-defined time steps.
144 	 *  
145 	 */
146 	public abstract void run();
147 
148 	/***
149 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#start()
150 	 */
151 	public void start() throws SimRuntimeException, RemoteException
152 	{
153 		if (this.isRunning())
154 		{
155 			throw new SimRuntimeException("Cannot start a running simulator");
156 		}
157 		if (this.replication == null)
158 		{
159 			throw new SimRuntimeException("Cannot start a simulator"
160 					+ " without replication details");
161 		}
162 		if (this.simulatorTime >= this.replication.getRunControl()
163 				.getRunLength())
164 		{
165 			throw new SimRuntimeException("Cannot start simulator : "
166 					+ "simulatorTime = runLength");
167 		}
168 		synchronized (this.semaphore)
169 		{
170 			this.running = true;
171 			this.fireEvent(START_EVENT, null);
172 			this.fireEvent(SimulatorInterface.TIME_CHANGED_EVENT,
173 					this.simulatorTime, this.simulatorTime);
174 			Logger.finer(this, "start", "OK");
175 			if (!Thread.currentThread().getName().equals(this.worker.getName()))
176 			{
177 				this.worker.interrupt();
178 			} else
179 			{
180 				this.run();
181 			}
182 		}
183 	}
184 
185 	/***
186 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#step()
187 	 */
188 	public void step() throws SimRuntimeException
189 	{
190 		if (this.isRunning())
191 		{
192 			throw new SimRuntimeException("Cannot step a running simulator");
193 		}
194 		if (this.replication == null)
195 		{
196 			throw new SimRuntimeException("Cannot step a simulator "
197 					+ "without replication details");
198 		}
199 		if (this.simulatorTime >= this.replication.getRunControl()
200 				.getRunLength())
201 		{
202 			throw new SimRuntimeException("Cannot step simulator: "
203 					+ "SimulatorTime = runControl.runLength");
204 		}
205 		Logger.finer(this, "step", "OK");
206 		this.fireEvent(SimulatorInterface.STEP_EVENT, null);
207 	}
208 
209 	/***
210 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#stop()
211 	 */
212 	public void stop()
213 	{
214 		if (this.isRunning())
215 		{
216 			this.running = false;
217 			Logger.finer(this, "stop", "OK");
218 			if (this.simulatorTime >= this.getReplication().getRunControl()
219 					.getRunLength())
220 			{
221 				this
222 						.fireEvent(new Event(
223 								SimulatorInterface.END_OF_REPLICATION_EVENT,
224 								this, null));
225 			}
226 			this.fireEvent(SimulatorInterface.STOP_EVENT, null);
227 		}
228 	}
229 }