The Joys of Wrapping your Head around Code

I never thought that I would have as much trouble understanding bugs as I just now had for a bug in JuK. First, a description of the bug is needed.

  • It only happens when using the Inline Tag Editor to edit a tag.
  • It only affects on Search Playlists (with another qualifier I’ll add later).
  • It only happens when setting a tag value to a value alread present in any of the other songs.

This bug keeps the Search Playlists that search on the tag being edited from being refreshed. So if you were to edit a song and change the tag so that it now belongs in one of those Search Playlists, it wouldn’t show up there until you somehow managed to force it to refresh (such as by adding an item).

Many, many kdDebug() statements later, I discovered that the bug doesn’t affect newly created Search Playlists, only ones loaded from disk. Turns out that what was happening is that Search Playlists are created with a so-called Playlist Observer. Whenever a playlist changes, it can call PlaylistInterface::update(), and any class which is observing it will be notified. It’s a very elegant design.

The problem is that when loaded from disk, the Search Playlists have “forgotten” what Playlists they were observing. Scott had gotten around this problem by connecting to a signal that the main playlist class (CollectionList) emits when it has changed. Since at this point in time this is also the only playlist that is ever observed, the solution worked well enough.

So it turns out that my bug was in a completely different class (CollectionList), which didn’t always emit the changed signal when the collection has changed (to be specific, it didn’t track the individual items themselves changing, just the addition or removal of them, and the addition of new tags, which was why adding an existing tag failed to refresh the list).

Whew! :-) Now that I understand this code much better, it should be easier for me to fix the bugs in automatically updating dynamic playlists, and get my retag-on-drag-and-drop code in CVS.