audio sinks don't need their custom drop anymore (#9336)

# Objective

- Fixes #9324 
- Audio sinks used to have a custom drop implementation to detach the
sinks because it was not required to keep a reference to it
- With the new audio api, a reference is kept as a component of an
entity

## Solution

- Remove that custom drop implementation, and the option wrapping that
was required for it.
This commit is contained in:
François 2023-08-11 23:16:12 +02:00 committed by GitHub
parent 6a8fd54006
commit 47a5a16d8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 72 deletions

View File

@ -105,35 +105,25 @@ pub(crate) fn play_queued_audio_system<Source: Asset + Decodable>(
match settings.mode { match settings.mode {
PlaybackMode::Loop => { PlaybackMode::Loop => {
sink.append(audio_source.decoder().repeat_infinite()); sink.append(audio_source.decoder().repeat_infinite());
commands commands.entity(entity).insert(SpatialAudioSink { sink });
.entity(entity)
.insert(SpatialAudioSink { sink: Some(sink) });
} }
PlaybackMode::Once => { PlaybackMode::Once => {
sink.append(audio_source.decoder()); sink.append(audio_source.decoder());
commands commands.entity(entity).insert(SpatialAudioSink { sink });
.entity(entity)
.insert(SpatialAudioSink { sink: Some(sink) });
} }
PlaybackMode::Despawn => { PlaybackMode::Despawn => {
sink.append(audio_source.decoder()); sink.append(audio_source.decoder());
commands commands
.entity(entity) .entity(entity)
// PERF: insert as bundle to reduce archetype moves // PERF: insert as bundle to reduce archetype moves
.insert(( .insert((SpatialAudioSink { sink }, PlaybackDespawnMarker));
SpatialAudioSink { sink: Some(sink) },
PlaybackDespawnMarker,
));
} }
PlaybackMode::Remove => { PlaybackMode::Remove => {
sink.append(audio_source.decoder()); sink.append(audio_source.decoder());
commands commands
.entity(entity) .entity(entity)
// PERF: insert as bundle to reduce archetype moves // PERF: insert as bundle to reduce archetype moves
.insert(( .insert((SpatialAudioSink { sink }, PlaybackRemoveMarker));
SpatialAudioSink { sink: Some(sink) },
PlaybackRemoveMarker,
));
} }
}; };
} }
@ -157,32 +147,25 @@ pub(crate) fn play_queued_audio_system<Source: Asset + Decodable>(
match settings.mode { match settings.mode {
PlaybackMode::Loop => { PlaybackMode::Loop => {
sink.append(audio_source.decoder().repeat_infinite()); sink.append(audio_source.decoder().repeat_infinite());
commands commands.entity(entity).insert(AudioSink { sink });
.entity(entity)
.insert(AudioSink { sink: Some(sink) });
} }
PlaybackMode::Once => { PlaybackMode::Once => {
sink.append(audio_source.decoder()); sink.append(audio_source.decoder());
commands commands.entity(entity).insert(AudioSink { sink });
.entity(entity)
.insert(AudioSink { sink: Some(sink) });
} }
PlaybackMode::Despawn => { PlaybackMode::Despawn => {
sink.append(audio_source.decoder()); sink.append(audio_source.decoder());
commands commands
.entity(entity) .entity(entity)
// PERF: insert as bundle to reduce archetype moves // PERF: insert as bundle to reduce archetype moves
.insert(( .insert((AudioSink { sink }, PlaybackDespawnMarker));
AudioSink { sink: Some(sink) },
PlaybackDespawnMarker,
));
} }
PlaybackMode::Remove => { PlaybackMode::Remove => {
sink.append(audio_source.decoder()); sink.append(audio_source.decoder());
commands commands
.entity(entity) .entity(entity)
// PERF: insert as bundle to reduce archetype moves // PERF: insert as bundle to reduce archetype moves
.insert((AudioSink { sink: Some(sink) }, PlaybackRemoveMarker)); .insert((AudioSink { sink }, PlaybackRemoveMarker));
} }
}; };
} }
@ -215,24 +198,24 @@ pub(crate) fn cleanup_finished_audio<T: Decodable + Asset>(
>, >,
) { ) {
for (entity, sink) in &query_nonspatial_despawn { for (entity, sink) in &query_nonspatial_despawn {
if sink.sink.as_ref().unwrap().empty() { if sink.sink.empty() {
commands.entity(entity).despawn(); commands.entity(entity).despawn();
} }
} }
for (entity, sink) in &query_spatial_despawn { for (entity, sink) in &query_spatial_despawn {
if sink.sink.as_ref().unwrap().empty() { if sink.sink.empty() {
commands.entity(entity).despawn(); commands.entity(entity).despawn();
} }
} }
for (entity, sink) in &query_nonspatial_remove { for (entity, sink) in &query_nonspatial_remove {
if sink.sink.as_ref().unwrap().empty() { if sink.sink.empty() {
commands commands
.entity(entity) .entity(entity)
.remove::<(AudioSourceBundle<T>, AudioSink, PlaybackRemoveMarker)>(); .remove::<(AudioSourceBundle<T>, AudioSink, PlaybackRemoveMarker)>();
} }
} }
for (entity, sink) in &query_spatial_remove { for (entity, sink) in &query_spatial_remove {
if sink.sink.as_ref().unwrap().empty() { if sink.sink.empty() {
commands.entity(entity).remove::<( commands.entity(entity).remove::<(
SpatialAudioSourceBundle<T>, SpatialAudioSourceBundle<T>,
SpatialAudioSink, SpatialAudioSink,

View File

@ -77,52 +77,44 @@ pub trait AudioSinkPlayback {
/// that source is unchanged, that translates to the audio restarting. /// that source is unchanged, that translates to the audio restarting.
#[derive(Component)] #[derive(Component)]
pub struct AudioSink { pub struct AudioSink {
// This field is an Option in order to allow us to have a safe drop that will detach the sink. pub(crate) sink: Sink,
// It will never be None during its life
pub(crate) sink: Option<Sink>,
}
impl Drop for AudioSink {
fn drop(&mut self) {
self.sink.take().unwrap().detach();
}
} }
impl AudioSinkPlayback for AudioSink { impl AudioSinkPlayback for AudioSink {
fn volume(&self) -> f32 { fn volume(&self) -> f32 {
self.sink.as_ref().unwrap().volume() self.sink.volume()
} }
fn set_volume(&self, volume: f32) { fn set_volume(&self, volume: f32) {
self.sink.as_ref().unwrap().set_volume(volume); self.sink.set_volume(volume);
} }
fn speed(&self) -> f32 { fn speed(&self) -> f32 {
self.sink.as_ref().unwrap().speed() self.sink.speed()
} }
fn set_speed(&self, speed: f32) { fn set_speed(&self, speed: f32) {
self.sink.as_ref().unwrap().set_speed(speed); self.sink.set_speed(speed);
} }
fn play(&self) { fn play(&self) {
self.sink.as_ref().unwrap().play(); self.sink.play();
} }
fn pause(&self) { fn pause(&self) {
self.sink.as_ref().unwrap().pause(); self.sink.pause();
} }
fn is_paused(&self) -> bool { fn is_paused(&self) -> bool {
self.sink.as_ref().unwrap().is_paused() self.sink.is_paused()
} }
fn stop(&self) { fn stop(&self) {
self.sink.as_ref().unwrap().stop(); self.sink.stop();
} }
fn empty(&self) -> bool { fn empty(&self) -> bool {
self.sink.as_ref().unwrap().empty() self.sink.empty()
} }
} }
@ -138,61 +130,52 @@ impl AudioSinkPlayback for AudioSink {
/// that source is unchanged, that translates to the audio restarting. /// that source is unchanged, that translates to the audio restarting.
#[derive(Component)] #[derive(Component)]
pub struct SpatialAudioSink { pub struct SpatialAudioSink {
// This field is an Option in order to allow us to have a safe drop that will detach the sink. pub(crate) sink: SpatialSink,
// It will never be None during its life
pub(crate) sink: Option<SpatialSink>,
}
impl Drop for SpatialAudioSink {
fn drop(&mut self) {
self.sink.take().unwrap().detach();
}
} }
impl AudioSinkPlayback for SpatialAudioSink { impl AudioSinkPlayback for SpatialAudioSink {
fn volume(&self) -> f32 { fn volume(&self) -> f32 {
self.sink.as_ref().unwrap().volume() self.sink.volume()
} }
fn set_volume(&self, volume: f32) { fn set_volume(&self, volume: f32) {
self.sink.as_ref().unwrap().set_volume(volume); self.sink.set_volume(volume);
} }
fn speed(&self) -> f32 { fn speed(&self) -> f32 {
self.sink.as_ref().unwrap().speed() self.sink.speed()
} }
fn set_speed(&self, speed: f32) { fn set_speed(&self, speed: f32) {
self.sink.as_ref().unwrap().set_speed(speed); self.sink.set_speed(speed);
} }
fn play(&self) { fn play(&self) {
self.sink.as_ref().unwrap().play(); self.sink.play();
} }
fn pause(&self) { fn pause(&self) {
self.sink.as_ref().unwrap().pause(); self.sink.pause();
} }
fn is_paused(&self) -> bool { fn is_paused(&self) -> bool {
self.sink.as_ref().unwrap().is_paused() self.sink.is_paused()
} }
fn stop(&self) { fn stop(&self) {
self.sink.as_ref().unwrap().stop(); self.sink.stop();
} }
fn empty(&self) -> bool { fn empty(&self) -> bool {
self.sink.as_ref().unwrap().empty() self.sink.empty()
} }
} }
impl SpatialAudioSink { impl SpatialAudioSink {
/// Set the two ears position. /// Set the two ears position.
pub fn set_ears_position(&self, left_position: Vec3, right_position: Vec3) { pub fn set_ears_position(&self, left_position: Vec3, right_position: Vec3) {
let sink = self.sink.as_ref().unwrap(); self.sink.set_left_ear_position(left_position.to_array());
sink.set_left_ear_position(left_position.to_array()); self.sink.set_right_ear_position(right_position.to_array());
sink.set_right_ear_position(right_position.to_array());
} }
/// Set the listener position, with an ear on each side separated by `gap`. /// Set the listener position, with an ear on each side separated by `gap`.
@ -205,9 +188,6 @@ impl SpatialAudioSink {
/// Set the emitter position. /// Set the emitter position.
pub fn set_emitter_position(&self, position: Vec3) { pub fn set_emitter_position(&self, position: Vec3) {
self.sink self.sink.set_emitter_position(position.to_array());
.as_ref()
.unwrap()
.set_emitter_position(position.to_array());
} }
} }