Sharpen Your Axe
Posted by Patrick on Monday, March 07, 2011Mon, Mar 07, 2011
c/c++
qt
tools

Since the release of Swivel, I've taken a bit of time to let myself unwind from the development cycle and dwell on what I want to work on next. I've decided on a new project that I'm really excited to get into, but before I do, I need to do a little work on my tools.

Abraham Lincoln said, “If I had six hours to chop down a tree, I'd spend the first four hours sharpening the axe.”

Picking the right tool for the job is, of course, important. And the need for a custom tool arises frequently. I ran into that twice with Swivel.

The first was my texture atlas generator — a fairly simple tool, and there are a few options out there, but I had custom requirements which warranted writing my own.

The second was, in retrospect, a huge exercise in “yak shaving”. For those who have not heard the term, it refers to a series of useless or prolonged activities undertaken in the name of accomplishing some other task.

To be honest, it's nothing more than a glorified form of procrastination

The yak shaver does much, but accomplishes little.

The yak in question was my font packer. Unfortunately, I let my inner designer trump my inner project manager and it insisted that Swivel have double layered fonts just so I could get two outlines and other things I probably didn't really need. This resulted in me wasting a lot of time writing my own font generator.

Anyhow, for my next project I am simplifying my font requirements to cut that out. I'm also anticipating being a lot tighter on texture space, so I'm rewriting my texture atlas packer. See my last post for more on texture atlases. I would use an external tool like Zwoptex but I do have a need it does not address.

So this will probably be the third or fourth time I'm rewriting this tool. This time I'm taking a slightly different approach.

First, I'm going to use Archivist to save the atlas manifest which will include images, sprites and fonts. This is actually a simplification. In my book, anything that lets me delete swaths of code is a good thing.

Second — and this gets into the topic for today — I'm putting aside my own library and using an external framework to write it with: Qt.

Qt is a cross-platform C++ application and UI framework.

It seems like people either know all about Qt or they've never heard of it. Those that have heard about it have probably dismissed it for one reason or another. Back in the day, it was licensed with either GPL or an expensive commercial license. If that drove you away, you may be interested to learn they have since been bought by Nokia and changed their license to LGPL, which makes it okay to use in commercial ventures.

In my experience, Qt is awesome for writing tools rapidly. It is extremely well documented, has a ton of functionality, is very mature, has good Mac support and is frequently and actively updated.

One thing that drives some people away is that it has its own preprocessor, called moc, that handles their C++ extensions. Yes, they decided to extend C++ (really?!)

But what they fail to tell you is: you don't need moc and you don't need their C++ extensions.

Here is what I do: I create a clean C++ console application in Xcode, I install their Mac binary package and use two of their frameworks: QtCore and QtGui.

By the way, if you try this you'll probably have to add “/Library/Frameworks/QtCore.framework/Versions/4/Headers” and “/Library/Frameworks/QtGui.framework/Versions/4/Headers” to your header search paths.

QtCore contains, naturally, their core classes. Quite a few useful things in there: containers, strings, regular expressions and file handling. QtGui contains their UI stuff which I don't really use, but also contains classes for dealing with images and graphics rendering, vector graphics, etc. This I use extensively.

I wrote Swivel's font packer in Qt because it has pretty good font rendering and metrics support. That was my first real introduction to the framework.

Since then, I've written a few little command-line tools in it and always found the experience pleasant. It's fast and good for rapid development. I rarely run into a situation where they don't have a feature I need so I don't have to write a lot of boilerplate code just for a simple tool.

This all results in much less yak shaving.

But what I really want to get across is that you should leverage external frameworks whenever possible, especially for tools and use-once-and-throw-away applications.

Most of us suffer from not invented here syndrome. I know I certainly do. While a certain amount of yak shaving is inevitable, it's worth expending conscious effort to keep it to a minimum.

Originally, I used my own game library to write my atlas packer since it had some of the functionality I needed and I figured the code sharing would be a good thing. But, truth be told, it became a bit of a pain to manage, and my code is designed and optimized for writing games, not tools. I found myself writing lots of support code not required for a game.

The rewrite of my tool (dubbed PackRat) is cleaner and performs better.

An added benefit is that I can release the code. My game engine is in constant flux and I can't ever seeing myself supporting it as public code — though I do publish snippets from time to time.

So, the takeaway: If you can use an existing product, do, but if you need to write a simple tool, I suggest you use a mature external framework, be it Qt, Cocoa or something else you're more familiar with. Sometimes it's easier and faster to write something in Ruby or Python. Ultimately, the less code you have to write, and the less time it takes, the better.

Do you know of any other good frameworks for writing tools? I'd love to hear about it. Please share your go-to favorites in the comments.

This post is part of iDevBlogADay, a group of blogs by indie iPhone developers featuring two posts per day. You can subscribe to iDevBlogADay through RSS or follow the #iDevBlogADay hash tag or @idevblogaday on Twitter.