Amarok/Archives/Boring2.0Todo

From KDE Community Wiki

The purpose of this page is to serve as a TODO list for non-user visible 2.0 development and engineering. Boring stuff only! Ideas for new interfaces and such probably deserve their own pages.

Publicity

  • Perhaps use the start of 2.0 development to do some blog/dot/digg publicity in the hope of attracting developers. Perhaps just tacked on to the normal publicity for 1.4.4. DEVELOPERS DEVELOPERS DEVELOPERS

Release Engineering

  • Release 1.4.5, then put 1.4 into a branch. 2.0 development starts out in trunk.
  • As Gabór can tell you, porting to KDE4 will take a lot of work to get to even compile. I (Ian) was thinking we could divide and conqueror in IRC.
  • Have planned online developer meetings? To make decisions and to coordinate development to get Amarok back into a basically usable state ASAP.

Organization

  • Split up files - only highly highly coupled classes should be together in the same .h/.cpp files. Eg playlistbrowseritems.cpp needs to be split up into a bunch of files.
    • may I suggest adopting a classname_differentiator.* filenaming scheme eg, playlistBrowserItem_events.cpp, playlistBrowserItem_slots.cpp --Mxcl 22:22, 13 September 2006 (UTC)
      • Please don't spread classes over more than one file - this makes it harder to locate code. Instead, if the class is too large, try to redesign it into several smaller ones. --Aumuell 5:34, 14 September 2006 (UTC)
        • Yeah I agree with this myself, splitting classes up sucks because IDEs are clueless, it should only be done if a class takes a long time to build and needs rebuilding often. Frankly if a class is so big its compile time is significant, the class probably needs redesigning and splitting into multiple classes --Mxcl 17:08, 20 September 2006 (UTC)
  • may I also suggest that we name files either with camelcase, firstletter lowercase eg playlistBrowserItem.cpp, or with underscores, eg playlist_browser_item.cpp. The latter is less pretty but more readable. All lowercase names sucks and I haven't done that in my own projects for years. I really recommend we adopt one them --Mxcl
    • Hell yea, good idea. :) --Ian 03:03, 14 September 2006 (UTC)
    • If we go CamelCase, then we should go all the way: name the file exactly as the most important class, e.g. PlaylistBrowserItem.cpp - this makes it more clear. --Aumuell 5:37, 14 September 2006 (UTC)
      • Yea, it makes sense to just use the names of classes for our files. --Ian 14:22, 14 September 2006 (UTC)
      • The only reason I suggested not capitalising the first letter is that on the command line, you don't expect capitals. But this is something to discuss, I also prefer the look of proper camelcase personally.
        • Anyone who cannot work with case-sensitive autocompletion should add "set completion-ignore-case On" to his ~/.inputrc and be done with it. --Ikonst 00:52, 2 December 2006 (UTC)
  • Organize the files into directories. We could use it as an opportunity to designate systems and sub-systems, as we do with current subdirectories. Like at K3M we had the idea to have a core for Amarok with database, engine and playlist functionality.
    • I used to be a big fan of subdirectories, but to be honest, it just makes you spend too much time doing organisation, and makes other things, like editing/opening/buildsystems harder. Also as a project develops you find out you placed files wrongly, or things are different now and the directories are wrong, but people don't move the sources around so the "organisation" is actually just confusing for newcomers. I suggest, a single directory for source files and then namespacing them in the filename, eg statusbar_this.cpp, statusbar_that.cpp. --Mxcl 22:22, 13 September 2006 (UTC)
      • Well I think CVS has been training us well, renaming isn't a big deal now with SVN. And its the same issue with namespace prefixes. Personally I think even an antiquated organization would be helpful, no organization is also confusing. Personally if I'm not sure where something is I use 'find in files' just like I did when I started Amarok development, this isn't meant so much for that. We just need some organization especially as we split up and create many new files. Namespace prefixes would be good as well. Actually I might be liking that idea better, I'm not sure :) --Ian 03:03, 14 September 2006 (UTC)

[Hey you! Insert a suggested file tree for Amarok 2.0 right here]

Build System

  • Port to CMake
  • Make it possible to compile and link only amarokapp, to allevilate the long link times associated with linking all the plugins.
  • Separate metabundle into its own library, as many plugins would only have to link against it.
  • Build on Windows and Mac.
  • We should use a precompiled header that contains most of Qt and common KDE stuff. This is great for two reasons:
    • With a well planned PCH, you get super build time speedups (especially with the Windows MS compiler)
    • It means you don't lose 5 minutes every time you write a new class determining which Qt header files you've missed out.
  • The pch could be amarok.h, although I go for: #include <Qt>

Database

  • Investigate a project called litesql to address our constant issues with problems due to database schema changes and related regressions. And it abstracts postgresql/sqlite/mysql for us.
    • The disadvantage is that it hasn't reached 1.0 and doesn't work on Windows, but if its as neat as it sounds perhaps it would be worth picking this up. Database management has recently become a lot of work, perhaps doing it the "Right Way" would be beneficial.
  • On that note, take a serious look at improvements that could be made to the schema. Now is the time to make radical changes.
  • Database access needs to be made object oriented, with subclassed objects for each database implementation.
  • Should we use internal Qt database access methods?

