Key to QWERTY

Recently on the Twitterwebs, Peter Hosey asked for a library that takes a character and returns the corresponding virtual key code (implicitly, in the U.S. keyboard layout). The intention was to use it to specify default key bindings when binding to physical keys rather than characters.

Now personally, I like to specify my defaults in plists, and if I was hard-coding them I’d use an enum. However, I thought of a mildly amusing implementation, so I wrote it (MIT/X11 license). It turned out to be less interestingly ugly than I expected, but did give me an opportunity to play with __builtin_constant_p(). This means that (if you’re using gcc) KEY_FROM_QWERTY_BODY(ex), where ex is a constant expression, will itself be a constant expression, and if ex is otherwise known at compile time to be constant (e.g. a locally-defined const int, which is not a constant expression in C) it will be constant-folded; in other cases, a function call will be generated.

Also included is code to generate the header, specifically the big ?:-based expression that does the work, using whatever keyboard layout happens to be active. Note, however, that the current implementation only includes keys that generate a single ASCII character, and skips dead keys. It includes capital letters as aliases for their lowercase equivalents, but not other shifted keys.

Conveniently, I’ve also written a library to get a display string for a virtual key code. That one does use the user’s current keyboard layout.

Posted in Code | Leave a comment

Hacking your Log Messages

More nasty code inspired by IRC conversations, but this time aimed at the iPhone SDK – although it will work on Mac OS X as well, and on WebObjects 4 for Windows NT, and probably on at least some flavours of NextStep. Simply drop this file into your project, and all NSLog() output will be redirected to stdout, using a private but documented Foundation function.

Why would you want to do that? Ahh, well, that part is covered by the iPhone SDK NDA. Lawyers, eh? It must be a pretty good reason, though, given testimonials like this.

Posted in Cocoa, Code | Tagged , , | 5 Comments

Property List Extractors

Continuing a theme of tearing out useful bits of functionality from Oolite, and inspired by recent Twitter exchanges with Craig Hockenberry and Rainer Brockerhoff, here’s some really boring code for you all – gruntwork that you don’t want to repeat, but should probably be using.

Executive summary for people who don’t like rambling anecdotes: property lists and user defaults should always be type-checked, and this makes it easy.

Oolite is highly moddable, with over 150500 expansion packs. Most of them are interoperable, and typically many will be in use at once. Essentially all of these contain property lists, generally written by hand by non-programmers, often on systems without plutil or Property List Editor. As such, many contain parse errors or structural problems.

Previous versions of Oolite blithely ignored the imperfections of mere humans. Unparseable property lists were effectively ignored, leading to unexpected behaviour, often quite subtle. Structural errors, however, caused exceptions, most of them seemingly at random.

The current test releases address the syntax issues by dumping the error string from NSPropertyListSerialization and the path to the relevant file to the game’s run log. A certain amount of context-sensitive type checking is done in certain areas, such as scripting (yes, property lists are used for scripting, although that’ll be deprecated in the next stable release).

The most significant fix, however, has been to replace most uses of -objectForKey: and -objectAtIndex: with methods that check types and perform conversions where they make sense. In particular, strings are automatically converted to numbers and booleans where appropriate, which is needed to work with the more pleasant OpenStep plist syntax. When a plist value can’t be converted to the required type, or simply isn’t there, an appropriate default value is used. The game will no longer try to get keyed objects from an array, or find the first character of a dictionary. Instead of code like this:

// Hope plist has correct structure.
unsigned myMagicNumber = [[[plist objectForKey:@"someArray"] objectAtIndex:3] unsignedIntValue];

or more fault-tolerant code like this:

unsigned myMagicNumber = 0;
id array = [plist objectForKey:@"someArray"];
if ([array isKindOfClass:[NSArray class]] && [array count] > 3)
{
    id number = [array objectAtIndex:3];
    if ([number respondsToSelector:@selector(unsignedIntValue)])
    {
        myMagicNumber = [number unsignedIntValue];
    }
}

we now have code like this:

unsigned myMagicNumber = [[plist arrayForKey:@"someArray"] unsignedIntAtIndex:3];

which will not throw an exception if @"someArray" is not an array or if the array has less than four members, but will instead return 0. It’s also shorter than the broken version. Default values other than 0 can be provided in the form [array integerAtIndex:3 defaultValue:-1] or [dictionary unsignedShortForKey:@"value" defaultValue:14].

Oolite is obviously an extreme case, but many applications deal with property lists. Even more deal with NSUserDefaults, which of course is a wrapper around property lists. You may think that you know what you’re putting into user defaults and can therefore rely on it to be correctly structured, but if you’re thinking that you’re wrong. First, users will modify your preferences file, break it, and forget they did it. Second, your code is buggy. If you write any sort of collection to your prefs, there’s a chance that you’ll put an object of the wrong class there if the phase of the moon is unusual. If you don’t check it when you read it, this will cause an exception, and you’ll end up guiding a user through digging around in ~/Library to clean up your mess. Better to be fault-tolerant to start with.

