GSoC 2020: Tree Model - Week 5

Posted 11 months ago

Hi! This week I have been working on fixing the problem that I described in my last blog, i.e. newly added measures not getting included in the tree.

Some of the things I tried to fix the problem:

  1. First of all, I wanted to confirm that the problem is just due to these new Measures, so I tried to add the newly created measures to the tree in an ad-hoc way. I created a set in Score class, called unaddedMeasures and added each Measure to this set in the constructor, and removed it from the set as soon as it was added to a system. These newly created measures were added to the children of the score class.

    At first, this wasn't working, due to a small bug in my code, but when I tried it again for the second time the test tst_unrollrepeats passed and there was no other problem too.

  2. Meanwhile, I also tried using the same logic for scanElements as before, not scanning the Measures from System and scanning them through the linked list in Score::scanElements.

    This one also worked, but I am worried that if we go with this method, the tree would remain incomplete. If we use the tree later on for some other purpose, we might face the same problem with the new measures there too.

  3. As suggested by my mentor, I tried putting the new measures into systems, as soon as they are put into the score, even if a layout is not done yet. I tried assigning them arbitrarily to the same system as the previous Measure.

    The advantage of this method would be that the tree would always remain complete, even if doLayout() hasn't been called.

    I wasn't really sure how to do this, and what part of the code should I change. I first tried looking for all instances where a new Measure is created, then I also tried searching for all the places where setNext and setPrev were called, and I also looked at the code for MeasureBaseList which is the implementation of the linked list of measures.

    In the end, I found that the easiest way to achieve this would be to modify setPrev itself, so that m->setPrev(e) would also add m to the same system as e.

    So after this small change, tst_unrollrepeats was passing.

 //   setNext
 void MeasureBase::setNext(MeasureBase* e)
     _next = e;
 //   setPrev
 ///   Sets _prev measure, and if the current one doesn't
 ///   have a system but the prev one does, then adds it
 ///   to that system. This is so that a new measure is
 ///   not left out of the score tree.
 void MeasureBase::setPrev(MeasureBase* e)
     _prev = e;
     if (!system() && _prev && _prev->system()) {

However this seems to have caused some problem with two other tests, one was tst_measures and another was tst_mxml_io. Both of these seem to have some problem with multi measure rests. I was able to fix tst_measures but I'm still working on fixing the musicxml tests.

Apart from this, I have also been working on the old scanElements function. I have identified some classes which still had some extra logic to check for visibilty, which got missed in the previous tests. I have made a todo list of those and I'll soon add that back to the new scanElements.

Also, I don't know why but the vtests are showing slight differences from the reference images, so I'm also working on investigating that issue.

TODO for this week

So here's the work I hope to complete this week:

  1. Fix problem with tst_measures and tst_mxml_io.
  2. Fix vtests.
  3. Add custom logic for visibility back to new scanElements in some classes.
  4. Mark PR as ready for review.


Pull request in GitHub:
Experimental branches: first second
Previous Blog:…
Next Blog:…