use super::Controller;
use super::{ControllerParams, SoundInstruction};
use std::sync::Mutex;
use std::time::Duration;
static CONTROLLER_ID_COUNTER: Mutex<u64> = Mutex::new(5_000_000_000);
#[must_use = "SoundBuilder does nothing unless passed to audio::play or a similar function"]
#[derive(Debug, PartialEq, Clone, Default)]
pub struct SoundBuilder(SoundInstruction);
impl SoundBuilder {
pub fn file(path: impl Into<String>) -> Self {
Self(SoundInstruction::PlayFile(path.into()))
}
pub fn list(sounds: Vec<SoundBuilder>) -> Self {
Self(SoundInstruction::List(
sounds.into_iter().map(SoundInstruction::from).collect(),
))
}
pub fn simultaneous(sounds: Vec<SoundBuilder>) -> Self {
Self(SoundInstruction::Simultaneous(
sounds.into_iter().map(SoundInstruction::from).collect(),
))
}
pub fn silence(duration: Duration) -> Self {
Self(SoundInstruction::Silence(duration))
}
pub fn speak_number(n: i64) -> Self {
Self(SoundInstruction::SpeakNumber(n))
}
pub fn sine_wave(hz: f32) -> Self {
Self(SoundInstruction::SineWave(hz))
}
pub fn error_sound() -> Self {
Self(SoundInstruction::ErrorSound)
}
pub fn empty_sound() -> Self {
Self(SoundInstruction::EmptySound)
}
pub fn repeat(self, times: u64) -> Self {
Self(SoundInstruction::Repeat(Box::new(self.0), Some(times)))
}
pub fn repeat_forever(self) -> Self {
Self(SoundInstruction::Repeat(Box::new(self.0), None))
}
pub fn volume(self, multiplier: f32) -> Self {
Self(SoundInstruction::Volume(multiplier, Box::new(self.0)))
}
pub fn speed(self, multiplier: f32) -> Self {
Self(SoundInstruction::Speed(multiplier, Box::new(self.0)))
}
pub fn controller(self) -> (Self, Controller) {
let id = next_controller_id();
let instruction = SoundInstruction::Controller(
Box::new(self.0),
ControllerParams {
id,
speed: None,
volume: None,
paused: None,
},
);
(Self(instruction), Controller::new(id))
}
pub fn controller_with_opts(self, opts: ControllerOpts) -> (Self, Controller) {
let id = next_controller_id();
let instruction = SoundInstruction::Controller(
Box::new(self.0),
ControllerParams {
id,
speed: opts.speed,
volume: opts.volume,
paused: opts.paused,
},
);
(Self(instruction), Controller::new(id))
}
pub fn from_instruction(instruction: SoundInstruction) -> Self {
Self(instruction)
}
pub fn into_instruction(self) -> SoundInstruction {
self.0
}
pub fn as_instruction(&self) -> &SoundInstruction {
&self.0
}
}
impl From<String> for SoundBuilder {
fn from(path: String) -> Self {
Self::file(path)
}
}
impl From<&str> for SoundBuilder {
fn from(path: &str) -> Self {
Self::file(path)
}
}
impl<T: Into<SoundBuilder>> From<Vec<T>> for SoundBuilder {
fn from(sounds: Vec<T>) -> Self {
Self::list(sounds.into_iter().map(Into::into).collect())
}
}
#[derive(Debug, Default, Clone)]
pub struct ControllerOpts {
speed: Option<f32>,
volume: Option<f32>,
paused: Option<bool>,
}
impl ControllerOpts {
pub fn new() -> Self {
Self::default()
}
pub fn speed(mut self, speed: f32) -> Self {
self.speed = Some(speed);
self
}
pub fn volume(mut self, volume: f32) -> Self {
self.volume = Some(volume);
self
}
pub fn pause(mut self) -> Self {
self.paused = Some(true);
self
}
}
impl From<SoundBuilder> for SoundInstruction {
fn from(builder: SoundBuilder) -> Self {
builder.0
}
}
pub fn next_controller_id() -> u64 {
let mut counter = CONTROLLER_ID_COUNTER.lock().unwrap();
*counter += 1;
*counter - 1
}