So, here it is: JAPropertyListAccessors 1.2 (MIT/X11 license). It provides:

  • A non-throwing variant of -[NSArray objectAtIndex:].
  • Functions to convert objects (NSNumber or NSString) to all standard integer types, as well as float and double, clamping the results rather than overflowing, and returning a user-specified default value if no conversion can be performed.
  • Convenience methods for accessing integers, floats, strings, arrays, dictionaries, sets, or objects of a specified class from NSArray, NSDictionary or NSUserDefaults. The following transparent conversions are performed when appropriate: NSString to numbers; NSNumber and NSDate to NSString; NSArray to NSSet.
  • Convenience methods to set integers and floating-point values in NSMutableArray, NSMutableDictionary and NSUserDefaults.
  • Unit tests for the primitive conversion functions.
  • Compatible with 32-bit and 64-bit runtimes, and with garbage-collected and non-GC code.
  • Very little in the way of comments.
  • Update (version 1.0.1): Default value (rather than nil) is now returned when conversion to string fails. String conversion now uses -stringValue if available.

Posted in Cocoa, Code, Oolite | Tagged , | 1 Comment

Hacking your Crash Reports

In a conversation on #macdev, it was pointed out that the Crash Reporter has an “Application Specific Information:” line when certain Apple apps crash. This obviously warranted investigation, and through the powers of Google it was determined that said investigation had in fact happened a few months ago. How fortunate that we didn’t spend time investigating it and writing test cases, only to find someone had already done a better job.

Anyway, this is an entirely unsupported thing to do, and the means of doing it may disappear at any time, so don’t. But if you do, do it cleanly, like this:

#ifndef NDEBUG
/*  Function to set “Application Specific Information” field in crash reporter
    log in Leopard. Extremely unsupported, so not used in release builds.
*/
static void InitCrashReporterInfo(void);
static void SetCrashReporterInfo(const char *info);
static BOOL sCrashReporterInfoAvailable = NO;
#else
#define InitCrashReporterInfo() do {} while (0)
#define SetCrashReporterInfo(i) do {} while (0)
#define sCrashReporterInfoAvailable 0
#endif

/* Insert code here. Or make it non-static, depending on what you’re doing. */

#ifndef NDEBUG
static char **sCrashReporterInfo = NULL;
static char *sOldCrashReporterInfo = NULL;
static NSLock *sCrashReporterInfoLock = nil;

static void InitCrashReporterInfo(void)
{
    // Load secret symbol __crashreporter_info__; don’t do anything if not found.
    sCrashReporterInfo = dlsym(RTLD_DEFAULT, "__crashreporter_info__");
    if (sCrashReporterInfo != NULL)
    {
        // We'll need a lock, too.
        sCrashReporterInfoLock = [[NSLock alloc] init];
        if (sCrashReporterInfoLock != nil)
        {
            sCrashReporterInfoAvailable = YES;
        }
        else
        {
            sCrashReporterInfo = NULL;
        }
    }
}

static void SetCrashReporterInfo(const char *info)
{
    char                    *copy = NULL, *old = NULL;
    
    /*  Don’t do anything if setup failed or the string is NULL or empty.
        (The NULL and empty checks may not be desirable in other uses.)
    */
    if (!sCrashReporterInfoAvailable || info == NULL || *info == '\0')  return;
    
    // Copy the string, which we assume to be dynamic...
    copy = strdup(info);
    if (copy == NULL)  return;
    
    /*  ...and swap it in.
        Note that we keep a separate pointer to the old value, in case
        something else overwrites __crashreporter_info__.
    */
    [sCrashReporterInfoLock lock];
    *sCrashReporterInfo = copy;
    old = sOldCrashReporterInfo;
    sOldCrashReporterInfo = copy;
    [sCrashReporterInfoLock unlock];
    
    // Delete our old string.
    if (old != NULL)  free(old);
}
#endif

For this to be actually useful, you’d want to be using Smart Crash Reports (apparently coming soonish to a Leopardy computer near you) or something similar.

Posted in Code | Tagged , , | 2 Comments

The Mysteries of iCal, Revealed!

Note: As of Snow Leopard, this functionality has been superseded by an official Dock tile plug-in mechanism.


One of the minor yet shiny new features of Mac OS X 10.5 is that iCal’s dock icon now shows the correct date even when iCal is not running. Some assumed this to be hard-coded functionality in the dock, but a few brave souls – well, one, being me – decided to find out.The following lines in iCal’s Info.plist are a bit of a hint:

<key>DockExtra</key>
<string>iCalDockExtra.bundle</string>

iCalDockExtra.bundle can be found in iCal’s Resources directory. 90 seconds with class-dump, otool, and class-dump again show that the bundle implements a subclass of DockExtra, which in turn is defined in the private SystemUIPlugin.framework.

