Objective-C Reflection

For glDebug I generate a lot of code so save having to write and update it, both for the call intercept library, and the application.¬†More recently in the application, I’ve added an event list similar to the one in PIX where it shows the parameters.
Screen Shot 2014-04-28 at 04.37.46

So to generate this, I generate an overload of my base command class for every method, and changing the description function to return based on the parameter type and function name.

Then to create the class, I just get the class by the function name prefixed with “GLDebug_”.

Class createClass = NSClassFromString([NSString stringWithFormat:@"GLDebug_%@", commandName]);
 
//
if(createClass == nil)
{
	createClass = [CommandData class];
}
 
//				
CommandData * commandData = [[createClass alloc] initWithPacket:packet];

Now in my outline view I can just use the description string. One limitation however is I want to replace GLenum with the correct enum string. However it appears there are some enums sharing the same name. I may need to generate a spreadsheet and fill out the enums manually.

Intercepting Objective-C Calls

Continuing on from my previous post about capturing OpenGL calls in C, I now needed some method to intercept the creation and destruction of contexts. While this is easy for the CGL library since it worked the same as intercepting the OpenGL calls, this wasn’t as easy as I thought it would be for NSOpenGLContext.
Screen Shot 2014-04-27 at 17.56.11 1
I eventually found a C methods for retrieving and replacing objective-c functions with C functions, I think they were class_replaceMethod and class_getInstanceMethod. However this was flawed, every so often I would run the application and permission errors from the operating system, crashing the program.

And even when they did work, I was unable to replace the dealloc method without getting a recursive feedback.

But while reading about these methods, I came by another method that involves not replacing a call, but exchanging it for another. So I wrote a class extension for NSOpenGLContext, with my own variations of the methods I wanted to intercept. Luckily, dealloc just worked for the extension and did not required swizzling.

@implementation NSOpenGLContext (glDebug)
 
//
- (id)init_glDebug_WithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share
{
	NSLog(@"initWithFormat:shareContext: intercepted\n");
	return [self init_glDebug_WithFormat:format shareContext:share];
}
 
//
- (id)init_glDebug_WithCGLContextObj:(void *)context
{
	NSLog(@"initWithCGLContextObj intercepted\n");
	return [self init_glDebug_WithCGLContextObj:context];
}
 
- (void)dealloc
{
	NSLog(@"Dealloc intercepted\n");
}
 
@end

While this fixed the recursive problem, I still occasionally received permission errors. And while googling for the answer, I found that objective-c classes have a static +(void)load method that the code was suppose to be put in, not the library constructor.

@implementation NSOpenGLContext (glDebug)
 
//
+ (void)load
{
	[NSOpenGLContext swizzleMethod1:@selector(initWithCGLContextObj:)
						withMethod2:@selector(init_glDebug_WithCGLContextObj:)];
 
	[NSOpenGLContext swizzleMethod1:@selector(initWithFormat:shareContext:)
						withMethod2:@selector(init_glDebug_WithFormat:shareContext:)];
}
 
//
+ (void)swizzleMethod1:(SEL)inOriginal withMethod2:(SEL)inSwizzled
{
	Method originalMethod = class_getInstanceMethod([NSOpenGLContext class], inOriginal);
	Method swizzledMethod = class_getInstanceMethod([NSOpenGLContext class], inSwizzled);
	method_exchangeImplementations(originalMethod, swizzledMethod);
}
 
//
+ (void)swizzleStaticMethod1:(SEL)inOriginal withMethod2:(SEL)inSwizzled
{
	Method originalMethod = class_getClassMethod([NSOpenGLContext class], inOriginal);
	Method swizzledMethod = class_getClassMethod([NSOpenGLContext class], inSwizzled);
	method_exchangeImplementations(originalMethod, swizzledMethod);
}
 
@end

This worked great and I haven’t had any troubles since.

Catalyst

Catalyst Title Screen

Whilst working on animation support for Athena for Courage, I began working on a game for the iPhone called Catalyst last weekend.

I was thinking about a game I had played about a month or two before called Polygonal Fury, and realised it would port nicely onto the iPhone.

Catalyst - A circle explodesSo I started a OpenGL ES project (and discovered the new version of the iPhone supports shaders), and started with just making some circles bounce around.

Since the collision of a circle is easy, they seems the easiest to setup for interaction with touching the screen.

Catalyst - A chain reactionInitially I just made them “die” if tapped, but later I added the ability of shapes to spawn reactions.

All sprites within the game are triangle fans, but I will probably change them to quads with a texture due to the break that occasionally appears in the geometry, and alpha glow around the edge.

Catalyst - Still three "clicks" leftIt is not much, but it is a start, I plan to add some more particle types, and maybe a few different upgrades than the ones giving in the Flash version.

The background needs changing, I was thinking of something going on in the background like in another Flash game I played, Spewer, with maybe cut scenes like the Nintendo DS game Contact had.