use std::time::Duration;
use crate::{
Decibels, Mix, Value,
effect::{Effect, EffectBuilder},
};
use super::{Delay, DelayHandle, command_writers_and_readers};
pub struct DelayBuilder {
pub(super) delay_time: Duration,
pub(super) feedback: Value<Decibels>,
pub(super) feedback_effects: Vec<Box<dyn Effect>>,
pub(super) mix: Value<Mix>,
}
impl DelayBuilder {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use = "This method consumes self and returns a modified DelayBuilder, so the return value should be used"]
pub fn delay_time(self, delay_time: Duration) -> Self {
Self { delay_time, ..self }
}
#[must_use = "This method consumes self and returns a modified DelayBuilder, so the return value should be used"]
pub fn feedback(self, feedback: impl Into<Value<Decibels>>) -> Self {
Self {
feedback: feedback.into(),
..self
}
}
pub fn add_feedback_effect<B: EffectBuilder>(&mut self, builder: B) -> B::Handle {
let (effect, handle) = builder.build();
self.feedback_effects.push(effect);
handle
}
pub fn with_feedback_effect<B: EffectBuilder>(mut self, builder: B) -> Self {
self.add_feedback_effect(builder);
self
}
#[must_use = "This method consumes self and returns a modified DelayBuilder, so the return value should be used"]
pub fn mix(self, mix: impl Into<Value<Mix>>) -> Self {
Self {
mix: mix.into(),
..self
}
}
}
impl Default for DelayBuilder {
fn default() -> Self {
Self {
delay_time: Duration::from_millis(500),
feedback: Value::Fixed(Decibels(-6.0)),
feedback_effects: vec![],
mix: Value::Fixed(Mix(0.5)),
}
}
}
impl EffectBuilder for DelayBuilder {
type Handle = DelayHandle;
fn build(self) -> (Box<dyn Effect>, Self::Handle) {
let (command_writers, command_readers) = command_writers_and_readers();
(
Box::new(Delay::new(self, command_readers)),
DelayHandle { command_writers },
)
}
}