Having retrieved the interface declaration for the DockExtra class from class-dump, it is a simple matter to implement a subclass which logs which methods are called and when. As it turns out, the only ones called are -_initWithController: and -dealloc, but through the power of my mighty brain I worked out that I could draw the dock icon whenever I wished, using -getContext: to get a drawing context and size, -setDockImageFromContext to update the image in the dock and -releaseContext to clean up afterwards.

And that’s pretty much it. Code is here. Read the Read Me first. (The most important caveat is that the bundle is never unloaded while SystemUIServer is running.) If someone actually uses this for something useful, please tell me about it.

Edit: I thought I’d said this earlier, but apparently not: as pointed out in the comments, Alacatia Labs published the same information a week before me, and did a slightly better job too. If I had used the power of the intergoogles, I would have known that, but then I’d have missed the fun of working it out.

Posted in Cocoa, Code | Tagged , , , , | 23 Comments

A Corny Plug-in

As soon as I saw Gus Mueller’s offer of a free license for anyone writing a decent plug-in for Acorn, I felt moved to exploit his generosity contribute to the nascent plug-in community. So I quickly slapped together a possibly-useful filter, which ended up being a simple wrapper for a Core Image kernel (my first). Obviously that should be repackaged as an Image Unit. However, it did crash in a confusing way for a while, which is good, because it inspired me to write (most of) a test rig: a command-line tool which loads a given Acorn plug-in and runs each action it registers.

Then I started on a new plug-in, which is UI-centric and therefore can’t usefully be tested on the command line.

As such, the test rig isn’t ready, but the new plug-in is. It adds an Export… menu item to Acorn’s File menu, allowing the export of any file format supported by ImageIO – currently BMP, GIF, JPEG, JPEG 2000, OpenEXR, PDF, Photoshop, PICT, PNG, SGI, TGA and TIFF. Some of these are already supported by Acorn. But hey, some aren’t.

Plug-in and source code (MIT/X11 license) available here.

Posted in Cocoa, Code | 2 Comments

Priority Queue

The Foundation framework: it has some collections. It doesn’t have others.

In particular, it doesn’t have a priority queue, which I need. CoreFoundation does, but this is for Oolite so it needs to work with GNUstep. Yes, I could bring in all of CFLite, but without the toll-free-bridging it’s not particularly attractive.

Mike Ash (who seems to be getting an indecent amount of exposure in this blog, to the extent that it counts as an exposed location) wrote about the issue last year. His solution was to use the C++ Standard Template Library, but I don’t like that solution much because a) GNUstep doesn’t play nice with Objective-C++ (its headers aren’t C++-clean) and b) it’s C++.

So, as you may have guessed, I’ve gone and written one. Here it is, with the small amount of Oolite dependency ripped out. MIT/X11 license.

Operations supported:

  • Add object.
  • Add all objects in a collection (anything that responds to -objectEnumerator or -nextObject).
  • Retrieve highest-priority object. Priority is defined by a comparison method specified when creating the priority queue. Priority is defined such that the NSOrderedDescendingmost object has the highest priority; as such, using caseInsensitiveCompare: as the comparator will cause strings to be retrieved in lexicographic order.
  • Delete highest-priority object.
  • Delete specific object.
  • Delete equal object (i.e., delete one object such that the comparator returns NSOrderedSame).
  • Retrieve all objects in sorted order, emptying the queue.
  • Equality testing and (low-quality) hashing.
  • Copying of the entire queue.
Posted in Cocoa, Code, Oolite | 5 Comments

Performance Comparisons of Common Operations, PPC Edition

Mike Ash has written some microbenchmarks to test the speed of operations like Objective-C message dispatch and object creation, in response to people’s premature optimizations based on unfound assumptions. This is one of those issues that comes up rather often. The numbers are interesting – especially the Objective-C message send vs. floating point division – but I wanted some numbers for PowerPC, since ABI and hardware differences could be expected to reorder the list somewhat.
Continue reading

Posted in Cocoa, Code | 2 Comments

GLSL uniform bindings for Cocoa

Executive summary: This article demonstrates the use of Objective-C’s dynamic object model and the Foundation framework to extract attributes from objects using information not available at compile time. This is done on the context of implementing OpenGL Shader Language support in a cross-platform game.

Introduction

A major feature of the current development line of Oolite is support for GLSL shaders. Shaders need to be able to reflect the state of the object they’re attached to – for instance, by having spaceship engines glow in proportion to engine power. The mechanism GLSL provides for this is uniform variables, attributes set by the host application and read by the shader.

A screen shot of Oolite.

Debris model with per-pixel lighting and heat glow which fades over time from glow_alloy.oxp. Model by Arexack_Heretic, textures by Griff, shaders by Ahruman.

Continue reading

Posted in Cocoa, Oolite, OpenGL | Leave a comment