View Javadoc

1   /*
2    * @(#)DEVSSimulator.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.eventlists.EventListInterface;
16  import nl.tudelft.simulation.dsol.eventlists.RedBlackTree;
17  import nl.tudelft.simulation.dsol.experiment.Replication;
18  import nl.tudelft.simulation.dsol.experiment.TimeUnit;
19  import nl.tudelft.simulation.dsol.experiment.TimeUnitInterface;
20  import nl.tudelft.simulation.dsol.formalisms.devs.SimEvent;
21  import nl.tudelft.simulation.dsol.formalisms.devs.SimEventInterface;
22  import nl.tudelft.simulation.event.Event;
23  import nl.tudelft.simulation.logger.Logger;
24  
25  /***
26   * The DEVS defines the interface of the DEVS simulator. DEVS stands for the
27   * Discrete Event System Specification. More information on Discrete Event
28   * Simulation can be found in "Theory of Modeling and Simulation" by Bernard
29   * Zeigler et. al.
30   * <p>
31   * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
32   * University of Technology </a>, the Netherlands. <br>
33   * See for project information <a href="http://www.simulation.tudelft.nl">
34   * www.simulation.tudelft.nl </a> <br>
35   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
36   * License (GPL) </a>, no warranty <br>
37   * 
38   * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
39   *         Jacobs </a>
40   * @version 1.16 2004-03-18
41   * @since 1.0
42   */
43  public class DEVSSimulator extends Simulator implements DEVSSimulatorInterface
44  {
45  
46  	/***
47  	 * eventList represents the future event list
48  	 * 
49  	 * @uml.property name="eventList"
50  	 */
51  	protected EventListInterface eventList = new RedBlackTree();
52  
53  
54  	/***
55  	 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface
56  	 *      #cancelEvent(SimEventInterface)
57  	 */
58  	public boolean cancelEvent(final SimEventInterface event)
59  	{
60  		return this.eventList.remove(event);
61  	}
62  
63  	/***
64  	 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface
65  	 *      #getEventList()
66  	 * 
67  	 * @uml.property name="eventList"
68  	 */
69  	public EventListInterface getEventList()
70  	{
71  		return this.eventList;
72  	}
73  
74  
75  	/***
76  	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface
77  	 *      #initialize(nl.tudelft.simulation.dsol.experiment.Replication)
78  	 */
79  	public void initialize(final Replication replication)
80  			throws RemoteException, SimRuntimeException
81  	{
82  		synchronized (super.semaphore)
83  		{
84  			super.initialize(replication);
85  			this.eventList.clear();
86  			this.replication.getRunControl().getTreatment().getExperiment()
87  					.getModel().constructModel(this);
88  			this.scheduleEvent(new SimEvent(this.getReplication()
89  					.getRunControl().getRunLength(),
90  					(short) (SimEventInterface.MIN_PRIORITY - 1), this, this,
91  					"stop", null));
92  			Object[] args = {new Event(SimulatorInterface.WARMUP_EVENT, this,
93  					null)};
94  			this.scheduleEvent(new SimEvent(this.getReplication()
95  					.getRunControl().getWarmupPeriod(),
96  					(short) (SimEventInterface.MAX_PRIORITY + 1), this, this,
97  					"fireEvent", args));
98  		}
99  	}
100 
101 	/***
102 	 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface
103 	 *      #scheduleEvent(SimEventInterface)
104 	 */
105 	public void scheduleEvent(final SimEventInterface event)
106 			throws SimRuntimeException
107 	{
108 		synchronized (super.semaphore)
109 		{
110 			if (event.getAbsoluteExecutionTime() < super.simulatorTime
111 					|| new Double(event.getAbsoluteExecutionTime()).isNaN())
112 			{
113 				throw new SimRuntimeException("cannot schedule event "
114 						+ event.toString() + " in past " + this.simulatorTime
115 						+ ">" + event.getAbsoluteExecutionTime());
116 			}
117 			this.eventList.add(event);
118 			Logger.finest(this, "scheduleEvent", "scheduled event at "
119 					+ event.getAbsoluteExecutionTime());
120 		}
121 	}
122 
123 	/***
124 	 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface#scheduleEvent(double,
125 	 *      java.lang.Object, java.lang.Object, java.lang.String,
126 	 *      java.lang.Object[])
127 	 */
128 	public void scheduleEvent(double relativeDelay, Object source,
129 			Object target, String method, Object[] args)
130 			throws SimRuntimeException
131 	{
132 		this.scheduleEvent(relativeDelay, SimEventInterface.NORMAL_PRIORITY,
133 				source, target, method, args);
134 	}
135 
136 	/***
137 	 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface#scheduleEvent(double,
138 	 *      short, java.lang.Object, java.lang.Object, java.lang.String,
139 	 *      java.lang.Object[])
140 	 */
141 	public void scheduleEvent(double relativeDelay, short priority,
142 			Object source, Object target, String method, Object[] args)
143 			throws SimRuntimeException
144 	{
145 		this.scheduleEvent(new SimEvent(this.simulatorTime + relativeDelay,
146 				priority, source, target, method, args));
147 	}
148 
149 	/***
150 	 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface#scheduleEvent(double,
151 	 *      nl.tudelft.simulation.dsol.experiment.TimeUnitInterface,
152 	 *      java.lang.Object, java.lang.Object, java.lang.String,
153 	 *      java.lang.Object[])
154 	 */
155 	public void scheduleEvent(double relativeDelay, TimeUnitInterface timeUnit,
156 			Object source, Object target, String method, Object[] args)
157 			throws RemoteException, SimRuntimeException
158 	{
159 		this
160 				.scheduleEvent(TimeUnit.convert(relativeDelay, timeUnit, this),
161 						SimEventInterface.NORMAL_PRIORITY, source, target,
162 						method, args);
163 	}
164 
165 	/***
166 	 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface#scheduleEvent(double,
167 	 *      nl.tudelft.simulation.dsol.experiment.TimeUnitInterface, short,
168 	 *      java.lang.Object, java.lang.Object, java.lang.String,
169 	 *      java.lang.Object[])
170 	 */
171 	public void scheduleEvent(double relativeDelay, TimeUnitInterface timeUnit,
172 			short priority, Object source, Object target, String method,
173 			Object[] args) throws RemoteException, SimRuntimeException
174 	{
175 		this.scheduleEvent(TimeUnit.convert(relativeDelay, timeUnit, this),
176 				priority, source, target, method, args);
177 	}
178 
179 	/***
180 	 * @see nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface
181 	 *      #setEventList(EventListInterface)
182 	 * 
183 	 * @uml.property name="eventList"
184 	 */
185 	public synchronized void setEventList(final EventListInterface eventList)
186 	{
187 		this.eventList = eventList;
188 		Logger.finer(this, "setEventList", "set the eventList to "
189 				+ eventList.toString());
190 		this.fireEvent(EVENTLIST_CHANGED_EVENT, null);
191 	}
192 
193 	/***
194 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#step()
195 	 */
196 	public void step() throws SimRuntimeException
197 	{
198 		synchronized (super.semaphore)
199 		{
200 			super.step();
201 			if (!this.eventList.isEmpty())
202 			{
203 				this.running = true;
204 				SimEventInterface event = this.eventList.removeFirst();
205 				this.simulatorTime = event.getAbsoluteExecutionTime();
206 				this.fireEvent(SimulatorInterface.TIME_CHANGED_EVENT,
207 						this.simulatorTime, this.simulatorTime);
208 				event.execute();
209 				this.running = false;
210 			}
211 		}
212 	}
213 
214 	/***
215 	 * @see nl.tudelft.simulation.dsol.simulators.Simulator#run()
216 	 */
217 	public void run()
218 	{
219 		while (isRunning())
220 		{
221 			synchronized (super.semaphore)
222 			{
223 				SimEventInterface event = this.eventList.removeFirst();
224 				this.simulatorTime = event.getAbsoluteExecutionTime();
225 				fireEvent(SimulatorInterface.TIME_CHANGED_EVENT,
226 						this.simulatorTime, this.simulatorTime);
227 				try
228 				{
229 					event.execute();
230 				} catch (Exception exception)
231 				{
232 					Logger.severe(this, "run", exception);
233 				}
234 			}
235 		}
236 	}
237 
238 	/***
239 	 * @see nl.tudelft.simulation.dsol.simulators.SimulatorInterface#stop()
240 	 */
241 	public void stop()
242 	{
243 		super.stop();
244 		if (this.getReplication() != null
245 				&& this.simulatorTime >= this.getReplication().getRunControl()
246 						.getRunLength())
247 		{
248 			this.eventList.clear();
249 		}
250 		if (this.eventList.isEmpty())
251 		{
252 			this.fireEvent(new Event(
253 					SimulatorInterface.END_OF_REPLICATION_EVENT, this, null));
254 		}
255 	}
256 }