1 package org.sim0mq.message.federationmanager;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import org.djunits.value.vdouble.scalar.Duration;
7 import org.djunits.value.vdouble.scalar.Time;
8 import org.djunits.value.vfloat.scalar.FloatDuration;
9 import org.djunits.value.vfloat.scalar.FloatTime;
10 import org.djutils.exceptions.Throw;
11 import org.djutils.serialization.SerializationException;
12 import org.sim0mq.Sim0MQException;
13 import org.sim0mq.message.MessageStatus;
14 import org.sim0mq.message.Sim0MQMessage;
15 import org.sim0mq.message.SimulationMessage;
16 import org.sim0mq.message.types.NumberDuration;
17 import org.sim0mq.message.types.NumberTime;
18
19
20
21
22
23
24
25
26
27
28
29 public class SimRunControlMessage extends Sim0MQMessage
30 {
31
32
33
34
35 private final NumberDuration runTime;
36
37
38
39
40
41 private final NumberDuration warmupTime;
42
43
44
45
46
47 private final NumberTime offsetTime;
48
49
50 private final double speed;
51
52
53 private final int numberReplications;
54
55
56 private final int numberRandomStreams;
57
58
59 private final Map<Object, Long> streamMap = new HashMap<>();
60
61
62 private static final String MESSAGETYPE = "FM.2";
63
64
65 private static final long serialVersionUID = 20170424L;
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 @SuppressWarnings("checkstyle:parameternumber")
90 public SimRunControlMessage(final Object simulationRunId, final Object senderId, final Object receiverId,
91 final long messageId, final Object runTime, final Object warmupTime, final Object offsetTime, final double speed,
92 final int numberReplications, final int numberRandomStreams, final Map<Object, Long> streamMap)
93 throws Sim0MQException, NullPointerException
94 {
95 super(simulationRunId, senderId, receiverId, MESSAGETYPE, messageId, MessageStatus.NEW);
96 Throw.whenNull(runTime, "runTime cannot be null");
97 Throw.whenNull(warmupTime, "warmupTime cannot be null");
98 Throw.whenNull(offsetTime, "offsetTime cannot be null");
99 Throw.whenNull(streamMap, "streamMap cannot be null");
100
101 if (runTime instanceof Number)
102 {
103 this.runTime = new NumberDuration((Number) runTime);
104 }
105 else if (runTime instanceof Duration)
106 {
107 this.runTime = new NumberDuration((Duration) runTime);
108 }
109 else if (runTime instanceof FloatDuration)
110 {
111 this.runTime = new NumberDuration((FloatDuration) runTime);
112 }
113 else
114 {
115 throw new Sim0MQException("runTime should be Number, Duration or FloatDuration");
116 }
117
118 if (warmupTime instanceof Number)
119 {
120 this.warmupTime = new NumberDuration((Number) warmupTime);
121 }
122 else if (warmupTime instanceof Duration)
123 {
124 this.warmupTime = new NumberDuration((Duration) warmupTime);
125 }
126 else if (warmupTime instanceof FloatDuration)
127 {
128 this.warmupTime = new NumberDuration((FloatDuration) warmupTime);
129 }
130 else
131 {
132 throw new Sim0MQException("warmupTime should be Number, Duration or FloatDuration");
133 }
134
135 if (offsetTime instanceof Number)
136 {
137 this.offsetTime = new NumberTime((Number) offsetTime);
138 }
139 else if (offsetTime instanceof Time)
140 {
141 this.offsetTime = new NumberTime((Time) offsetTime);
142 }
143 else if (offsetTime instanceof FloatTime)
144 {
145 this.offsetTime = new NumberTime((FloatTime) offsetTime);
146 }
147 else
148 {
149 throw new Sim0MQException("offsetTime should be Number, Time or FloatTime");
150 }
151
152 this.speed = speed;
153
154 Throw.when(numberReplications <= 0, Sim0MQException.class, "numberReplications should be > 0");
155 this.numberReplications = numberReplications;
156
157 Throw.when(numberRandomStreams < 0, Sim0MQException.class, "numberRandomStreams should be >= 0");
158 Throw.when(numberRandomStreams != streamMap.size(), Sim0MQException.class,
159 "numberRandomStreams as given and in map are different");
160 this.numberRandomStreams = numberRandomStreams;
161 this.streamMap.putAll(streamMap);
162 }
163
164
165
166
167 public final NumberDuration getRunTime()
168 {
169 return this.runTime;
170 }
171
172
173
174
175 public final NumberDuration getWarmupTime()
176 {
177 return this.warmupTime;
178 }
179
180
181
182
183 public final NumberTime getOffsetTime()
184 {
185 return this.offsetTime;
186 }
187
188
189
190
191 public final double getSpeed()
192 {
193 return this.speed;
194 }
195
196
197
198
199 public final int getNumberReplications()
200 {
201 return this.numberReplications;
202 }
203
204
205
206
207 public final int getNumberRandomStreams()
208 {
209 return this.numberRandomStreams;
210 }
211
212
213
214
215 public final Map<Object, Long> getStreamMap()
216 {
217 return this.streamMap;
218 }
219
220
221
222
223 public static final String getMessageType()
224 {
225 return MESSAGETYPE;
226 }
227
228
229 @Override
230 public Object[] createObjectArray()
231 {
232 return new Object[] { getSimulationRunId(), getSenderId(), getReceiverId(), getMessageTypeId(), getMessageId(),
233 getMessageStatus(), this.runTime, this.warmupTime, this.offsetTime, this.speed, this.numberReplications,
234 this.numberRandomStreams, this.streamMap };
235 }
236
237
238 @Override
239 public byte[] createByteArray() throws Sim0MQException, SerializationException
240 {
241 return SimulationMessage.encodeUTF8(getSimulationRunId(), getSenderId(), getReceiverId(), getMessageTypeId(),
242 getMessageId(), getMessageStatus(), this.runTime, this.warmupTime, this.offsetTime, this.speed,
243 this.numberReplications, this.numberRandomStreams, this.streamMap);
244 }
245
246
247
248
249
250
251
252
253 public static SimRunControlMessage createMessage(final Object[] fields, final Object intendedReceiverId)
254 throws Sim0MQException
255 {
256 Map<Object, Long> streams = new HashMap<>();
257 int numberStreams = ((Integer) fields[13]).intValue();
258 check(fields, 6 + 2 * numberStreams, MESSAGETYPE, intendedReceiverId);
259 for (int i = 14; i < 14 + 2 * numberStreams; i += 2)
260 {
261 Object streamId = fields[i];
262 Long seed = ((Long) fields[i + 1]).longValue();
263 streams.put(streamId, seed);
264 }
265 return new SimRunControlMessage(fields[1], fields[2], fields[3], ((Long) fields[5]).longValue(), fields[8], fields[9],
266 fields[10], ((Double) fields[11]).doubleValue(), ((Integer) fields[12]).intValue(), numberStreams, streams);
267 }
268
269
270
271
272
273
274
275
276
277
278
279
280
281 public static class Builder extends Sim0MQMessage.Builder<SimRunControlMessage.Builder>
282 {
283
284
285
286
287 private NumberDuration runTime;
288
289
290
291
292
293 private NumberDuration warmupTime;
294
295
296
297
298
299 private NumberTime offsetTime;
300
301
302 private double speed;
303
304
305 private int numberReplications;
306
307
308 private Map<Object, Long> streamMap = new HashMap<>();
309
310
311
312
313 public Builder()
314 {
315
316 }
317
318
319
320
321
322 public final Builder setRunTime(final Number newRunTime)
323 {
324 this.runTime = new NumberDuration(newRunTime);
325 return this;
326 }
327
328
329
330
331
332 public final Builder setRunTime(final Duration newRunTime)
333 {
334 this.runTime = new NumberDuration(newRunTime);
335 return this;
336 }
337
338
339
340
341
342 public final Builder setRunTime(final FloatDuration newRunTime)
343 {
344 this.runTime = new NumberDuration(newRunTime);
345 return this;
346 }
347
348
349
350
351
352 public final Builder setWarmupTime(final Number newWarmupTime)
353 {
354 this.warmupTime = new NumberDuration(newWarmupTime);
355 return this;
356 }
357
358
359
360
361
362 public final Builder setWarmupTime(final Duration newWarmupTime)
363 {
364 this.warmupTime = new NumberDuration(newWarmupTime);
365 return this;
366 }
367
368
369
370
371
372 public final Builder setWarmupTime(final FloatDuration newWarmupTime)
373 {
374 this.warmupTime = new NumberDuration(newWarmupTime);
375 return this;
376 }
377
378
379
380
381
382 public final Builder setOffsetTime(final Number newOffsetTime)
383 {
384 this.offsetTime = new NumberTime(newOffsetTime);
385 return this;
386 }
387
388
389
390
391
392 public final Builder setOffsetTime(final Duration newOffsetTime)
393 {
394 this.offsetTime = new NumberTime(newOffsetTime);
395 return this;
396 }
397
398
399
400
401
402 public final Builder setOffsetTime(final FloatDuration newOffsetTime)
403 {
404 this.offsetTime = new NumberTime(newOffsetTime);
405 return this;
406 }
407
408
409
410
411
412 public final Builder setSpeed(final double newSpeed)
413 {
414 this.speed = newSpeed;
415 return this;
416 }
417
418
419
420
421
422 public final Builder setNumberReplications(final int newNumberReplications)
423 {
424 this.numberReplications = newNumberReplications;
425 return this;
426 }
427
428
429
430
431
432 public final Builder setStreamMap(final Map<Object, Long> newStreamMap)
433 {
434 this.streamMap = newStreamMap;
435 return this;
436 }
437
438
439 @Override
440 public Sim0MQMessage build() throws Sim0MQException, NullPointerException
441 {
442 return new SimRunControlMessage(this.simulationRunId, this.senderId, this.receiverId, this.messageId, this.runTime,
443 this.warmupTime, this.offsetTime, this.speed, this.numberReplications, this.streamMap.size(),
444 this.streamMap);
445 }
446
447 }
448 }