1 | package desmoj.core.simulator; |
2 | |
3 | /** |
4 | * Provides the class for user defined events to change the model's |
5 | * state at a distinct point in simulation time.<p> |
6 | * For events specifically changing the state of up to three entities, refer |
7 | * to <code>Event</code>, <code>EventOf2Entities</code> and <code>EventOf3Entities</code>. |
8 | * Events not associated to a specific entity are called external events as they |
9 | * are are typically used for external influences, e.g. arrivals from outside or incidents. |
10 | * |
11 | * |
12 | * Derive from this class to |
13 | * design special external events for a model. To use external events, always |
14 | * create a new object of this class. |
15 | * |
16 | * @see Event |
17 | * @see EventOf2Entities |
18 | * @see EventOf3Entities |
19 | * @see TimeInstant |
20 | * @see TimeSpan |
21 | * |
22 | * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011 |
23 | * @author Tim Lechler |
24 | * |
25 | * Licensed under the Apache License, Version 2.0 (the "License"); |
26 | * you may not use this file except in compliance with the License. You |
27 | * may obtain a copy of the License at |
28 | * http://www.apache.org/licenses/LICENSE-2.0 |
29 | * |
30 | * Unless required by applicable law or agreed to in writing, software |
31 | * distributed under the License is distributed on an "AS IS" |
32 | * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
33 | * or implied. See the License for the specific language governing |
34 | * permissions and limitations under the License. |
35 | * |
36 | */ |
37 | public abstract class ExternalEvent extends EventAbstract |
38 | { |
39 | |
40 | /** |
41 | * Creates an external event for the given model with the given name and the |
42 | * specified tracemode. |
43 | * |
44 | * @param owner |
45 | * Model : The external event's model |
46 | * @param name |
47 | * java.lang.String : The external event's name |
48 | * @param showInTrace |
49 | * boolean : Flag for showing this external event in |
50 | * tracemessages |
51 | */ |
52 | public ExternalEvent(Model owner, String name, boolean showInTrace) { |
53 | |
54 | super(owner, name, showInTrace); |
55 | this.numberOfEntities = 0; |
56 | |
57 | } |
58 | |
59 | /** |
60 | * Implement this method to express the semantics of this external event. |
61 | * External events are supposed to act on the model or experiment in |
62 | * general. They are not related to a special Entity (unlike method |
63 | * <code>eventRoutine(Entity who)</code> of class <code>Event</code>). |
64 | * Override this method to implement this Externalevent's behaviour. |
65 | */ |
66 | public abstract void eventRoutine(); |
67 | |
68 | /** |
69 | * Schedules this external event to make the desired changes to the |
70 | * experiment or model at the current point of time plus the given span of |
71 | * time |
72 | * |
73 | * @param dt |
74 | * TimeSpan : The offset to the current simulation time at which |
75 | * this external event is to be scheduled |
76 | * @see SimClock |
77 | */ |
78 | public void schedule(TimeSpan dt) { |
79 | if ((dt == null)) { |
80 | sendWarning("Can't schedule external event!", "ExternalEvent : " |
81 | + getName() + " Method: schedule(Entity who, TimeSpan dt)", |
82 | "The simulation time given as parameter is a null " |
83 | + "reference.", |
84 | "Be sure to have a valid TimeSpan reference before calling " |
85 | + "this method."); |
86 | return; // no proper parameter |
87 | } |
88 | |
89 | if (isScheduled()) { |
90 | sendWarning("Can't schedule external event! Command ignored.", |
91 | "ExternalEvent : " + getName() |
92 | + " Method: schedule(Entity wo, TimeSpan dt)", |
93 | "The external event to be scheduled is already scheduled.", |
94 | "Use external events only once, do not reuse them " |
95 | + "multiple times."); |
96 | return; // was already scheduled |
97 | } |
98 | |
99 | // generate trace |
100 | this.generateTraceForScheduling(null, null, null, null, null, TimeOperations.add(presentTime(), dt)); |
101 | |
102 | // schedule Event |
103 | getModel().getExperiment().getScheduler().schedule(null, this, dt); |
104 | |
105 | if (currentlySendDebugNotes()) { |
106 | sendDebugNote("schedules on EventList<br>" |
107 | + getModel().getExperiment().getScheduler().toString()); |
108 | } |
109 | } |
110 | |
111 | /** |
112 | * Schedules this external event to make the desired changes to the |
113 | * experiment or model at the specified point in simulation time. |
114 | * |
115 | * @param when |
116 | * TimeInstant : The point in simulation time this external event |
117 | * is scheduled to happen. |
118 | * @see SimClock |
119 | */ |
120 | public void schedule(TimeInstant when) { |
121 | if ((when == null)) { |
122 | sendWarning("Can't schedule external event!", "ExternalEvent : " |
123 | + getName() |
124 | + " Method: schedule(Entity who, TimeInstant when)", |
125 | "The point of simulation time given as parameter is a null " |
126 | + "reference.", |
127 | "Be sure to have a valid TimeInstant reference before calling " |
128 | + "this method."); |
129 | return; // no proper parameter |
130 | } |
131 | |
132 | if (isScheduled()) { |
133 | sendWarning("Can't schedule external event! Command ignored.", |
134 | "ExternalEvent : " + getName() |
135 | + " Method: schedule(Entity wo, TimeInstant when)", |
136 | "The external event to be scheduled is already scheduled.", |
137 | "Use external events only once, do not reuse them " |
138 | + "multiple times."); |
139 | return; // was already scheduled |
140 | } |
141 | |
142 | // generate trace |
143 | this.generateTraceForScheduling(null, null, null, null, null, when); |
144 | |
145 | // schedule Event |
146 | getModel().getExperiment().getScheduler().schedule(null, this, when); |
147 | |
148 | if (currentlySendDebugNotes()) { |
149 | sendDebugNote("schedules on EventList<br>" |
150 | + getModel().getExperiment().getScheduler().toString()); |
151 | } |
152 | } |
153 | |
154 | /** |
155 | * @deprecated Replaced by schedule(TimeSpan dt).Schedules this external |
156 | * Event to make the desired changes to the experiment or model |
157 | * at the specified point in simulation time. The point of time |
158 | * is given as an offset to the current simulation time as |
159 | * displayed by the simclock. |
160 | * |
161 | * @param dt |
162 | * SimTime : The offset to the current simulation time this event |
163 | * is to happen |
164 | * @see SimClock |
165 | */ |
166 | @Deprecated |
167 | public void schedule(SimTime dt) { |
168 | schedule(SimTime.toTimeSpan(dt)); |
169 | } |
170 | |
171 | /** |
172 | * Schedules this external event to act on the experiment or model state |
173 | * directly after the given Schedulable is already set to be activated. Note |
174 | * that this external event's point of simulation time will be set to be the |
175 | * same as the Schedulable's time. Thus this external event will occur |
176 | * directly after the given Schedulable but the simulation clock will not |
177 | * change. Make sure that the Schedulable given as parameter is actually |
178 | * scheduled. |
179 | * |
180 | * @param after |
181 | * Schedulable : The Schedulable this external event should be |
182 | * scheduled after |
183 | */ |
184 | public void scheduleAfter(Schedulable after) { |
185 | |
186 | if ((after == null)) { |
187 | sendWarning("Can't schedule external event! Command ignored.", |
188 | "ExternalEvent : " + getName() |
189 | + " Method: scheduleAfter(Schedulable after, " |
190 | + "Entity who)", |
191 | "The Schedulable given as parameter is a null reference.", |
192 | "Be sure to have a valid Schedulable reference for this " |
193 | + "external event to be scheduled with."); |
194 | return; // no proper parameter |
195 | } |
196 | |
197 | if (isScheduled()) { |
198 | sendWarning("Can't schedule external event! Command ignored.", |
199 | "ExternalEvent : " + getName() |
200 | + " Method: scheduleAfter(Schedulable after)", |
201 | "The external event to be scheduled is already scheduled.", |
202 | "Use method external events only once, do not use them " |
203 | + "multiple times."); |
204 | return; // was already scheduled |
205 | } |
206 | |
207 | if (!after.isScheduled()) { |
208 | sendWarning( |
209 | "Can't schedule external event! Command ignored.", |
210 | "ExternalEvent : " + getName() |
211 | + " Method: scheduleAfter(Schedulable after)", |
212 | "The Schedulable '" |
213 | + after.getName() |
214 | + "' given as a positioning " |
215 | + "reference has to be already scheduled but is not.", |
216 | "Use method isScheduled() of any Schedulable to find out " |
217 | + "if it is already scheduled."); |
218 | return; // was not scheduled |
219 | } |
220 | |
221 | // generate trace |
222 | this.generateTraceForScheduling(null, null, null, after, null, after.getEventNotes().get(after.getEventNotes().size()-1).getTime()); |
223 | |
224 | // schedule Event |
225 | getModel().getExperiment().getScheduler().scheduleAfter(after, null, |
226 | this); |
227 | |
228 | if (currentlySendDebugNotes()) { |
229 | sendDebugNote("scheduleAfter " + after.getQuotedName() |
230 | + " on EventList<br>" |
231 | + getModel().getExperiment().getScheduler().toString()); |
232 | } |
233 | |
234 | } |
235 | |
236 | /** |
237 | * Schedules this external event to act on the experiment or model state |
238 | * directly before the given Schedulable is already set to be activated. |
239 | * Note that this external event's point of simulation time will be set to |
240 | * be the same as the Schedulable's time. Thus this external event will |
241 | * occur directly before the given Schedulable but the simulation clock will |
242 | * not change. Make sure that the Schedulable given as parameter is actually |
243 | * scheduled. |
244 | * |
245 | * @param before |
246 | * Schedulable : The Schedulable this external event should be |
247 | * scheduled before |
248 | */ |
249 | public void scheduleBefore(Schedulable before) { |
250 | |
251 | if ((before == null)) { |
252 | sendWarning("Can't schedule external event! Command ignored.", |
253 | "ExternalEvent : " + getName() |
254 | + " Method: scheduleBefore(Schedulable before, " |
255 | + "Entity who)", |
256 | "The Schedulable given as parameter is a null reference.", |
257 | "Be sure to have a valid Schedulable reference for this " |
258 | + "external event to be scheduled with."); |
259 | return; // no proper parameter |
260 | } |
261 | |
262 | if (isScheduled()) { |
263 | sendWarning("Can't schedule external event! Command ignored.", |
264 | "ExternalEvent : " + getName() |
265 | + " Method: scheduleBefore(Schedulable before)", |
266 | "The external event to be scheduled is already scheduled.", |
267 | "Use method external events only once, do not use them " |
268 | + "multiple times."); |
269 | return; // was already scheduled |
270 | } |
271 | |
272 | if (!before.isScheduled()) { |
273 | sendWarning("Can't schedule external event! Command ignored.", |
274 | "ExternalEvent : " + getName() |
275 | + " Method: scheduleBefore(Schedulable before)", |
276 | "The Schedulable '" + before.getName() + "' given as a " |
277 | + "positioning reference has to be already " |
278 | + "scheduled but is not.", |
279 | "Use method isScheduled() of any Schedulable to find out " |
280 | + "if it is already scheduled."); |
281 | return; // was not scheduled |
282 | } |
283 | |
284 | // generate trace |
285 | this.generateTraceForScheduling(null, null, null, null, before, before.getEventNotes().get(0).getTime()); |
286 | |
287 | // schedule Event |
288 | getModel().getExperiment().getScheduler().scheduleBefore(before, null, |
289 | this); |
290 | |
291 | if (currentlySendDebugNotes()) { |
292 | sendDebugNote("scheduleBefore " + before.getQuotedName() |
293 | + " on EventList<br>" |
294 | + getModel().getExperiment().getScheduler().toString()); |
295 | } |
296 | |
297 | } |
298 | |
299 | /** |
300 | * Creates and returns a copy of this event. |
301 | * Note that subclasses have to implement the interface |
302 | * </code>java.lang.Cloneable</code> to actually use this method as |
303 | * otherwise, a </code>CloneNotSupportedException</code> will be thrown. |
304 | * |
305 | * @return ExternalEvent : A copy of this event. |
306 | */ |
307 | protected ExternalEvent clone() throws CloneNotSupportedException { |
308 | return (ExternalEvent) super.clone(); |
309 | } |
310 | } |