Engine

  • Make the engine a separate process and license it as MIT/LGPL/We-don't-give-a-crap for linking against libraries that are GPL incompatible.
    • This means removing Qt dependencies from the engines.
    • I'm against this step, even if it complicates things only slightly, as this is not guaranteed to resolve the license issues: [1] --Aumuell 5:24, 14 September 2006 (UTC)
      • It does make people percieve that it resolves licensing issues, eg. this is what SUSE did with Helix. And with this crap perception is 90% of the law. Also it has some other advantages in terms of like how xine hangs Amarok when it feels like it. --Ian 14:16, 14 September 2006 (UTC)

Planning

  • We should plan the changes for 2.0 quite extensively before changing a single line of code. I'm thinking of changes to MetaBundle (make it more object-oriented) and the plugin interface.
    • Yeah you should be able to get stuff from a metabundle, like albumImage(), no more passing metabundles to DB classes. In fact I'd make the db impossible to access directly, and only via convenience classes like metabundle. Or it'd be nice to investigate. --Mxcl 22:27, 13 September 2006 (UTC)
    • I disagree somewhat. I think we should work towards a roughly feature-equivalent KDE4 Amarok before we go on to refactor. One thing at a time. That doesn't really require any designing, just coordination. But yes, before we add any new features or refactor existing code planning is a good idea. Perhaps even bust open the ole' Umbrello? Maybe some .odt design documents? Am I crazy? :P --Ian 03:08, 14 September 2006 (UTC)
      • I believe that if we throw ourselves straight into a KDE4 port, then we won't ever get around to actually redesigning and refactoring the core with the correct design patterns. The caveat is, do we have enough man power and time to do this? --Seb 04:03, 14 September 2006 (UTC)
      • I have to agree with Ian: We should separate porting from KDE3 to KDE4 from redesigning: a working Amarok is needed for testing, and this minimizes the time, where Amarok does not work. And the natural order seems to be: porting to KDE4 followed by refactoring, as Qt4/KDE4 enables us to structure the code in new ways. --Aumuell 7:46, 14 September 2006 (UTC)

Design Patterns

Ownership

  • If we make more use of object-oriented features like inheritance in 2.0 (and we should!) we have to decide on some policy to prevent memory leaks, e.g. each method which creates a new object and gives up ownership of it has to clearly state that in it's api doc. Can klockwork help us to detect calling code which doesn't delete the object?
    • This confuses me, where do we not inherit and we should? What leaks? And would QObject parent-child cleanup not suffice? --Mxcl 22:27, 13 September 2006 (UTC)

The Singleton System

  • May I introduce the The singleton system, it looks like:
  The::playlist()->doTheLocomotion();
  • The advantages are:
    • Shorter call, eg The::playlist() vs Playlist::instance()
    • Avoids problems due to stupid KDE API usage of the instance() function for eg KXMLGui (KDE FTW)
    • You can declare these all in a single header, and then if you only need playlist as a QWidget, you don't need to include playlist.h, (QWidget*)The::playlist().
      • I strongly advise against doing this: in this case, the compiler does not have enough knowledge to get this cast right in the case of multiple inheritance. And changing The::playlist() to be not derived from QWidget any longer won't hinder this code from compiling, only from working correctly. --Aumuell 5:53, 14 September 2006 (UTC)
      • I think we're all grown up enough to be able to assume a reinterpret cast on an obvious widget. --Mxcl 08:46, 14 September 2006 (UTC)
  • You make it all work like this:

amarok.h

  namespace The {
  Playlist *playlist();
  QMainWindow *mainWindow();
  etc.
  }

playlist.h

  class Playlist {
  friend Playlist *The::playlist();
  ...
  };
  namespace The {
  inline Playlist *playlist() { return Playlist::s_instance; }
  }

So the function still gets inlined.

  • You can also add other things to the The namespace, like The::action( "play" )
  • Sounds good! Seems like a find/replace operation mostly, might as well do it before 1.4.4 is released. --Ian 03:20, 14 September 2006 (UTC)
  • Why not simply rename instance() to the()? Using Playlist::the() is just as short and prevents nasty problems caused by undefined classes. --Aumuell 7:58, 14 September 2006 (UTC)
    • The-playlist reads better than playlist::the, and that you can add other things to it. Otherwise you are right, but your nasty undefined issue is a non issue as far as I'm concerned, reinterpret_cast is something you have to inevitably do and also something you do pretty rarely. --Mxcl 08:46, 14 September 2006 (UTC)
      • Its not really that nasty, it would be an easily identifiable compile-time error. And I don't really see there being much use of the (QWidget*)The::playlist() type thing, though it would be useful where it is. But thats a seperate issue. --Ian 14:47, 14 September 2006 (UTC)

Polymorphism

  • We should use far more polymorphism than we do. We do it partly with PlaylistBrowserItems, but in some cases we could have encapsulated the logic into the item classes, we used a lot of "isThis()" or "isThat()" instead. Look at PlaylistBrowser::slotDoubleClicked() for an example. Well, I could change that still on 1.4.4, I just mean we should avoid it. Some other places in Amarok could use similar approaches:
    • Database handling (in case we don't find a nice way of not handling it ourselves).
    • Collection Browser. With the logic properly encapsulated into different classes for each different kind of item, the code could be so much easier. Adding other group by options would have been much easier and regression free (anyone remembers how long, and how much effort it took us to get "Year - Album" right?)
    • MetaBundle, maybe? Having different classes for Stream, Podcasts and LastFm Metabundles, which can actually reimplement stuff like prettyTitle() and all, would be interesting, and better than the current solution (stream stuff embedded into MetaBundle itself, which holds pointers to possible Podcasts/Lastfm bundles).