Fix crash due to reentrancy in AudioStreamPlayer* finished signal.
This crash occurred when an audio stream finished playing in NOTIFICATION_INTERNAL_PROCESS, during which it would iterate through a loop of playbacks, leading to a "finished" signal, which removed the audio player from the tree which led to a NOTIFICATION_EXIT_TREE, which would mutate the array of playbacks while within the above loop. This moves the signal callback outside of the loop which avoids the crash. Note: previously, the signal was called multiple times if the same player finishes multiple times in one frame. Now it is at most once per frame. Affects AudioStreamPlayer, AudioStreamPlayer2D and AudioStreamPlayer3D
This commit is contained in:
parent
d3547be9ae
commit
c088a2dd89
|
@ -78,7 +78,6 @@ void AudioStreamPlayer2D::_notification(int p_what) {
|
|||
Vector<Ref<AudioStreamPlayback>> playbacks_to_remove;
|
||||
for (Ref<AudioStreamPlayback> &playback : stream_playbacks) {
|
||||
if (playback.is_valid() && !AudioServer::get_singleton()->is_playback_active(playback) && !AudioServer::get_singleton()->is_playback_paused(playback)) {
|
||||
emit_signal(SNAME("finished"));
|
||||
playbacks_to_remove.push_back(playback);
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +90,9 @@ void AudioStreamPlayer2D::_notification(int p_what) {
|
|||
active.clear();
|
||||
set_physics_process_internal(false);
|
||||
}
|
||||
if (!playbacks_to_remove.is_empty()) {
|
||||
emit_signal(SNAME("finished"));
|
||||
}
|
||||
}
|
||||
|
||||
while (stream_playbacks.size() > max_polyphony) {
|
||||
|
|
|
@ -292,7 +292,6 @@ void AudioStreamPlayer3D::_notification(int p_what) {
|
|||
Vector<Ref<AudioStreamPlayback>> playbacks_to_remove;
|
||||
for (Ref<AudioStreamPlayback> &playback : stream_playbacks) {
|
||||
if (playback.is_valid() && !AudioServer::get_singleton()->is_playback_active(playback) && !AudioServer::get_singleton()->is_playback_paused(playback)) {
|
||||
emit_signal(SNAME("finished"));
|
||||
playbacks_to_remove.push_back(playback);
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +304,9 @@ void AudioStreamPlayer3D::_notification(int p_what) {
|
|||
active.clear();
|
||||
set_physics_process_internal(false);
|
||||
}
|
||||
if (!playbacks_to_remove.is_empty()) {
|
||||
emit_signal(SNAME("finished"));
|
||||
}
|
||||
}
|
||||
|
||||
while (stream_playbacks.size() > max_polyphony) {
|
||||
|
|
|
@ -45,7 +45,6 @@ void AudioStreamPlayer::_notification(int p_what) {
|
|||
Vector<Ref<AudioStreamPlayback>> playbacks_to_remove;
|
||||
for (Ref<AudioStreamPlayback> &playback : stream_playbacks) {
|
||||
if (playback.is_valid() && !AudioServer::get_singleton()->is_playback_active(playback) && !AudioServer::get_singleton()->is_playback_paused(playback)) {
|
||||
emit_signal(SNAME("finished"));
|
||||
playbacks_to_remove.push_back(playback);
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +57,9 @@ void AudioStreamPlayer::_notification(int p_what) {
|
|||
active.clear();
|
||||
set_process_internal(false);
|
||||
}
|
||||
if (!playbacks_to_remove.is_empty()) {
|
||||
emit_signal(SNAME("finished"));
|
||||
}
|
||||
}
|
||||
|
||||
if (p_what == NOTIFICATION_EXIT_TREE) {
|
||||
|
|
Loading…
Reference in New Issue