use crate::sounds::wrappers::SetPaused;
use crate::sounds::wrappers::SetVolume;
use crate::Sound;
use std::sync::mpsc;
use super::stoppable::SetStopped;
use super::AddSound;
use super::ClearSounds;
use super::SetSpeed;
use super::Wrapper;
pub struct Controllable<S: Sound> {
inner: S,
command_receiver: mpsc::Receiver<Command<S>>,
finished: bool,
}
impl<S> Controllable<S>
where
S: Sound,
{
pub fn new(inner: S) -> (Self, Controller<S>) {
let (command_sender, command_receiver) = mpsc::channel::<Command<S>>();
let controllable = Controllable {
inner,
command_receiver,
finished: false,
};
let controller = Controller { command_sender };
(controllable, controller)
}
pub fn finish_with_inner(&mut self) {
self.finished = true;
}
}
impl<S> Sound for Controllable<S>
where
S: Sound,
{
fn channel_count(&self) -> u16 {
self.inner.channel_count()
}
fn sample_rate(&self) -> u32 {
self.inner.sample_rate()
}
fn next_sample(&mut self) -> Result<crate::NextSample, crate::Error> {
let next = self.inner.next_sample()?;
match next {
crate::NextSample::Sample(_)
| crate::NextSample::MetadataChanged
| crate::NextSample::Paused => Ok(next),
crate::NextSample::Finished => {
if self.finished {
Ok(crate::NextSample::Finished)
} else {
Ok(crate::NextSample::Paused)
}
}
}
}
fn on_start_of_batch(&mut self) {
loop {
match self.command_receiver.try_recv() {
Ok(command) => command(&mut self.inner),
Err(mpsc::TryRecvError::Empty) => break,
Err(mpsc::TryRecvError::Disconnected) => {
self.finished = true;
break;
}
}
}
self.inner.on_start_of_batch();
}
}
impl<S> Wrapper for Controllable<S>
where
S: Sound,
{
type Inner = S;
fn inner(&self) -> &S {
&self.inner
}
fn inner_mut(&mut self) -> &mut Self::Inner {
&mut self.inner
}
fn into_inner(self) -> S {
self.inner
}
}
type Command<S> = Box<dyn FnOnce(&mut S) + Send>;
pub struct Controller<S: Sound> {
command_sender: mpsc::Sender<Command<S>>,
}
impl<S> Clone for Controller<S>
where
S: Sound,
{
fn clone(&self) -> Self {
Self {
command_sender: self.command_sender.clone(),
}
}
}
impl<S> Controller<S>
where
S: Sound,
{
pub fn send_command(&mut self, command: Command<S>) {
let _ = self.command_sender.send(command);
}
}
impl<S> Controller<S>
where
S: Sound + AddSound,
{
pub fn add(&mut self, sound: Box<dyn Sound>) {
self.send_command(Box::new(|s: &mut S| s.add(sound)));
}
}
impl<S> Controller<S>
where
S: Sound + ClearSounds,
{
pub fn clear(&mut self) {
self.send_command(Box::new(|s: &mut S| s.clear()));
}
}
impl<S> Controller<S>
where
S: Sound + SetPaused,
{
pub fn set_paused(&mut self, paused: bool) {
self.send_command(Box::new(move |s: &mut S| s.set_paused(paused)));
}
}
impl<S> Controller<S>
where
S: Sound + SetStopped,
{
pub fn set_stopped(&mut self) {
self.send_command(Box::new(move |s: &mut S| s.set_stopped()));
}
}
impl<S> Controller<S>
where
S: Sound + SetSpeed,
{
pub fn set_speed(&mut self, speed: f32) {
self.send_command(Box::new(move |s: &mut S| s.set_speed(speed)));
}
}
impl<S> Controller<S>
where
S: Sound + SetVolume,
{
pub fn set_volume(&mut self, volume: f32) {
self.send_command(Box::new(move |s: &mut S| s.set_volume(volume)));
}
}