Switch to using hierarchies for sound playback, and restore play`stop/pause methods for forcing immediate source changes.

This commit is contained in:
Nolan Darilek 2021-01-08 12:56:08 -06:00
parent ea24e966ef
commit c33a28efce

View File

@ -156,8 +156,6 @@ impl Default for Sound {
} }
} }
pub type Sounds = HashMap<String, Sound>;
#[derive(Default)] #[derive(Default)]
pub struct GlobalEffects(Vec<AuxEffectSlot>); pub struct GlobalEffects(Vec<AuxEffectSlot>);
@ -179,10 +177,9 @@ fn source_update(
context: Res<Context>, context: Res<Context>,
buffers: Res<Buffers>, buffers: Res<Buffers>,
mut global_effects: ResMut<GlobalEffects>, mut global_effects: ResMut<GlobalEffects>,
mut query: Query<(&mut Sounds, Option<&Transform>)>, mut query: Query<(&mut Sound, Option<&Transform>, Option<&GlobalTransform>)>,
) { ) {
for (mut sounds, transform) in query.iter_mut() { for (mut sound, transform, global_transform) in query.iter_mut() {
for mut sound in sounds.values_mut() {
let state = sound.state; let state = sound.state;
match state { match state {
SoundState::Stopped => { SoundState::Stopped => {
@ -214,26 +211,38 @@ fn source_update(
} }
} }
} }
if let Some(source) = sound.source.as_mut() { let state = sound.state;
sound.state = match source.state() { let gain = sound.gain;
let looping = sound.looping;
let pitch = sound.pitch;
let source_state = if let Some(source) = &sound.source {
Some(source.state())
} else {
None
};
if let Some(source_state) = source_state {
sound.state = match source_state {
SourceState::Initial => SoundState::Stopped, SourceState::Initial => SoundState::Stopped,
SourceState::Playing => SoundState::Playing, SourceState::Playing => SoundState::Playing,
SourceState::Paused => SoundState::Paused, SourceState::Paused => SoundState::Paused,
SourceState::Stopped => SoundState::Stopped, SourceState::Stopped => SoundState::Stopped,
SourceState::Unknown(_) => SoundState::Stopped, SourceState::Unknown(_) => SoundState::Stopped,
}; };
if sound.state != SoundState::Stopped { } else {
source.set_gain(sound.gain).unwrap(); sound.state = SoundState::Stopped;
source.set_looping(sound.looping); }
source.set_pitch(sound.pitch).unwrap(); if let Some(source) = sound.source.as_mut() {
if let Some(transform) = transform { if state != SoundState::Stopped {
source.set_gain(gain).unwrap();
source.set_looping(looping);
source.set_pitch(pitch).unwrap();
let translation = global_transform
.map(|v| v.translation)
.or_else(|| transform.map(|v| v.translation));
if let Some(translation) = translation {
source.set_relative(false); source.set_relative(false);
source source
.set_position([ .set_position([translation.x, translation.y, translation.z])
transform.translation.x,
transform.translation.y,
transform.translation.z,
])
.unwrap(); .unwrap();
} else { } else {
source.set_relative(true); source.set_relative(true);
@ -248,14 +257,46 @@ fn source_update(
} }
} }
} }
impl Sound {
pub fn stop(&mut self) {
if let Some(source) = self.source.as_mut() {
source.stop();
}
self.state = SoundState::Stopped;
self.source = None;
}
pub fn play(&mut self) {
if let Some(source) = self.source.as_mut() {
source.play();
}
self.state = SoundState::Playing;
}
pub fn pause(&mut self) {
if let Some(source) = self.source.as_mut() {
source.pause();
}
self.state = SoundState::Paused;
}
} }
#[derive(Clone, Copy, Debug, Default, Reflect)] #[derive(Clone, Copy, Debug, Default, Reflect)]
#[reflect(Component)] #[reflect(Component)]
pub struct Listener; pub struct Listener;
fn listener_update(context: ResMut<Context>, query: Query<(&Listener, Option<&Transform>)>) { fn listener_update(
for (_, transform) in query.iter() { context: ResMut<Context>,
query: Query<(&Listener, Option<&Transform>, Option<&GlobalTransform>)>,
) {
for (_, transform, global_transform) in query.iter() {
let transform = transform.cloned().or_else(|| {
global_transform.map(|v| {
let matrix = v.compute_matrix();
Transform::from_matrix(matrix)
})
});
if let Some(transform) = transform { if let Some(transform) = transform {
let matrix = transform.compute_matrix().inverse(); let matrix = transform.compute_matrix().inverse();
let look = matrix.x_axis; let look = matrix.x_axis;