use super::audiounit::*;
use super::buffer::*;
use super::math::*;
use super::net::*;
use super::setting::*;
use super::signal::*;
use thingbuf::mpsc::{Receiver, Sender, channel};
extern crate alloc;
use alloc::boxed::Box;
#[derive(Default, Clone)]
pub(crate) enum NetMessage {
#[default]
Null,
Net(Net),
Setting(Setting),
}
#[derive(Default, Clone)]
pub(crate) enum NetReturn {
#[default]
Null,
Net(Net),
Unit(Box<dyn AudioUnit>),
}
pub struct NetBackend {
sender: Option<Sender<NetReturn>>,
receiver: Receiver<NetMessage>,
net: Net,
}
impl Clone for NetBackend {
fn clone(&self) -> Self {
let (sender_net, _receiver_net) = channel(1);
let (_sender_message, receiver_message) = channel(1);
Self {
sender: Some(sender_net),
receiver: receiver_message,
net: self.net.clone(),
}
}
}
impl NetBackend {
pub(crate) fn new(sender: Sender<NetReturn>, receiver: Receiver<NetMessage>, net: Net) -> Self {
Self {
sender: Some(sender),
receiver,
net,
}
}
fn handle_messages(&mut self) {
let mut latest_net: Option<Net> = None;
#[allow(clippy::while_let_loop)]
loop {
match self.receiver.try_recv() {
Ok(message) => {
match message {
NetMessage::Net(net) => {
if let Some(mut net) = latest_net {
self.net.apply_foreign_edits(&mut net, &self.sender);
if self
.sender
.as_ref()
.unwrap()
.try_send(NetReturn::Net(net))
.is_ok()
{}
}
latest_net = Some(net);
}
NetMessage::Setting(setting) => {
self.net.set(setting);
}
NetMessage::Null => (),
}
}
_ => break,
}
}
if let Some(mut net) = latest_net {
self.net.migrate(&mut net);
core::mem::swap(&mut net, &mut self.net);
self.net.apply_edits(&self.sender);
if self
.sender
.as_ref()
.unwrap()
.try_send(NetReturn::Net(net))
.is_ok()
{}
}
}
}
impl AudioUnit for NetBackend {
fn inputs(&self) -> usize {
self.net.inputs()
}
fn outputs(&self) -> usize {
self.net.outputs()
}
fn reset(&mut self) {
self.net.reset();
self.handle_messages();
}
fn set_sample_rate(&mut self, sample_rate: f64) {
self.net.set_sample_rate(sample_rate);
self.handle_messages();
}
fn tick(&mut self, input: &[f32], output: &mut [f32]) {
self.handle_messages();
self.net.tick_2(input, output, &self.sender);
}
fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
self.handle_messages();
self.net.process_2(size, input, output, &self.sender);
}
fn get_id(&self) -> u64 {
self.net.get_id()
}
fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
self.handle_messages();
self.net.ping(probe, hash)
}
fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
self.handle_messages();
self.net.route(input, frequency)
}
fn footprint(&self) -> usize {
self.net.footprint()
}
fn allocate(&mut self) {
self.net.allocate();
}
}