Quirky APIs

I don't like quirky, idiosyncratic APIs. I really, really don't like them. They're harder to learn, more prone to bugs, and altogether not fun.

So naturally, I put a lot of effort into making Rubygame's API as consistent as I can. Sometimes, though, I have the unfortunate task of trying to create a consistent Rubygame API on top of a quirky library, and things get tricky.

SDL_gfx was an example of this early in Rubygame's development. Small things, like one function having a lowercase letter where all the others like it had upper case. Or one type of shape not having every drawing style that the others do.

Right now, though, it's SDL_mixer and its weird little idiosyncracies that I'm wrestling with:

  1. For Mix_PlayChannel, passing 0 for the number of loops means to play the sound 1 time (repeat 0 times), and passing 1 means to play it twice (repeat 1 time). But for Mix_PlayMusic, passing 0 means play the music 0 times, and passing 1 means to play it once!
  2. Worse, you can't just blindly offset the loops variable by 1 to make them consistent, because in both cases, passing -1 means to repeat forever. So, you have to test if it's -1 before offsetting.
  3. Mix_SetMusicPosition does different things depending on whether you're playing an Ogg Vorbis, MP3, or MOD file. (And if you were hoping to use this function with the other music formats SDL_mixer can load... well, tough break.)
  4. Mix_RewindMusic apparently doesn't work for WAV files at all. (Don't ask me why not, I have no clue.)
  5. Mix_ResumeMusic is safe to use even on music which was stopped or is already playing, but the docs for Mix_PauseMusic suggest that function shouldn't be used on music which is stopped or already paused.

And the thing about library APIs is that you can't change them later. Not without breaking the applications that use that library, that is. So I don't expect SDL_mixer to get better soon.

But, it's my task to turn the quirky API I'm given into something consistent... even elegant, if I can manage it.


Have something interesting to say about this post? Email your thoughtful comments to comments@rubygame.org.