1#[macro_export]
16macro_rules! impl_struct_data {
17 ($name:ident = $value:expr $(, $from:literal => $to:literal)* $(,)?) => {
18 impl_name_by_member! { $name }
19 impl_default_by_value! { $name = $value }
20 impl_display_by_patched_debug! { $name $(, $from => $to)* }
21 };
22}
23
24#[doc(hidden)]
26#[macro_export]
27macro_rules! impl_name_by_member {
28 ($name:ident) => {
29 impl total_space::Name for $name {
30 fn name(&self) -> String {
31 let name: &'static str = std::convert::From::from(self.name);
32 name.to_string()
33 }
34 }
35 };
36}
37
38#[macro_export]
49macro_rules! impl_enum_data {
50 ($name:ident = $value:expr $(, $from:literal => $to:literal)* $(,)?) => {
51 impl_default_by_value! { $name = $value }
52 impl_name_for_into_static_str! { $name $(, $from => $to)* }
53 impl_display_by_patched_debug! { $name, "name=" => "" $(, $from => $to)* }
54 };
55}
56
57#[doc(hidden)]
59#[macro_export]
60macro_rules! impl_default_by_value {
61 ($name:ident = $value:expr) => {
62 impl Default for $name {
63 fn default() -> Self {
64 $value
65 }
66 }
67 };
68}
69
70#[doc(hidden)]
75#[macro_export]
76macro_rules! impl_name_for_into_static_str {
77 ($name:ident $(, $from:literal => $to:literal)* $(,)?) => {
78 impl total_space::Name for $name {
79 fn name(&self) -> String {
80 let static_str: &'static str = self.into();
81 let string = static_str.to_string();
82 $(
83 let string = string.replace($from, $to);
84 )*
85 string
86 }
87 }
88 };
89}
90
91#[doc(hidden)]
95#[macro_export]
96macro_rules! impl_display_by_patched_debug {
97 ($name:ident $(, $from:literal => $to:literal)* $(,)?) => {
98 impl Display for $name {
99 fn fmt(&self, formatter: &mut Formatter<'_>) -> FormatterResult {
100 let string = format!("{:?}", self)
101 .replace(" ", "")
102 .replace(":", "=")
103 .replace("{", "(")
104 .replace("}", ")");
105 $(
106 let string = string.replace($from, $to);
107 )*
108 write!(formatter, "{}", string)
109 }
110 }
111 };
112}
113
114#[macro_export]
122macro_rules! declare_agent_type_data {
123 ($name:ident, $agent:ident, $model:ident) => {
124 std::thread_local! {
125 static $name: std::cell::RefCell<
126 Option<
127 std::rc::Rc<
128 AgentTypeData::<
129 $agent,
130 <$model as MetaModel>::StateId,
131 <$model as MetaModel>::Payload,
132 >
133 >
134 >
135 > = std::cell::RefCell::new(None);
136 }
137 };
138}
139
140#[macro_export]
146macro_rules! init_agent_type_data {
147 ($name:ident, $agent_type:expr) => {
148 $name.with(|data| *data.borrow_mut() = Some($agent_type.clone()))
149 };
150}
151
152#[macro_export]
157macro_rules! declare_agent_indices {
158 ($name:ident) => {
159 thread_local! {
160 static $name: std::cell::RefCell<Vec<usize>> = std::cell::RefCell::new(Vec::new());
161 }
162 };
163}
164
165#[macro_export]
170macro_rules! declare_agent_index {
171 ($name:ident) => {
172 thread_local! {
173 static $name: std::cell::RefCell<usize> = std::cell::RefCell::new(usize::max_value());
174 }
175 };
176}
177
178#[macro_export]
184macro_rules! init_agent_indices {
185 ($name:ident, $agent_type:expr) => {{
186 assert!(!$agent_type.is_singleton());
187 $name.with(|refcell| {
188 let mut indices = refcell.borrow_mut();
189 indices.clear();
190 for instance in 0..$agent_type.instances_count() {
191 indices.push($agent_type.first_index() + instance);
192 }
193 });
194 }};
195}
196
197#[macro_export]
203macro_rules! init_agent_index {
204 ($name:ident, $agent_type:expr) => {
205 assert!($agent_type.is_singleton());
206 $name.with(|refcell| *refcell.borrow_mut() = $agent_type.first_index());
207 };
208}
209
210#[macro_export]
216macro_rules! agent_index {
217 ($name:ident) => {{
218 $name.with(|refcell| *refcell.borrow())
219 }};
220 ($name:ident[$index:expr]) => {
221 $name.with(|refcell| refcell.borrow()[$index])
222 };
223}
224
225#[macro_export]
231macro_rules! agents_count {
232 ($name:ident) => {
233 $name.with(|refcell| refcell.borrow().len())
234 };
235}
236
237#[macro_export]
242macro_rules! activity_alternatives {
243 ($payload1:expr, $payload2:expr $(,)?) => {
244 total_space::Activity::Process1Of([
245 Some($payload1),
246 Some($payload2),
247 None,
248 None,
249 None,
250 None,
251 ])
252 };
253 ($payload1:expr, $payload2:expr $(,)?) => {
254 total_space::Activity::Process1Of([
255 Some($payload1),
256 Some($payload2),
257 None,
258 None,
259 None,
260 None,
261 ])
262 };
263 ($payload1:expr, $payload2:expr, $payload3:expr $(,)?) => {
264 total_space::Activity::Process1Of([
265 Some($payload1),
266 Some($payload2),
267 Some($payload3),
268 None,
269 None,
270 None,
271 ])
272 };
273 ($payload1:expr, $payload2:expr, $payload3:expr, $payload4:expr $(,)?) => {
274 total_space::Activity::Process1Of([
275 Some($payload1),
276 Some($payload2),
277 Some($payload3),
278 Some($payload4),
279 None,
280 None,
281 ])
282 };
283 ($payload1:expr, $payload2:expr, $payload3:expr, $payload4:expr, $payload5:expr $(,)?) => {
284 total_space::Activity::Process1Of([
285 Some($payload1),
286 Some($payload2),
287 Some($payload3),
288 Some($payload4),
289 Some($payload5),
290 None,
291 ])
292 };
293 ($payload1:expr, $payload2:expr, $payload3:expr, $payload4:expr, $payload5:expr, $payload6:expr $(,)?) => {
294 total_space::Activity::Process1Of([
295 Some($payload1),
296 Some($payload2),
297 Some($payload3),
298 Some($payload4),
299 Some($payload5),
300 Some($payload6),
301 ])
302 };
303 ($_:tt) => {
304 compile_error!("expected 2 to 6 payloads");
305 };
306}
307
308#[macro_export]
313macro_rules! reaction_alternatives {
314 ($action1:expr, $action2:expr $(,)?) => {
315 total_space::Reaction::Do1Of([Some(action1), Some(action2), None, None, None, None])
316 };
317 ($action1:expr, $action2:expr, $action3:expr $(,)?) => {
318 total_space::Reaction::Do1Of([
319 Some(action1),
320 Some(action2),
321 Some(action3),
322 None,
323 None,
324 None,
325 ])
326 };
327 ($action1:expr, $action2:expr, $action3:expr, $action4:expr $(,)?) => {
328 total_space::Reaction::Do1Of([
329 Some(action1),
330 Some(action2),
331 Some(action3),
332 Some(action4),
333 None,
334 None,
335 ])
336 };
337 ($action1:expr, $action2:expr, $action3:expr, $action4:expr, $action5:expr $(,)?) => {
338 total_space::Reaction::Do1Of([
339 Some(action1),
340 Some(action2),
341 Some(action3),
342 Some(action4),
343 Some(action5),
344 None,
345 ])
346 };
347 ($action1:expr, $action2:expr, $action3:expr, $action4:expr, $action5:expr, $action6:expr $(,)?) => {
348 total_space::Reaction::Do1Of([
349 Some(action1),
350 Some(action2),
351 Some(action3),
352 Some(action4),
353 Some(action5),
354 Some(action6),
355 ])
356 };
357 ($_:tt) => {
358 compile_error!("expected 2 to 6 actions");
359 };
360}
361
362#[macro_export]
366macro_rules! action_sends {
367 ($emit1:expr, $emit2:expr $(,)?) => {
368 total_space::Action::Sends([Some($emit1), Some($emit2), None, None, None, None])
369 };
370 ($emit1:expr, $emit2:expr, $emit3:expr $(,)?) => {
371 total_space::Action::Sends([Some($emit1), Some($emit2), Some($emit3), None, None, None])
372 };
373 ($emit1:expr, $emit2:expr, $emit3:expr, $emit4:expr $(,)?) => {
374 total_space::Action::Sends([
375 Some($emit1),
376 Some($emit2),
377 Some($emit3),
378 Some($emit4),
379 None,
380 None,
381 ])
382 };
383 ($emit1:expr, $emit2:expr, $emit3:expr, $emit4:expr, $emit5:expr $(,)?) => {
384 total_space::Action::Sends([
385 Some($emit1),
386 Some($emit2),
387 Some($emit3),
388 Some($emit4),
389 Some($emit5),
390 None,
391 ])
392 };
393 ($emit1:expr, $emit2:expr, $emit3:expr, $emit4:expr, $emit5:expr, $emit6:expr $(,)?) => {
394 total_space::Action::Sends([
395 Some($emit1),
396 Some($emit2),
397 Some($emit3),
398 Some($emit4),
399 Some($emit5),
400 Some($emit6),
401 ])
402 };
403 ($_:tt) => {
404 compile_error!("expected 2 to 6 emits");
405 };
406}
407
408#[macro_export]
413macro_rules! action_change_and_sends {
414 ($state:expr, $emit1:expr, $emit2:expr $(,)?) => {
415 total_space::Action::ChangeAndSends(
416 $state,
417 [Some($emit1), Some($emit2), None, None, None, None],
418 )
419 };
420 ($state:expr, $emit1:expr, $emit2:expr, $emit3:expr $(,)?) => {
421 total_space::Action::ChangeAndSends(
422 $state,
423 [Some($emit1), Some($emit2), Some($emit3), None, None, None],
424 )
425 };
426 ($state:expr, $emit1:expr, $emit2:expr, $emit3:expr, $emit4:expr $(,)?) => {
427 total_space::Action::ChangeAndSends(
428 $state,
429 [
430 Some($emit1),
431 Some($emit2),
432 Some($emit3),
433 Some($emit4),
434 None,
435 None,
436 ],
437 )
438 };
439 ($state:expr, $emit1:expr, $emit2:expr, $emit3:expr, $emit4:expr, $emit5:expr $(,)?) => {
440 total_space::Action::ChangeAndSends(
441 $state,
442 [
443 Some($emit1),
444 Some($emit2),
445 Some($emit3),
446 Some($emit4),
447 Some($emit5),
448 None,
449 ],
450 )
451 };
452 ($state:expr, $emit1:expr, $emit2:expr, $emit3:expr, $emit4:expr, $emit5:expr, $emit6:expr $(,)?) => {
453 total_space::Action::ChangeAndSends(
454 $state,
455 [
456 Some($emit1),
457 Some($emit2),
458 Some($emit3),
459 Some($emit4),
460 Some($emit5),
461 Some($emit6),
462 ],
463 )
464 };
465 ($_:tt) => {
466 compile_error!("expected state and 2 to 6 emits");
467 };
468}
469
470#[macro_export]
475macro_rules! assert_configuration_hash_entry_size {
476 ($model:ident, $size:literal) => {
477 const _: usize = 0
478 - (std::mem::size_of::<<$model as MetaModel>::ConfigurationHashEntry>() != $size)
479 as usize;
480 };
481}
482
483#[macro_export]
490macro_rules! agent_states_iter {
491 ($configuration:expr, $name:ident, $($iter:tt)*) => {
492 $name.with(|refcell| {
493 if let Some(agent_type) = refcell.borrow().as_ref() {
494 (0..agent_type.instances_count())
495 .map(|agent_instance| {
496 let agent_index = agent_type.first_index() + agent_instance;
497 let state_id = $configuration.state_ids[agent_index];
498 agent_type.get_state(state_id)
499 })
500 .$($iter)*
501 } else {
502 unreachable!()
503 }
504 })
505 };
506}
507
508#[macro_export]
514macro_rules! messages_iter {
515 ($model:expr, $configuration:expr, $($iter:tt)*) => {
516 $configuration
517 .message_ids
518 .iter()
519 .take_while(|message_id| message_id.is_valid())
520 .map(|message_id| $model.get_message(*message_id))
521 .$($iter)*
522 };
523}