Friday, 8 January 2010

Widgets and function pointers

I'm currently working through the setting screens, so I needed to make a few widget classes. Basically I have a bunch of widgets which contain their position, size and some functions to determine how input is handled. Now comes the fun bit, re-using the class for different options. I wanted one widget to handle starting a new game, one for toggling collision boxes, etc.

To get this done, I used function pointers. I'd let the scene handle the interactions with the widgets and when one was invoked, it's set callback was fired.

So in the header file, I have two members, the first being the function to call, and second being the parameter to pass into the function.
 @interface WidgetButton : WidgetBase   
{
@public
void (*callback_routine)(void *data);
void *callback_data;
}

When the widget is invoked, it then went ahead and fired it's function pointer.
 -(BOOL)handleControls:(ScreenTouches*)screenTouch  
{
if( [super handleControls:screenTouch] )
{
if( callback_routine )
{
callback_routine( callback_data );
}
return YES;
}
return NO;
}

So in the case of toggling a bool on or off, in the main scene I'd create a widget and pass in the function pointer for toggling bools with the variable active.
 activateWidget = [[WidgetButton alloc] init];  
((WidgetButton*)activateWidget)->callback_routine = &toggleBool;
((WidgetButton*)activateWidget)->callback_data = &active;

Finally, the function of toggleBool would simply toggle the bool.
 void toggleBool(void *data)  
{
BOOL *toggle = (BOOL*)data;
*toggle = !(*toggle);
}

So now we have a classes which encapsulate the drawing and user interaction, but provide differing responses.