use crossbeam::channel::{bounded, Select};
use std::ops::{Index, IndexMut, Range};
use crate::scheduler::engine::Token;
use crate::scheduler::session::Session;
use crate::scheduler::signal::{Id, Value};
pub mod traits;
pub mod transport;
use traits::{AnyRelay, AnySender};
use transport::{Error, Relay};
#[derive(Debug)]
pub struct Router<I> {
relays: Vec<Box<dyn AnyRelay<I>>>,
senders: Vec<(Box<dyn AnySender<I>>, Token)>,
}
impl<I> Router<I>
where
I: Id,
{
pub fn session<T>(&mut self) -> Session<I, T>
where
T: Value,
{
let (sender, receiver) = bounded(1024);
let mut relay = Relay::from(receiver);
for (inner, token) in &self.senders {
let _ = AnyRelay::add(&mut relay, *token, inner.as_ref());
}
self.relays.push(Box::new(relay));
Session { sender }
}
pub fn add(&mut self, token: Token, sender: &dyn AnySender<I>) {
self.senders.push((sender.clone_box(), token));
for relay in &mut self.relays {
let _ = relay.add(token, sender);
}
}
#[inline]
pub fn add_to_select<'a>(
&'a self, select: &mut Select<'a>,
) -> Range<usize> {
if self.relays.is_empty() {
return 0..0;
}
let start = self.relays[0].add_to_select(select);
for relay in &self.relays[1..] {
relay.add_to_select(select);
}
start..start + self.relays.len()
}
pub fn poll(&mut self, index: usize) -> Vec<Token> {
match self.relays[index].poll() {
Ok(tokens) => return tokens,
Err(Error::Disconnected) => {
self.relays.swap_remove(index);
}
_ => unreachable!(),
}
vec![]
}
}
#[allow(clippy::must_use_candidate)]
impl<T> Router<T> {
#[inline]
pub fn len(&self) -> usize {
self.relays.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.relays.is_empty()
}
}
impl<I> Index<usize> for Router<I> {
type Output = dyn AnyRelay<I>;
#[inline]
fn index(&self, index: usize) -> &Self::Output {
self.relays[index].as_ref()
}
}
impl<I> IndexMut<usize> for Router<I> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.relays[index].as_mut()
}
}
impl<I> Default for Router<I> {
#[inline]
fn default() -> Self {
Self {
relays: Vec::default(),
senders: Vec::default(),
}
}
}