use crate::traits::Tracker;
use crate::{Input, Message, Output, Signal};
use alloc::vec;
use alloc::vec::Vec;
use rustc_hash::FxHashMap;
pub struct DynamicTracker<T = ()> {
id_position: usize,
buffer_size: usize,
inputs: FxHashMap<usize, FxHashMap<&'static str, Vec<Output>>>,
signals: FxHashMap<usize, FxHashMap<&'static str, Signal>>,
messages: FxHashMap<usize, Vec<Message<T>>>,
}
impl<T> DynamicTracker<T> {
pub fn new(buffer_size: usize) -> Self {
DynamicTracker {
id_position: 0,
buffer_size,
inputs: FxHashMap::default(),
signals: FxHashMap::default(),
messages: FxHashMap::default(),
}
}
}
impl<T> Tracker<T> for DynamicTracker<T> {
fn get_buffer_size(&self) -> &usize {
&self.buffer_size
}
fn create_source_id(&mut self) -> usize {
let id = self.id_position;
self.id_position += 1;
id
}
fn clear_source(&mut self, id: usize) {
self.signals.remove(&id);
}
fn get_sources(&self, id: &usize) -> Vec<usize> {
let mut sources = vec![];
if let Some(source) = self.inputs.get(id) {
for input in source.values() {
for output in input {
sources.push(*output.get_source_id());
}
}
}
sources
}
fn get_output(&self, o: &Output) -> Option<&Signal> {
self.signals
.get(o.get_source_id())
.and_then(|signals| signals.get(o.get_signal_id()))
}
fn get_mut_output(&mut self, o: &Output) -> Option<&mut Signal> {
self.signals
.get_mut(o.get_source_id())
.and_then(|signals| signals.get_mut(o.get_signal_id()))
}
fn init_output(&mut self, o: &Output) {
if let None = self.signals.get(o.get_source_id()) {
self.signals
.insert(*o.get_source_id(), FxHashMap::default());
}
let source = self.signals.get_mut(o.get_source_id()).unwrap();
source.insert(o.get_signal_id(), Signal::empty(self.buffer_size));
}
fn init_input(&mut self, s: &Input) {
if let None = self.inputs.get(s.get_source_id()) {
self.inputs.insert(*s.get_source_id(), FxHashMap::default());
}
let input = self.inputs.get_mut(s.get_source_id()).unwrap();
input.insert(s.get_signal_id(), vec![]);
}
fn get_input(&self, s: &Input) -> Option<&[Output]> {
self.inputs
.get(s.get_source_id())
.and_then(|signals| signals.get(s.get_signal_id()))
.map(|v| v.as_slice())
}
fn resize_buffers(&mut self, buffer_size: usize) {
self.buffer_size = buffer_size;
for (_, source) in self.signals.iter_mut() {
for (_, signal) in source.iter_mut() {
signal.samples.resize(self.buffer_size, 0.0);
}
}
}
fn connect_signal(&mut self, output: &Output, input: &Input) {
if let Some(input) = self
.inputs
.get_mut(input.get_source_id())
.and_then(|signals| signals.get_mut(input.get_signal_id()))
{
input.push(*output);
}
}
fn clear_connection(&mut self, output: &Output, input: &Input) {
if let Some(input) = self
.inputs
.get_mut(input.get_source_id())
.and_then(|signals| signals.get_mut(input.get_signal_id()))
{
input.retain(|o| o != output);
}
}
fn send_message(&mut self, id: &usize, message: Message<T>) {
if let Some(messages) = self.messages.get_mut(id) {
messages.push(message);
}
}
fn get_messages(&self, id: &usize) -> Option<&[Message<T>]> {
self.messages.get(id).map(|v| v.as_slice())
}
fn clear_messages(&mut self) {
self.messages.clear();
}
}