use nord_format::formats::nsmp::codec::Audio;
#[cfg(not(target_arch = "wasm32"))]
mod native;
#[cfg(not(target_arch = "wasm32"))]
use native::Sound;
#[cfg(target_arch = "wasm32")]
mod web;
#[cfg(target_arch = "wasm32")]
use web::Sound;
pub type Zone = (u64, usize);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Act {
Play(Zone),
Stop,
}
pub fn act(playing: Option<Zone>, zone: Zone) -> Act {
match playing == Some(zone) {
true => Act::Stop,
false => Act::Play(zone),
}
}
#[derive(Default)]
pub struct Player {
sound: Sound,
playing: Option<Zone>,
}
impl Player {
pub fn playing(&self) -> Option<Zone> {
self.playing
}
pub fn toggle(&mut self, zone: Zone, audio: &Audio) -> Result<(), String> {
let asked = act(self.playing, zone);
self.stop();
if let Act::Play(zone) = asked {
self.sound.play(&audio.samples, audio.channels)?;
self.playing = Some(zone);
}
Ok(())
}
pub fn stop(&mut self) {
if self.playing.take().is_some() {
self.sound.stop();
}
}
pub fn settle(&mut self) {
if self.playing.is_some() && self.sound.finished() {
self.playing = None;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn only_one_zone_ever_sounds() {
let first = (7, 0);
let second = (7, 1);
let elsewhere = (9, 0);
assert_eq!(act(None, first), Act::Play(first));
assert_eq!(act(Some(first), first), Act::Stop);
assert_eq!(act(Some(first), second), Act::Play(second));
assert_eq!(act(Some(first), elsewhere), Act::Play(elsewhere));
}
}