use std::{
collections::{BTreeSet, HashMap},
sync::Arc,
};
use gled_gpu::constants::UNIVERSE_SLOTS;
use gled_model::{
asset::output_device::{
OutputDevice,
routing::{OutputRouting, OutputRoutings},
},
asset_id::AssetId,
};
use super::Recipient;
use crate::{pipeline::extract_output::OutputConfig, storage::collections::Collections};
#[derive(Debug, Clone, PartialEq)]
pub(super) struct Route {
pub(super) universe: u16,
pub(super) routing: OutputRouting,
pub(super) device: AssetId<OutputDevice>,
pub(super) recipient: Option<Recipient>,
}
#[derive(Debug, Default)]
pub(super) struct Routes {
universes: Arc<BTreeSet<u16>>,
routings: Arc<OutputRoutings>,
generation: Option<u64>,
slots: Vec<Option<Route>>,
slot_of: HashMap<Recipient, usize>,
}
impl Routes {
pub(super) fn update(&mut self, config: &OutputConfig, collections: &Collections) {
if self.generation == Some(collections.generation())
&& Arc::ptr_eq(&self.universes, &config.universes)
&& Arc::ptr_eq(&self.routings, &config.routings)
{
return;
}
self.universes = config.universes.clone();
self.routings = config.routings.clone();
self.generation = Some(collections.generation());
self.slots = config
.universes
.iter()
.take(UNIVERSE_SLOTS as usize)
.map(|universe| {
let routing = config.routings.get(universe)?;
Some(Route {
universe: *universe,
routing: routing.clone(),
device: routing.device?,
recipient: routing.recipient(collections),
})
})
.collect();
self.slot_of = self
.slots
.iter()
.enumerate()
.filter_map(|(slot, route)| Some((route.as_ref()?.recipient.clone()?, slot)))
.collect();
}
pub(super) fn slot(&self, slot: usize) -> Option<&Route> {
self.slots.get(slot)?.as_ref()
}
pub(super) fn len(&self) -> usize {
self.slots.len()
}
pub(super) fn slot_of(&self, recipient: &Recipient) -> Option<usize> {
self.slot_of.get(recipient).copied()
}
}