Page 1 of 1

Stateful callbacks...

Posted: Sun Jan 04, 2009 6:08 pm
by Izhido
Hello!

The recent release of libnds went with many cool changes in the way things are handled. Some of them even include the possibility of registering callback functions to customize the behavior of the new functionality.

It's about the callbacks that I want to talk right now. For us C++ developers, using callbacks the C way almost always means we have to use, either global variables, or singletons, for making the callback functions do something useful for us. While not bad *per se*, we sometimes feel uncomfortable adding "global" stuff in programs that usually do not need it.

This has been tackled in many ways in the different frameworks that I have had the chance to work with. My favorite way, thus far, is including a "state" parameter as part of the callback declaration:

Code: Select all

void VBlankHandler(void* state);
that is to be specified at the moment of registering the callback function:

Code: Select all

   VBlankHandlerClass* vbh = new VBlankHandlerClass( /* ... */ );
   /* ... */
   irqSetHandler(IRQ_VBLANK, VBlankHandler, vbh);
This way, the program doesn't have to rely on it's own globals of any kind to do its work:

Code: Select all

void VBlankHandler(void* state)
{
   VBlankHandlerClass* vbh = (VBlankHandlerClass*)state; /* ... or your favorite way of casting */
   vbh->DoSomething( /* or other */ );
   /* ... */
}
I think that will help many of us to write better code. I know that it will for me. What do you think? Does it sound like a good suggestion?

- Izhido

Re: Stateful callbacks...

Posted: Sun Jan 04, 2009 6:47 pm
by StoneCypher
Ew.

Prefer a lone singleton which manages all the hooks at once. There's no reason for 14 UDTs, 14 class instances and 14 constructions to handle a single, permanently unchanging bank of registers, and the relationship between the interrupts would be clearer if they were each managed by a member function from said handler class. Provide one getter, one setter and one enable toggle per interrupt, plus a toggle for IME and for the display register interrupt control flag, and you're golden.

Minimalism is tricky.