Refactor source management to be clearer and make more sense.

This commit is contained in:
Nolan Darilek 2021-05-21 12:02:45 -05:00
parent ca7492583a
commit 88fd87227e

View File

@ -42,11 +42,9 @@ impl AssetLoader for BufferAssetLoader {
let reader = claxon::FlacReader::new(cursor); let reader = claxon::FlacReader::new(cursor);
if let Ok(mut reader) = reader { if let Ok(mut reader) = reader {
let mut samples: Vec<i16> = vec![]; let mut samples: Vec<i16> = vec![];
for sample in reader.samples() { for sample in reader.samples().flatten() {
if let Ok(sample) = sample {
samples.push(sample as i16); samples.push(sample as i16);
} }
}
let info = reader.streaminfo(); let info = reader.streaminfo();
Some(Buffer { Some(Buffer {
samples, samples,
@ -73,11 +71,9 @@ impl AssetLoader for BufferAssetLoader {
let reader = hound::WavReader::new(cursor); let reader = hound::WavReader::new(cursor);
if let Ok(mut reader) = reader { if let Ok(mut reader) = reader {
let mut samples: Vec<i16> = vec![]; let mut samples: Vec<i16> = vec![];
for sample in reader.samples::<i16>() { for sample in reader.samples::<i16>().flatten() {
if let Ok(sample) = sample {
samples.push(sample); samples.push(sample);
} }
}
Some(Buffer { Some(Buffer {
samples, samples,
sample_rate: reader.spec().sample_rate as i32, sample_rate: reader.spec().sample_rate as i32,
@ -156,8 +152,8 @@ pub struct Sound {
pub buffer: Handle<Buffer>, pub buffer: Handle<Buffer>,
pub state: SoundState, pub state: SoundState,
pub gain: f32, pub gain: f32,
pub looping: bool,
pub pitch: f32, pub pitch: f32,
pub looping: bool,
pub reference_distance: f32, pub reference_distance: f32,
pub max_distance: f32, pub max_distance: f32,
pub rolloff_factor: f32, pub rolloff_factor: f32,
@ -200,10 +196,19 @@ impl DerefMut for GlobalEffects {
} }
} }
fn update_source_position( #[allow(clippy::too_many_arguments)]
fn sync_source_and_components(
source: &mut StaticSource, source: &mut StaticSource,
transform: Option<&Transform>, transform: Option<&Transform>,
global_transform: Option<&GlobalTransform>, global_transform: Option<&GlobalTransform>,
gain: f32,
pitch: f32,
looping: bool,
reference_distance: f32,
max_distance: f32,
rolloff_factor: f32,
bypass_global_effects: bool,
global_effects: &mut Vec<AuxEffectSlot>,
) { ) {
let translation = global_transform let translation = global_transform
.map(|v| v.translation) .map(|v| v.translation)
@ -214,10 +219,20 @@ fn update_source_position(
.set_position([translation.x, translation.y, translation.z]) .set_position([translation.x, translation.y, translation.z])
.unwrap(); .unwrap();
} else { } else {
//println!("No translation: {:?}, {:?}", transform, global_transform);
source.set_relative(true); source.set_relative(true);
source.set_position([0., 0., 0.]).unwrap(); source.set_position([0., 0., 0.]).unwrap();
} }
source.set_gain(gain).unwrap();
source.set_pitch(pitch).unwrap();
source.set_looping(looping);
source.set_reference_distance(reference_distance).unwrap();
source.set_max_distance(max_distance).unwrap();
source.set_rolloff_factor(rolloff_factor).unwrap();
if !bypass_global_effects {
for (send, effect) in global_effects.iter_mut().enumerate() {
source.set_aux_send(send as i32, effect).unwrap();
}
}
} }
fn source_update( fn source_update(
@ -227,8 +242,17 @@ fn source_update(
mut query: Query<(&mut Sound, Option<&Transform>, Option<&GlobalTransform>)>, mut query: Query<(&mut Sound, Option<&Transform>, Option<&GlobalTransform>)>,
) { ) {
for (mut sound, transform, global_transform) in query.iter_mut() { for (mut sound, transform, global_transform) in query.iter_mut() {
let state = sound.state; let Sound {
match state { gain,
pitch,
looping,
reference_distance,
max_distance,
rolloff_factor,
bypass_global_effects,
..
} = *sound;
match &sound.state {
SoundState::Stopped => { SoundState::Stopped => {
if let Some(source) = sound.source.as_mut() { if let Some(source) = sound.source.as_mut() {
source.stop(); source.stop();
@ -237,8 +261,20 @@ fn source_update(
} }
SoundState::Playing => { SoundState::Playing => {
if let Some(source) = sound.source.as_mut() { if let Some(source) = sound.source.as_mut() {
let source_state = source.state(); sync_source_and_components(
if source_state == SourceState::Paused { source,
transform,
global_transform,
gain,
pitch,
looping,
reference_distance,
max_distance,
rolloff_factor,
bypass_global_effects,
&mut **global_effects,
);
if ![SourceState::Playing, SourceState::Stopped].contains(&source.state()) {
source.play(); source.play();
} }
} else { } else {
@ -246,65 +282,72 @@ fn source_update(
if let Some(buffer) = buffers.0.get(&sound.buffer.id) { if let Some(buffer) = buffers.0.get(&sound.buffer.id) {
source.set_buffer(buffer.clone()).unwrap(); source.set_buffer(buffer.clone()).unwrap();
} }
update_source_position(&mut source, transform, global_transform); sync_source_and_components(
&mut source,
transform,
global_transform,
gain,
pitch,
looping,
reference_distance,
max_distance,
rolloff_factor,
bypass_global_effects,
&mut **global_effects,
);
source.play(); source.play();
sound.source = Some(source); sound.source = Some(source);
} }
} }
SoundState::Paused => { SoundState::Paused => {
if let Some(source) = sound.source.as_mut() { if let Some(source) = sound.source.as_mut() {
if source.state() != SourceState::Paused {
source.pause(); source.pause();
sync_source_and_components(
source,
transform,
global_transform,
gain,
pitch,
looping,
reference_distance,
max_distance,
rolloff_factor,
bypass_global_effects,
&mut **global_effects,
);
}
} else { } else {
let mut source = context.new_static_source().unwrap(); let mut source = context.new_static_source().unwrap();
if let Some(buffer) = buffers.0.get(&sound.buffer.id) { if let Some(buffer) = buffers.0.get(&sound.buffer.id) {
source.set_buffer(buffer.clone()).unwrap(); source.set_buffer(buffer.clone()).unwrap();
} }
sync_source_and_components(
&mut source,
transform,
global_transform,
gain,
pitch,
looping,
reference_distance,
max_distance,
rolloff_factor,
bypass_global_effects,
&mut **global_effects,
);
source.pause(); source.pause();
sound.source = Some(source); sound.source = Some(source);
} }
} }
} }
let state = sound.state; if let Some(source) = &sound.source {
let gain = sound.gain; sound.state = match source.state() {
let looping = sound.looping;
let pitch = sound.pitch;
let reference_distance = sound.reference_distance;
let max_distance = sound.max_distance;
let rolloff_factor = sound.rolloff_factor;
let bypass_global_effects = sound.bypass_global_effects;
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,
}; };
} else {
sound.state = SoundState::Stopped;
}
if let Some(source) = sound.source.as_mut() {
if state != SoundState::Stopped {
source.set_gain(gain).unwrap();
source.set_looping(looping);
source.set_pitch(pitch).unwrap();
source.set_reference_distance(reference_distance).unwrap();
source.set_max_distance(max_distance).unwrap();
source.set_rolloff_factor(rolloff_factor).unwrap();
update_source_position(source, transform, global_transform);
if !bypass_global_effects {
for (send, effect) in global_effects.iter_mut().enumerate() {
source.set_aux_send(send as i32, effect).unwrap();
}
}
} else {
sound.source = None;
}
} }
} }
} }
@ -382,7 +425,7 @@ impl Plugin for OpenAlPlugin {
if !app.world().contains_resource::<OpenAlConfig>() { if !app.world().contains_resource::<OpenAlConfig>() {
app.insert_resource(OpenAlConfig::default()); app.insert_resource(OpenAlConfig::default());
} }
let config = app.world().get_resource::<OpenAlConfig>().unwrap().clone(); let config = *app.world().get_resource::<OpenAlConfig>().unwrap();
let al = Alto::load_default().expect("Could not load alto"); let al = Alto::load_default().expect("Could not load alto");
let device = al.open(None).expect("Could not open device"); let device = al.open(None).expect("Could not open device");
let mut context_attrs = ContextAttrs::default(); let mut context_attrs = ContextAttrs::default();