1use crate::memoize::*;
2use crate::reactions::*;
3use crate::utilities::*;
4
5use std::cell::RefCell;
6use std::marker::PhantomData;
7use std::rc::Rc;
8
9pub enum Instances {
11 Singleton,
13
14 Count(usize),
16}
17
18pub trait AgentInstances<StateId: IndexLike, Payload: DataLike>: Name {
20 fn prev_agent_type(&self) -> Option<Rc<dyn AgentType<StateId, Payload>>>;
22
23 fn first_index(&self) -> usize;
25
26 fn next_index(&self) -> usize;
28
29 fn is_singleton(&self) -> bool;
33
34 fn instances_count(&self) -> usize;
36
37 fn instance_order(&self, instance: usize) -> usize;
39
40 fn display_state(&self, state_id: StateId) -> Rc<String>;
47
48 fn terse_id(&self, state_id: StateId) -> StateId;
50
51 fn display_terse(&self, name_id: StateId) -> String;
53}
54
55pub trait AgentType<StateId: IndexLike, Payload: DataLike>:
57 AgentInstances<StateId, Payload>
58{
59 fn reaction(
62 &self,
63 instance: usize,
64 state_ids: &[StateId],
65 payload: &Payload,
66 ) -> Reaction<StateId, Payload>;
67
68 fn activity(&self, instance: usize, state_ids: &[StateId]) -> Activity<Payload>;
70
71 fn state_is_deferring(&self, instance: usize, state_ids: &[StateId]) -> bool;
73
74 fn state_invalid_because(&self, instance: usize, state_ids: &[StateId])
76 -> Option<&'static str>;
77
78 fn state_max_in_flight_messages(&self, instance: usize, state_ids: &[StateId])
81 -> Option<usize>;
82
83 fn states_count(&self) -> usize;
85
86 fn compute_terse(&self);
88}
89
90pub trait PartType<State: DataLike, StateId: IndexLike> {
92 fn part_state_by_id(&self, state_id: StateId) -> State;
94
95 fn part_first_index(&self) -> usize;
97
98 fn parts_count(&self) -> usize;
100}
101
102pub struct AgentTypeData<State: DataLike, StateId: IndexLike, Payload: DataLike> {
108 states: RefCell<Memoize<State, StateId>>,
110
111 first_index: usize,
113
114 name: &'static str,
116
117 is_singleton: bool,
119
120 label_of_state: RefCell<Vec<Rc<String>>>,
122
123 terse_of_state: RefCell<Vec<StateId>>,
125
126 name_of_terse: RefCell<Vec<String>>,
128
129 order_of_instances: Vec<usize>,
131
132 prev_agent_type: Option<Rc<dyn AgentType<StateId, Payload>>>,
134
135 _payload: PhantomData<Payload>,
137}
138
139pub struct ContainerOf1TypeData<
143 State: DataLike,
144 Part: DataLike,
145 StateId: IndexLike,
146 Payload: DataLike,
147 const MAX_PARTS: usize,
148> {
149 agent_type_data: AgentTypeData<State, StateId, Payload>,
151
152 part_type: Rc<dyn PartType<Part, StateId>>,
154}
155
156pub struct ContainerOf2TypeData<
160 State: DataLike,
161 Part1: DataLike,
162 Part2: DataLike,
163 StateId: IndexLike,
164 Payload: DataLike,
165 const MAX_PARTS: usize,
166> {
167 agent_type_data: AgentTypeData<State, StateId, Payload>,
169
170 part1_type: Rc<dyn PartType<Part1, StateId>>,
172
173 part2_type: Rc<dyn PartType<Part2, StateId>>,
175}
176
177impl<State: DataLike, StateId: IndexLike, Payload: DataLike>
180 AgentTypeData<State, StateId, Payload>
181{
182 pub fn new(
184 name: &'static str,
185 instances: Instances,
186 prev_agent_type: Option<Rc<dyn AgentType<StateId, Payload>>>,
187 ) -> Self {
188 let (is_singleton, count) = match instances {
189 Instances::Singleton => (true, 1),
190 Instances::Count(amount) => {
191 assert!(
192 amount > 0,
193 "zero instances specified for agent type {}",
194 name
195 );
196 (false, amount)
197 }
198 };
199
200 let default_state: State = Default::default();
201 let mut states = Memoize::new(StateId::invalid().to_usize());
202 states.store(default_state);
203 let label_of_state = RefCell::new(vec![]);
204 label_of_state
205 .borrow_mut()
206 .push(Rc::new(format!("{}", default_state)));
207
208 let order_of_instances = vec![0; count];
209
210 Self {
211 name,
212 order_of_instances,
213 is_singleton,
214 label_of_state,
215 terse_of_state: RefCell::new(vec![]),
216 name_of_terse: RefCell::new(vec![]),
217 states: RefCell::new(states),
218 first_index: prev_agent_type
219 .clone()
220 .map_or(0, |agent_type| agent_type.next_index()),
221 prev_agent_type,
222 _payload: PhantomData,
223 }
224 }
225
226 pub fn set_order(&mut self, instance: usize, order: usize) {
230 assert!(
231 instance < self.instances_count(),
232 "instance: {} count: {}",
233 instance,
234 self.instances_count()
235 );
236 self.order_of_instances[instance] = order;
237 }
238
239 fn impl_compute_terse(&self) {
243 let mut terse_of_state = self.terse_of_state.borrow_mut();
244 let mut name_of_terse = self.name_of_terse.borrow_mut();
245
246 assert!(terse_of_state.is_empty());
247 assert!(name_of_terse.is_empty());
248
249 let states = self.states.borrow();
250 terse_of_state.reserve(states.len());
251 name_of_terse.reserve(states.len());
252
253 for state_id in 0..states.len() {
254 let state = states.get(StateId::from_usize(state_id));
255 let state_name = state.name();
256 if let Some(terse_id) = name_of_terse
257 .iter()
258 .position(|terse_name| terse_name == &state_name)
259 {
260 terse_of_state.push(StateId::from_usize(terse_id));
261 } else {
262 terse_of_state.push(StateId::from_usize(name_of_terse.len()));
263 name_of_terse.push(state_name);
264 }
265 }
266
267 name_of_terse.shrink_to_fit();
268 }
269
270 pub fn get_state(&self, state_id: StateId) -> State {
272 self.states.borrow().get(state_id)
273 }
274}
275
276impl<
277 State: DataLike,
278 Part: DataLike,
279 StateId: IndexLike,
280 Payload: DataLike,
281 const MAX_PARTS: usize,
282 > ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
283{
284 pub fn new(
286 name: &'static str,
287 instances: Instances,
288 part_type: Rc<dyn PartType<Part, StateId>>,
289 prev_type: Rc<dyn AgentType<StateId, Payload>>,
290 ) -> Self {
291 Self {
292 agent_type_data: AgentTypeData::new(name, instances, Some(prev_type)),
293 part_type,
294 }
295 }
296}
297
298impl<
300 State: DataLike,
301 Part1: DataLike,
302 Part2: DataLike,
303 StateId: IndexLike,
304 Payload: DataLike,
305 const MAX_PARTS: usize,
306 > ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
307{
308 pub fn new(
310 name: &'static str,
311 instances: Instances,
312 part1_type: Rc<dyn PartType<Part1, StateId>>,
313 part2_type: Rc<dyn PartType<Part2, StateId>>,
314 prev_type: Rc<dyn AgentType<StateId, Payload>>,
315 ) -> Self {
316 Self {
317 agent_type_data: AgentTypeData::new(name, instances, Some(prev_type)),
318 part1_type,
319 part2_type,
320 }
321 }
322}
323impl<State: DataLike, StateId: IndexLike, Payload: DataLike> PartType<State, StateId>
326 for AgentTypeData<State, StateId, Payload>
327{
328 fn part_state_by_id(&self, state_id: StateId) -> State {
329 self.states.borrow().get(state_id)
330 }
331
332 fn part_first_index(&self) -> usize {
333 self.first_index
334 }
335
336 fn parts_count(&self) -> usize {
337 self.instances_count()
338 }
339}
340
341pub trait AgentState<State: DataLike, Payload: DataLike> {
343 fn reaction(&self, instance: usize, payload: &Payload) -> Reaction<State, Payload>;
346
347 fn activity(&self, _instance: usize) -> Activity<Payload> {
349 Activity::Passive
350 }
351
352 fn is_deferring(&self, _instance: usize) -> bool {
354 false
355 }
356
357 fn invalid_because(&self, _instance: usize) -> Option<&'static str> {
359 None
360 }
361
362 fn max_in_flight_messages(&self, _instance: usize) -> Option<usize> {
365 None
366 }
367}
368
369pub trait ContainerOf1State<State: DataLike, Part: DataLike, Payload: DataLike> {
371 fn reaction(
374 &self,
375 instance: usize,
376 payload: &Payload,
377 parts: &[Part],
378 ) -> Reaction<State, Payload>;
379
380 fn activity(&self, _instance: usize, _parts: &[Part]) -> Activity<Payload> {
382 Activity::Passive
383 }
384
385 fn is_deferring(&self, _instance: usize, _parts: &[Part]) -> bool {
387 false
388 }
389
390 fn invalid_because(&self, _instance: usize, _parts: &[Part]) -> Option<&'static str> {
394 None
395 }
396
397 fn max_in_flight_messages(&self, _instance: usize, _parts: &[Part]) -> Option<usize> {
402 None
403 }
404}
405
406pub trait ContainerOf2State<State: DataLike, Part1: DataLike, Part2: DataLike, Payload: DataLike> {
410 fn reaction(
413 &self,
414 instance: usize,
415 payload: &Payload,
416 parts1: &[Part1],
417 parts2: &[Part2],
418 ) -> Reaction<State, Payload>;
419
420 fn activity(
422 &self,
423 _instance: usize,
424 _parts1: &[Part1],
425 _parts2: &[Part2],
426 ) -> Activity<Payload> {
427 Activity::Passive
428 }
429
430 fn is_deferring(&self, _instance: usize, _parts1: &[Part1], _parts2: &[Part2]) -> bool {
432 false
433 }
434
435 fn invalid_because(
437 &self,
438 _instance: usize,
439 _parts1: &[Part1],
440 _parts2: &[Part2],
441 ) -> Option<&'static str> {
442 None
443 }
444
445 fn max_in_flight_messages(
448 &self,
449 _instance: usize,
450 _parts1: &[Part1],
451 _parts2: &[Part2],
452 ) -> Option<usize> {
453 None
454 }
455}
456
457impl<State: DataLike, StateId: IndexLike, Payload: DataLike>
460 AgentTypeData<State, StateId, Payload>
461{
462 fn translate_reaction(
463 &self,
464 reaction: &Reaction<State, Payload>,
465 ) -> Reaction<StateId, Payload> {
466 match reaction {
467 Reaction::Unexpected => Reaction::Unexpected,
468 Reaction::Ignore => Reaction::Ignore,
469 Reaction::Defer => Reaction::Defer,
470 Reaction::Do1(action) => Reaction::Do1(self.translate_action(action)),
471 Reaction::Do1Of(actions) => Reaction::Do1Of(self.translate_actions(&actions)), }
473 }
474
475 fn translate_action(&self, action: &Action<State, Payload>) -> Action<StateId, Payload> {
476 match *action {
477 Action::Defer => Action::Defer,
478
479 Action::Ignore => Action::Ignore, Action::Change(state) => Action::Change(self.translate_state(state)),
481
482 Action::Send1(emit) => Action::Send1(emit),
483 Action::ChangeAndSend1(state, emit) => {
484 Action::ChangeAndSend1(self.translate_state(state), emit)
485 }
486
487 Action::Sends(emits) => Action::Sends(emits), Action::ChangeAndSends(state, emits) => {
489 Action::ChangeAndSends(self.translate_state(state), emits)
490 }
491 }
492 }
493
494 fn translate_actions(
497 &self,
498 actions: &[Option<Action<State, Payload>>; MAX_COUNT],
499 ) -> [Option<Action<StateId, Payload>>; MAX_COUNT] {
500 let mut translated_actions: [Option<Action<StateId, Payload>>; MAX_COUNT] =
501 [None; MAX_COUNT];
502 for (maybe_action, maybe_translated) in actions.iter().zip(translated_actions.iter_mut()) {
503 *maybe_translated = maybe_action
504 .as_ref()
505 .map(|action| self.translate_action(action));
506 }
507 translated_actions
508 }
509
510 fn translate_state(&self, state: State) -> StateId {
513 let stored = self.states.borrow_mut().store(state);
514 if stored.is_new {
515 debug_assert!(self.label_of_state.borrow().len() == stored.id.to_usize());
516 self.label_of_state
517 .borrow_mut()
518 .push(Rc::new(format!("{}", state)));
519 }
520 stored.id
521 }
522}
523
524impl<State: DataLike, StateId: IndexLike, Payload: DataLike> Name
525 for AgentTypeData<State, StateId, Payload>
526{
527 fn name(&self) -> String {
528 self.name.to_string()
529 }
530}
531
532impl<
533 State: DataLike,
534 Part: DataLike,
535 StateId: IndexLike,
536 Payload: DataLike,
537 const MAX_PARTS: usize,
538 > Name for ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
539{
540 fn name(&self) -> String {
541 self.agent_type_data.name()
542 }
543}
544
545impl<
547 State: DataLike,
548 Part1: DataLike,
549 Part2: DataLike,
550 StateId: IndexLike,
551 Payload: DataLike,
552 const MAX_PARTS: usize,
553 > Name for ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
554{
555 fn name(&self) -> String {
556 self.agent_type_data.name()
557 }
558}
559impl<State: DataLike, StateId: IndexLike, Payload: DataLike> AgentInstances<StateId, Payload>
562 for AgentTypeData<State, StateId, Payload>
563{
564 fn prev_agent_type(&self) -> Option<Rc<dyn AgentType<StateId, Payload>>> {
565 self.prev_agent_type.clone()
566 }
567
568 fn first_index(&self) -> usize {
569 self.first_index
570 }
571
572 fn next_index(&self) -> usize {
573 self.first_index + self.instances_count()
574 }
575
576 fn is_singleton(&self) -> bool {
577 self.is_singleton
578 }
579
580 fn instances_count(&self) -> usize {
581 self.order_of_instances.len()
582 }
583
584 fn instance_order(&self, instance: usize) -> usize {
585 self.order_of_instances[instance]
586 }
587
588 fn display_state(&self, state_id: StateId) -> Rc<String> {
589 self.label_of_state.borrow()[state_id.to_usize()].clone()
590 }
591
592 fn terse_id(&self, state_id: StateId) -> StateId {
593 self.terse_of_state.borrow()[state_id.to_usize()]
594 }
595
596 fn display_terse(&self, terse_id: StateId) -> String {
597 self.name_of_terse.borrow()[terse_id.to_usize()].clone()
598 }
599}
600
601impl<
602 State: DataLike + ContainerOf1State<State, Part, Payload>,
603 Part: DataLike + AgentState<Part, Payload>,
604 StateId: IndexLike,
605 Payload: DataLike,
606 const MAX_PARTS: usize,
607 > AgentInstances<StateId, Payload>
608 for ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
609{
610 fn prev_agent_type(&self) -> Option<Rc<dyn AgentType<StateId, Payload>>> {
611 self.agent_type_data.prev_agent_type.clone()
612 }
613
614 fn first_index(&self) -> usize {
615 self.agent_type_data.first_index()
616 }
617
618 fn next_index(&self) -> usize {
619 self.agent_type_data.next_index()
620 }
621
622 fn is_singleton(&self) -> bool {
623 self.agent_type_data.is_singleton()
624 }
625
626 fn instances_count(&self) -> usize {
627 self.agent_type_data.instances_count()
628 }
629
630 fn instance_order(&self, instance: usize) -> usize {
631 self.agent_type_data.instance_order(instance)
632 }
633
634 fn display_state(&self, state_id: StateId) -> Rc<String> {
635 self.agent_type_data.display_state(state_id)
636 }
637
638 fn terse_id(&self, state_id: StateId) -> StateId {
640 self.agent_type_data.terse_id(state_id)
641 }
642
643 fn display_terse(&self, terse_id: StateId) -> String {
644 self.agent_type_data.display_terse(terse_id)
645 }
646 }
648
649impl<
651 State: DataLike + ContainerOf2State<State, Part1, Part2, Payload>,
652 Part1: DataLike + AgentState<Part1, Payload>,
653 Part2: DataLike + AgentState<Part2, Payload>,
654 StateId: IndexLike,
655 Payload: DataLike,
656 const MAX_PARTS: usize,
657 > AgentInstances<StateId, Payload>
658 for ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
659{
660 fn prev_agent_type(&self) -> Option<Rc<dyn AgentType<StateId, Payload>>> {
661 self.agent_type_data.prev_agent_type.clone()
662 }
663
664 fn first_index(&self) -> usize {
665 self.agent_type_data.first_index()
666 }
667
668 fn next_index(&self) -> usize {
669 self.agent_type_data.next_index()
670 }
671
672 fn is_singleton(&self) -> bool {
673 self.agent_type_data.is_singleton()
674 }
675
676 fn instances_count(&self) -> usize {
677 self.agent_type_data.instances_count()
678 }
679
680 fn instance_order(&self, instance: usize) -> usize {
681 self.agent_type_data.instance_order(instance)
682 }
683
684 fn display_state(&self, state_id: StateId) -> Rc<String> {
685 self.agent_type_data.display_state(state_id)
686 }
687
688 fn terse_id(&self, state_id: StateId) -> StateId {
689 self.agent_type_data.terse_id(state_id)
690 }
691
692 fn display_terse(&self, terse_id: StateId) -> String {
693 self.agent_type_data.display_terse(terse_id)
694 }
695}
696impl<State: DataLike + AgentState<State, Payload>, StateId: IndexLike, Payload: DataLike>
699 AgentType<StateId, Payload> for AgentTypeData<State, StateId, Payload>
700{
701 fn reaction(
702 &self,
703 instance: usize,
704 state_ids: &[StateId],
705 payload: &Payload,
706 ) -> Reaction<StateId, Payload> {
707 debug_assert!(
708 instance < self.instances_count(),
709 "instance: {} count: {}",
710 instance,
711 self.instances_count() );
713 let state = self
714 .states
715 .borrow()
716 .get(state_ids[self.first_index + instance]);
717 let reaction = state.reaction(instance, payload);
718 self.translate_reaction(&reaction)
719 }
720
721 fn activity(&self, instance: usize, state_ids: &[StateId]) -> Activity<Payload> {
722 debug_assert!(
723 instance < self.instances_count(),
724 "instance: {} count: {}",
725 instance,
726 self.instances_count() );
728 self.states
729 .borrow()
730 .get(state_ids[self.first_index + instance])
731 .activity(instance)
732 }
733
734 fn state_is_deferring(&self, instance: usize, state_ids: &[StateId]) -> bool {
735 debug_assert!(
736 instance < self.instances_count(),
737 "instance: {} count: {}",
738 instance,
739 self.instances_count() );
741 self.states
742 .borrow()
743 .get(state_ids[self.first_index + instance])
744 .is_deferring(instance)
745 }
746
747 fn state_invalid_because(
748 &self,
749 instance: usize,
750 state_ids: &[StateId],
751 ) -> Option<&'static str> {
752 debug_assert!(
753 instance < self.instances_count(),
754 "instance: {} count: {}",
755 instance,
756 self.instances_count() );
758 self.states
759 .borrow()
760 .get(state_ids[self.first_index + instance])
761 .invalid_because(instance)
762 }
763
764 fn state_max_in_flight_messages(
765 &self,
766 instance: usize,
767 state_ids: &[StateId],
768 ) -> Option<usize> {
769 debug_assert!(
770 instance < self.instances_count(),
771 "instance: {} count: {}",
772 instance,
773 self.instances_count() );
775 self.states
776 .borrow()
777 .get(state_ids[self.first_index + instance])
778 .max_in_flight_messages(instance)
779 }
780
781 fn states_count(&self) -> usize {
782 self.states.borrow().len()
783 }
784
785 fn compute_terse(&self) {
786 self.impl_compute_terse();
787 }
788}
789
790impl<
791 State: DataLike + ContainerOf1State<State, Part, Payload>,
792 Part: DataLike + AgentState<Part, Payload>,
793 StateId: IndexLike,
794 Payload: DataLike,
795 const MAX_PARTS: usize,
796 > ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
797{
798 fn collect_parts(&self, state_ids: &[StateId]) -> [Part; MAX_PARTS] {
799 let mut parts = [Part::default(); MAX_PARTS];
800 let part_first_index = self.part_type.part_first_index();
801 (0..self.part_type.parts_count()).for_each(|part_instance| {
802 let state_id = state_ids[part_first_index + part_instance];
803 parts[part_instance] = self.part_type.part_state_by_id(state_id);
804 });
805
806 parts
807 }
808
809 pub fn set_order(&mut self, instance: usize, order: usize) {
813 self.agent_type_data.set_order(instance, order);
814 }
815
816 }
818
819impl<
821 State: DataLike + ContainerOf2State<State, Part1, Part2, Payload>,
822 Part1: DataLike + AgentState<Part1, Payload>,
823 Part2: DataLike + AgentState<Part2, Payload>,
824 StateId: IndexLike,
825 Payload: DataLike,
826 const MAX_PARTS: usize,
827 > ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
828{
829 fn collect_parts(&self, state_ids: &[StateId]) -> ([Part1; MAX_PARTS], [Part2; MAX_PARTS]) {
830 let mut parts1 = [Part1::default(); MAX_PARTS];
831 let part1_first_index = self.part1_type.part_first_index();
832 (0..self.part1_type.parts_count()).for_each(|part1_instance| {
833 let state_id = state_ids[part1_first_index + part1_instance];
834 parts1[part1_instance] = self.part1_type.part_state_by_id(state_id);
835 });
836
837 let mut parts2 = [Part2::default(); MAX_PARTS];
838 let part2_first_index = self.part2_type.part_first_index();
839 (0..self.part2_type.parts_count()).for_each(|part2_instance| {
840 let state_id = state_ids[part2_first_index + part2_instance];
841 parts2[part2_instance] = self.part2_type.part_state_by_id(state_id);
842 });
843
844 (parts1, parts2)
845 }
846
847 pub fn set_order(&mut self, instance: usize, order: usize) {
849 self.agent_type_data.set_order(instance, order);
850 }
851}
852impl<
855 State: DataLike + ContainerOf1State<State, Part, Payload>,
856 Part: DataLike + AgentState<Part, Payload>,
857 StateId: IndexLike,
858 Payload: DataLike,
859 const MAX_PARTS: usize,
860 > AgentType<StateId, Payload>
861 for ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
862{
863 fn reaction(
864 &self,
865 instance: usize,
866 state_ids: &[StateId],
867 payload: &Payload,
868 ) -> Reaction<StateId, Payload> {
869 debug_assert!(
870 instance < self.instances_count(),
871 "instance: {} count: {}",
872 instance,
873 self.instances_count() );
875
876 let all_parts = self.collect_parts(state_ids);
877 let parts = &all_parts[..self.part_type.parts_count()];
878
879 let reaction = self
880 .agent_type_data
881 .states
882 .borrow()
883 .get(state_ids[self.agent_type_data.first_index + instance])
884 .reaction(instance, payload, parts);
885 self.agent_type_data.translate_reaction(&reaction)
886 }
887
888 fn activity(&self, instance: usize, state_ids: &[StateId]) -> Activity<Payload> {
889 debug_assert!(
890 instance < self.instances_count(),
891 "instance: {} count: {}",
892 instance,
893 self.instances_count() );
895
896 let all_parts = self.collect_parts(state_ids);
897 let parts = &all_parts[..self.part_type.parts_count()];
898
899 self.agent_type_data
900 .states
901 .borrow()
902 .get(state_ids[self.agent_type_data.first_index + instance])
903 .activity(instance, parts)
904 }
905
906 fn state_is_deferring(&self, instance: usize, state_ids: &[StateId]) -> bool {
907 debug_assert!(
908 instance < self.instances_count(),
909 "instance: {} count: {}",
910 instance,
911 self.instances_count() );
913
914 let all_parts = self.collect_parts(state_ids);
915 let parts = &all_parts[..self.part_type.parts_count()];
916
917 self.agent_type_data
918 .states
919 .borrow()
920 .get(state_ids[self.agent_type_data.first_index + instance])
921 .is_deferring(instance, parts)
922 }
923
924 fn state_invalid_because(
926 &self,
927 instance: usize,
928 state_ids: &[StateId],
929 ) -> Option<&'static str> {
930 debug_assert!(
931 instance < self.instances_count(),
932 "instance: {} count: {}",
933 instance,
934 self.instances_count()
935 );
936
937 let all_parts = self.collect_parts(state_ids);
938 let parts = &all_parts[..self.part_type.parts_count()];
939
940 self.agent_type_data
941 .states
942 .borrow()
943 .get(state_ids[self.agent_type_data.first_index + instance])
944 .invalid_because(instance, parts)
945 }
946 fn state_max_in_flight_messages(
949 &self,
950 instance: usize,
951 state_ids: &[StateId],
952 ) -> Option<usize> {
953 debug_assert!(
954 instance < self.instances_count(),
955 "instance: {} count: {}",
956 instance,
957 self.instances_count() );
959
960 let all_parts = self.collect_parts(state_ids);
961 let parts = &all_parts[..self.part_type.parts_count()];
962
963 self.agent_type_data
964 .states
965 .borrow()
966 .get(state_ids[self.agent_type_data.first_index + instance])
967 .max_in_flight_messages(instance, parts)
968 }
969
970 fn states_count(&self) -> usize {
972 self.agent_type_data.states.borrow().len()
973 }
974 fn compute_terse(&self) {
977 self.agent_type_data.impl_compute_terse();
978 }
979}
980
981impl<
983 State: DataLike + ContainerOf2State<State, Part1, Part2, Payload>,
984 Part1: DataLike + AgentState<Part1, Payload>,
985 Part2: DataLike + AgentState<Part2, Payload>,
986 StateId: IndexLike,
987 Payload: DataLike,
988 const MAX_PARTS: usize,
989 > AgentType<StateId, Payload>
990 for ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
991{
992 fn reaction(
993 &self,
994 instance: usize,
995 state_ids: &[StateId],
996 payload: &Payload,
997 ) -> Reaction<StateId, Payload> {
998 debug_assert!(
999 instance < self.instances_count(),
1000 "instance: {} count: {}",
1001 instance,
1002 self.instances_count()
1003 );
1004
1005 let (all_parts1, all_parts2) = self.collect_parts(state_ids);
1006 let parts1 = &all_parts1[..self.part1_type.parts_count()];
1007 let parts2 = &all_parts2[..self.part2_type.parts_count()];
1008
1009 let reaction = self
1010 .agent_type_data
1011 .states
1012 .borrow()
1013 .get(state_ids[self.agent_type_data.first_index + instance])
1014 .reaction(instance, payload, parts1, parts2);
1015 self.agent_type_data.translate_reaction(&reaction)
1016 }
1017
1018 fn activity(&self, instance: usize, state_ids: &[StateId]) -> Activity<Payload> {
1019 debug_assert!(
1020 instance < self.instances_count(),
1021 "instance: {} count: {}",
1022 instance,
1023 self.instances_count()
1024 );
1025
1026 let (all_parts1, all_parts2) = self.collect_parts(state_ids);
1027 let parts1 = &all_parts1[..self.part1_type.parts_count()];
1028 let parts2 = &all_parts2[..self.part2_type.parts_count()];
1029
1030 self.agent_type_data
1031 .states
1032 .borrow()
1033 .get(state_ids[self.agent_type_data.first_index + instance])
1034 .activity(instance, parts1, parts2)
1035 }
1036
1037 fn state_is_deferring(&self, instance: usize, state_ids: &[StateId]) -> bool {
1038 debug_assert!(
1039 instance < self.instances_count(),
1040 "instance: {} count: {}",
1041 instance,
1042 self.instances_count()
1043 );
1044
1045 let (all_parts1, all_parts2) = self.collect_parts(state_ids);
1046 let parts1 = &all_parts1[..self.part1_type.parts_count()];
1047 let parts2 = &all_parts2[..self.part2_type.parts_count()];
1048
1049 self.agent_type_data
1050 .states
1051 .borrow()
1052 .get(state_ids[self.agent_type_data.first_index + instance])
1053 .is_deferring(instance, parts1, parts2)
1054 }
1055
1056 fn state_invalid_because(
1057 &self,
1058 instance: usize,
1059 state_ids: &[StateId],
1060 ) -> Option<&'static str> {
1061 debug_assert!(
1062 instance < self.instances_count(),
1063 "instance: {} count: {}",
1064 instance,
1065 self.instances_count()
1066 );
1067
1068 let (all_parts1, all_parts2) = self.collect_parts(state_ids);
1069 let parts1 = &all_parts1[..self.part1_type.parts_count()];
1070 let parts2 = &all_parts2[..self.part2_type.parts_count()];
1071
1072 self.agent_type_data
1073 .states
1074 .borrow()
1075 .get(state_ids[self.agent_type_data.first_index + instance])
1076 .invalid_because(instance, parts1, parts2)
1077 }
1078
1079 fn state_max_in_flight_messages(
1080 &self,
1081 instance: usize,
1082 state_ids: &[StateId],
1083 ) -> Option<usize> {
1084 debug_assert!(
1085 instance < self.instances_count(),
1086 "instance: {} count: {}",
1087 instance,
1088 self.instances_count()
1089 );
1090
1091 let (all_parts1, all_parts2) = self.collect_parts(state_ids);
1092 let parts1 = &all_parts1[..self.part1_type.parts_count()];
1093 let parts2 = &all_parts2[..self.part2_type.parts_count()];
1094
1095 self.agent_type_data
1096 .states
1097 .borrow()
1098 .get(state_ids[self.agent_type_data.first_index + instance])
1099 .max_in_flight_messages(instance, parts1, parts2)
1100 }
1101
1102 fn states_count(&self) -> usize {
1103 self.agent_type_data.states.borrow().len()
1104 }
1105
1106 fn compute_terse(&self) {
1107 self.agent_type_data.impl_compute_terse();
1108 }
1109}
1110#[macro_export]
1118macro_rules! index_type {
1119 ($name:ident, $type:ident) => {
1120 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Debug)]
1121 pub struct $name($type);
1122
1123 impl total_space::IndexLike for $name {
1124 fn from_usize(value: usize) -> Self {
1125 $name($type::from_usize(value).unwrap())
1126 }
1127
1128 fn to_usize(&self) -> usize {
1129 let $name(value) = self;
1130 $type::to_usize(value).unwrap()
1131 }
1132
1133 fn invalid() -> Self {
1134 $name($type::max_value())
1135 }
1136 }
1137
1138 impl Display for $name {
1139 fn fmt(&self, formatter: &mut Formatter<'_>) -> FormatterResult {
1140 write!(formatter, "{}", self.to_usize())
1141 }
1142 }
1143 };
1144}