Fix semi-infinite loop in PlaybackModel (and an assertion) when opening a certain MusicXML score #23339
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Resolves: #23276
Check whether string is empty before calling
.back()
This fixes an assertion failure.
Actually it should be
!m_wordsText.empty() && !rawWordsText.empty()
, but!rawWordsText.empty()
implies!m_wordsText.empty()
, so checking only!rawWordsText.empty()
suffices.Only check for measure repeats once per staff
The score from Memory leak upon opening MusicXML file exported from Sibelius #23276 contains a weird situation: notes in voice 2, while there is a measure repeat sign in voice 1. And that repeated for the entire score.
The playback model would render a measure repeat in two situations: 1) when finding one 2) when a segment's measure turns out to be a measure repeat measure. "Rendering" means here that it looks back at the previous measure and renders that to the location of the measure repeat.
So, for measure 2 of that score from that issue, it would first encounter the measure repeat element and render playback for it, and thus for the voice 2 notes, it would notice that their measure is a measure repeat measure and thus render the measure repeat again. So, we re-look at measure 1 twice.
For measure 2, that was just a bit wasteful, but on the other hand not catastrophic. Where it gets exciting is beyond measure 2. Measure 3 contains the same situation as measure 2. So, for measure 3, we look back at measure 2 twice. But for each time that we look at measure 2, we look twice at measure 1. So, now we look 4 times at measure 1! And it only gets worse from here; exponentially worse, to be precise.
We solve this by only checking whether the current measure is a measure repeat once per staff, i.e. at the first voice. This way, we're back in the linear world. (Well, rendering the n-th measure now takes linear time, so rendering n measures takes quadratic time.)