GSoC 2020 Week 1 BC (Before Coding): Under-the-Hood Changes

Posted 1 month ago
Previous post Next post

Last week, I was in a conference call with the other MuseScore GSoC students and mentors, where we mainly discussed the challenge of minimizing conflicting code changes (both among ourselves and between us and the core team). We could work in three different directions all summer, happily oblivious to each other, and find out in three months that it's impossible for all three of our projects to be merged at once. Or, we could submit our work frequently as we progress, piece by piece, so that the repository we're all working on can be incrementally updated throughout the summer, and we can rebase on top of each other's work along the way. We were advised to do the latter.

So, immediately following the call, I opened my first WIP pull request:

The PR contains three commits. None of them extend MuseScore's abilities in any way. However, each one makes some changes that were going to be necessary at some point.

Rename local variables and add comments in createMMRest()

It used to be that only a few people developed MuseScore. Much of MuseScore's code was written by, and for, a handful of people who intimately understood it, and they didn't need to put much effort into reminding themselves how the code they wrote worked. Now that MuseScore has grown so much, this can make it complicated for people who aren't already familiar with the code when they look at it. I spent some time studying just one function, Score::createMMRests(), and mostly renaming variables so that next time it will be easier to read (for me, in the coming weeks, and for anyone else in the future).

One example: there was a variable of type Segment* called "ss" (unfortunately, it is a very common practice in MuseScore's code to create variables that are only named with one or two letters). I renamed the variable to say what it was: "lastMeasureEndBarlineSeg".

Add class MMRest and ElementType::MMREST

It's a good practice in object-oriented programming to not let types get too generalized. For instance, in MuseScore, notes and rests have a lot in common, but they are distinct: there is a class called ChordRest that has some of the basic shared code, and then two separate child classes Note and Rest that have the more specific code. I will be adding a lot of code specific to multimeasure rests, and I don't want to make the Rest class too huge. So last week I moved everything related to multimeasure rests out of the Rest class and into a child of Rest, called MMRest, instead. I also created a separate ElementType, MMREST.

Unfortunately, this made it impossible for MuseScore to open scores with the old kind of multimeasure rests. That is what I want to figure out this week. Once that is fixed, I hope the PR will be merged.

Add new Style page

This was very simple. Since I will be adding more style options for multimeasure rests, I need a place to put them in the UI. I moved the existing options to a new page of the Style dialog, and made sure that the context menu for multimeasure rests will direct users to that page. I named it "Rests," rather than "Multimeasure Rests," because, after all, a multimeasure rest is a kind of rest, and I foresee a time when there are also style choices for regular rests.

Previous post Next post


Good job!

Regarding rest style setting - one that's a good candidate already has to do with vertical displacement in a multivoice context. So far we've always used a fixed offset that works sometimes but isn't enough at other times. There is a pending PR to automatically apply a larger offset where necessary - But probably it would be good to have further control here.

Regarding reading the old-style mmrest, the key question to answer is whether you actually need these new mmrests to be written differently than the old. I'm kind of guessing the answer will turn out to be "no", that there would be no reason the MMRest class couldn't just write the normal Rest tags to the file and add a few unique properties. Kind of like how all the subclasses of TextLineBase write their own properties but use TextLineBase (or, more generically, Line) to write the common stuff, and the same on read. So I'd look to, for example, the Ottava class for inspiration.