Skip to content

Commit

Permalink
core: Stop sounds attached to an unloaded root movie
Browse files Browse the repository at this point in the history
  • Loading branch information
Toad06 committed Nov 8, 2024
1 parent 99f6b22 commit 1b07ddb
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 14 deletions.
20 changes: 20 additions & 0 deletions core/src/backend/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,26 @@ impl<'gc> AudioManager<'gc> {
});
}

/// Stops any sound associated with the given Display Object and its children. The DO must represent the parent.
/// Sounds associated with DOs are an AVM1/Timeline concept and should not be called from AVM2 scripts.
pub fn stop_sounds_on_parent_and_children(
&mut self,
audio: &mut dyn AudioBackend,
display_object: DisplayObject<'gc>,
) {
self.sounds.retain(move |sound| {
let mut other = sound.display_object;
while let Some(other_do) = other {
if DisplayObject::ptr_eq(other_do, display_object) {
audio.stop_sound(sound.instance);
return false;
}
other = other_do.parent();
}
true
});
}

pub fn stop_all_sounds(&mut self, audio: &mut dyn AudioBackend) {
self.sounds.clear();
audio.stop_all_sounds();
Expand Down
5 changes: 5 additions & 0 deletions core/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ impl<'gc> UpdateContext<'gc> {
.stop_sounds_with_display_object(self.audio, display_object)
}

pub fn stop_sounds_on_parent_and_children(&mut self, display_object: DisplayObject<'gc>) {
self.audio_manager
.stop_sounds_on_parent_and_children(self.audio, display_object)
}

pub fn stop_all_sounds(&mut self) {
self.audio_manager.stop_all_sounds(self.audio)
}
Expand Down
4 changes: 0 additions & 4 deletions core/src/display_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2147,10 +2147,6 @@ pub trait TDisplayObject<'gc>:
}
}

context
.audio_manager
.stop_sounds_with_display_object(context.audio, (*self).into());

self.set_avm1_removed(context.gc_context, true);
}

Expand Down
4 changes: 1 addition & 3 deletions core/src/display_object/avm1_button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,7 @@ impl<'gc> TDisplayObject<'gc> for Avm1Button<'gc> {
} else if let Some(node) = self.masker() {
node.set_maskee(context.gc(), None, true);
}
context
.audio_manager
.stop_sounds_with_display_object(context.audio, (*self).into());

self.set_avm1_removed(context.gc(), true);
}
}
Expand Down
4 changes: 0 additions & 4 deletions core/src/display_object/edit_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2413,10 +2413,6 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
.retain(|&text_field| !DisplayObject::ptr_eq(text_field.into(), (*self).into()));
}

context
.audio_manager
.stop_sounds_with_display_object(context.audio, (*self).into());

self.set_avm1_removed(context.gc_context, true);
}
}
Expand Down
8 changes: 5 additions & 3 deletions core/src/display_object/movie_clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2925,9 +2925,11 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
mc.stop_audio_stream(context);
}

context
.audio_manager
.stop_sounds_with_display_object(context.audio, (*self).into());
if self.is_root() {
context
.audio_manager
.stop_sounds_on_parent_and_children(context.audio, (*self).into());
}

// If this clip is currently pending removal, then it unload event will have already been dispatched
if !self.avm1_pending_removal() {
Expand Down

0 comments on commit 1b07ddb

Please sign in to comment.