feat(audio): add AudioSource ECS component

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 14:43:48 +09:00
parent ce1a79cab6
commit 6121530bfe
2 changed files with 80 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
/// ECS component that attaches audio playback to an entity.
#[derive(Debug, Clone)]
pub struct AudioSource {
pub clip_id: u32,
pub volume: f32,
pub spatial: bool,
pub looping: bool,
pub playing: bool,
pub played_once: bool,
}
impl AudioSource {
pub fn new(clip_id: u32) -> Self {
AudioSource {
clip_id,
volume: 1.0,
spatial: false,
looping: false,
playing: false,
played_once: false,
}
}
pub fn spatial(mut self) -> Self { self.spatial = true; self }
pub fn looping(mut self) -> Self { self.looping = true; self }
pub fn play(&mut self) {
self.playing = true;
self.played_once = false;
}
pub fn stop(&mut self) {
self.playing = false;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_defaults() {
let src = AudioSource::new(42);
assert_eq!(src.clip_id, 42);
assert!((src.volume - 1.0).abs() < 1e-6);
assert!(!src.spatial);
assert!(!src.looping);
assert!(!src.playing);
assert!(!src.played_once);
}
#[test]
fn test_builder_pattern() {
let src = AudioSource::new(1).spatial().looping();
assert!(src.spatial);
assert!(src.looping);
}
#[test]
fn test_play_stop() {
let mut src = AudioSource::new(1);
src.play();
assert!(src.playing);
assert!(!src.played_once);
src.played_once = true;
src.play(); // re-play should reset played_once
assert!(!src.played_once);
src.stop();
assert!(!src.playing);
}
#[test]
fn test_volume() {
let mut src = AudioSource::new(1);
src.volume = 0.5;
assert!((src.volume - 0.5).abs() < 1e-6);
}
}

View File

@@ -6,8 +6,10 @@ pub mod wasapi;
pub mod audio_system;
pub mod spatial;
pub mod mix_group;
pub mod audio_source;
pub use audio_clip::AudioClip;
pub use audio_source::AudioSource;
pub use wav::{parse_wav, generate_wav_bytes};
pub use mixing::{PlayingSound, mix_sounds};
pub use audio_system::AudioSystem;