use crate::{
clock::{Duration, Instant},
io::NodeAddress,
node::SimNodeErased,
tcp_bus::{TcpEvent, TcpSimBus},
};
pub trait TcpEventHandler {
fn on_tcp_event(&mut self, event: &TcpEvent, now: Instant);
}
pub struct TcpSimRunner<const N: usize, const Q: usize> {
bus: TcpSimBus<N, Q>,
}
impl<const N: usize, const Q: usize> TcpSimRunner<N, Q> {
pub fn new(bus: TcpSimBus<N, Q>) -> Self {
Self { bus }
}
pub fn bus(&mut self) -> &mut TcpSimBus<N, Q> {
&mut self.bus
}
pub fn now(&self) -> Instant {
self.bus.now()
}
pub fn tick(
&mut self,
nodes: &mut [&mut dyn SimNodeErased<N, Q>],
tcp_event_nodes: &mut [&mut dyn TcpEventHandler],
duration: Duration,
) -> usize {
let delivered = self.bus.tick(duration);
let now = self.bus.now();
let mut count = 0;
for envelope in &delivered {
for node in nodes.iter_mut() {
if *node.address() == envelope.dst {
node.handle(&envelope.src, &envelope.data, now);
count += 1;
}
}
}
let tcp_events: heapless::Vec<TcpEvent, 16> = self.bus.drain_events().collect();
for event in &tcp_events {
for handler in tcp_event_nodes.iter_mut() {
handler.on_tcp_event(event, now);
}
}
for node in nodes.iter_mut() {
node.tick(now);
}
let mut outbox: heapless::Vec<(NodeAddress, heapless::Vec<u8, N>), Q> =
heapless::Vec::new();
for node in nodes.iter_mut() {
outbox.clear();
node.drain_outbox(&mut outbox);
let src = node.address().clone();
for (dst, data) in outbox.iter() {
self.bus.send(src.clone(), dst.clone(), data);
}
}
count
}
}