But where to put you?

I’ve been writing programs with Qt since the Qt 3 era, and when I made my first Qt 4 programs available for general use I added cross platform support. One thing that entails is storing user data files in different locations on different platforms. At the time, I couldn’t find any way in Qt to do that, so I ended up writing this in CuteMaze:

QString homeDataPath()
{
#if defined(Q_OS_MAC)
    QString path = QDir::homePath() +
        "/Library/Application Support/GottCode/CuteMaze";
#elif defined(Q_OS_UNIX)
    QString path = qgetenv("XDG_DATA_HOME");
    if (path.isEmpty()) {
        path = QDir::homePath() + "/.local/share";
    }
    path += "/games/cutemaze";
#elif defined(Q_OS_WIN32)
    QString path = QDir::homePath() +
        "/Application Data/GottCode/CuteMaze";
#endif
    return path;
}

I’ve never been happy with that code. For one thing, it uses platform specific code in a platform independent codebase, which limits the number of supported platforms to those I can easily test myself. Thankfully, I will notice any bugs I introduce in one platform but not the rest, since I build my programs on those platforms.

However, I was recently made aware of the fact that CuteMaze would not compile on less common platforms, and that piece of code was one of the reasons. I figured that this was a chance to improve said code, so I went looking to see if there is a better way to write… and there is! After I released CuteMaze, a new class for desktop integration was added to Qt. The above code would be better written like this:

QString homeDataPath()
{
    return QDesktopServices::storageLocation( QDesktopServices::DataLocation ) + "/CuteMaze";
}

The above functionality was added in Qt 4.4. Instead of using it, I have been dragging the messy and inferior code from project to project. Obviously I don’t re-solve every problem I come to, I remember what I have done or what I have read about. It’s only natural I will miss things when reading about new versions of Qt.

Now that I know about this, I am going to use the new code for the platforms not already supported. In future projects I will use only the new code, but I don’t want to go through the headache of moving all of the user data files for all of my current projects.

Advertisements

Thoughts about version numbers

I’ve wanted to talk about this for a while now; I don’t understand why so many open source projects don’t give their programs a “1.0” moniker. Are they afraid of it? A program isn’t done when it reaches that! I think that that specific version number just means that it is the first version that you consider usable and stable for the general public. Every program gains new features after its 1.0 release.

A great example of this is digiKam. I’ve been using it for years to manage my photos and never once had it crash or lose data, and yet they just made a 0.10 release for KDE4. Why isn’t that program well past 1.0? I give all of my programs a 1.0.0 version number when I consider it ready for general consumption, not when I consider it “done”. There may be a big feature you want to add to it, sure. But that’s why you have releases after 1.0.

On the other end of the extreme, there are projects who seem determined to pad their numbers as much as they can. For example, Ubuntu uses a date based approach — they use the last two digits of the year followed by the month to make it look like a regular version number. So you go from a starting version of 4.10 to the current release of 8.10. Why not just go with the full date like so many other distros? Then it wouldn’t look so much like version number padding.

A logical and simple alternative to the date format is simply counting the releases. An example of this is Fedora. The first release was in the tail end of 2003 and the current release is version 10. There have been 10 releases, and 10 bumps in the version number. It seems fair: if you don’t want to try and figure out if the features require a version bump, and you don’t simply want to follow the date, just incremenent the version number with each release.

When I put CuteMaze online I hadn’t thought that much about version numbers. If I was to do it now, I would have worked on it a bit longer and made a 1.0 release. I just think that the first “release” should be 1.0, not 0.1; if it’s stable enough to release, it’s stable enough for “1.0”. This is, of course, assuming that you are not releasing it from the very beginning of the project for testing purposes.

Repositories

I’ve worked with a few different source control systems in the past, but none of them have really clicked with me. My projects are usually small, they don’t have much history, and I’ve been the only work working on them, so I haven’t had them in any source control systems. But now that they are online, I really should change that.

So I have changed that! DreamHost supports subversion repositories, but I’m not a huge fan of subversion. I wouldn’t want there to just be one central location for the repository — what happens if it goes offline? And who says that my repository should be the only one? That doesn’t fit with the whole open source mindset. Sure, I started these projects, but other people are free to pick them up and run with them in different (and even incompatible) directions.

Instead, I have chosen git, which really embodies that attitude. I didn’t feel like setting up the public repositories myself, so I am using github. Plus, github make it very easy for someone to fork one of my projects and start their own version.

With all of that said, you can find my repositories here.

Watch that tango!

Wife: Dancing lynx? That would be really cute. Of course, they’d have to get fitted for special little shoes, if they were going to be, like, tap-dancing or anything. Still…

Me: It’s links. With an “i”.

Wife: Yes, I know that, but it would be much cuter if it was a bobcat.

Me: And less useful.

 

Yesterday I implemented the Dancing Links algorithm. I first heard about it a few years ago after I wrote a simple Sudoku game. I didn’t write a version back then because I had tired of writing Yet Another Sudoku Game, and my game languished and was forgotten. This time, however, my current project could benefit from it.

It is a surprisingly easy algorithm to write. With the way people talk about it — and with some of the implementations I have seen — I was expecting it to be a long, drawn out battle to get it done. Not so! It was the work of maybe a few hours to read about it and get it completed. Now I just need to see if it will work for my purposes. 😛