1use crate::{
11 clock::{Duration, Instant},
12 io::NodeAddress,
13 node::SimNodeErased,
14 tcp_bus::{TcpEvent, TcpSimBus},
15};
16use acex_core::Vec;
17
18pub trait TcpEventHandler {
30 fn on_tcp_event(&mut self, event: &TcpEvent, now: Instant);
31}
32
33#[cfg_attr(all(feature = "defmt", not(feature = "alloc")), derive(defmt::Format))]
42pub struct TcpSimRunner<
43 const MAX_DATA: usize,
44 const MAX_QUEUED: usize,
45 const TCP_MAX_EVENTS: usize,
46 const MAX_OUTBOX: usize,
47> {
48 bus: TcpSimBus<MAX_DATA, MAX_QUEUED, TCP_MAX_EVENTS>,
49}
50
51impl<
52 const MAX_DATA: usize,
53 const MAX_QUEUED: usize,
54 const TCP_MAX_EVENTS: usize,
55 const MAX_OUTBOX: usize,
56 > TcpSimRunner<MAX_DATA, MAX_QUEUED, TCP_MAX_EVENTS, MAX_OUTBOX>
57{
58 pub fn new(bus: TcpSimBus<MAX_DATA, MAX_QUEUED, TCP_MAX_EVENTS>) -> Self {
59 Self { bus }
60 }
61
62 pub fn bus(&mut self) -> &mut TcpSimBus<MAX_DATA, MAX_QUEUED, TCP_MAX_EVENTS> {
63 &mut self.bus
64 }
65
66 pub fn now(&self) -> Instant {
67 self.bus.now()
68 }
69
70 pub fn tick(
80 &mut self,
81 nodes: &mut [&mut dyn SimNodeErased<MAX_DATA, MAX_OUTBOX>],
82 tcp_event_nodes: &mut [&mut dyn TcpEventHandler],
83 duration: Duration,
84 ) -> usize {
85 let delivered = self.bus.tick(duration);
86 let now = self.bus.now();
87 let mut count = 0;
88
89 for envelope in &delivered {
90 for node in nodes.iter_mut() {
91 if *node.address() == envelope.dst {
92 node.handle(&envelope.src, &envelope.data, now);
93 count += 1;
94 }
95 }
96 }
97
98 let tcp_events: Vec<TcpEvent, TCP_MAX_EVENTS> = self.bus.drain_events().collect();
99 for event in &tcp_events {
100 for handler in tcp_event_nodes.iter_mut() {
101 handler.on_tcp_event(event, now);
102 }
103 }
104
105 for node in nodes.iter_mut() {
106 node.tick(now);
107 }
108
109 let mut outbox: Vec<(NodeAddress, Vec<u8, MAX_DATA>), MAX_OUTBOX> = Vec::new();
110 for node in nodes.iter_mut() {
111 outbox.clear();
112 node.drain_outbox(&mut outbox);
113
114 let src = node.address().clone();
115
116 for (dst, data) in outbox.iter() {
117 self.bus.send(src.clone(), dst.clone(), data);
118 }
119 }
120
121 count
122 }
123}
124
125