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