I’m programming in a very static environment and would like to generalize the problem/code in the best way possible, to make it clean and avoid any boilerplate code. This is my case; I’m developing a modification system which sits between the program and the extensions, where the extensions will be forwarded the API calls. When my modification gets loaded by the program, I receive a pointer to a table consisting entirely of function pointers.
struct APITable
{
void (*MouseClick)(int, int);
void (*MouseLeave)(bool);
int (*MouseRet)(float, int);
// And about a 200 more
// ......
};
In this function I set the callback functions/pointers, to point at my own (i.e apiTable->MouseClick = &MyMouseClick;). I’m trying to extend this framework (since it only allows one modification at a time) to support multiple plugins. This is done by loading additional plugins (as libraries) and then forward all callbacks (such as MouseClick) to the loaded plugins. This is an example;
void MyMouseClick(int x, int y)
{
bool blockOriginal = false;
// Iterate over all plugins
if(plugin_function_is_defined_pre)
blockOriginal = call_plugin_callback_pre(x, y);
if(!blockOriginal)
EngineMouseClick(x, y); // This is the programs "engine" function, which I have to call if I want normal execution flow
// Iterate over all plugins
if(plugin_function_is_defined_post)
call_plugin_callback_post(x, y);
}
This is a very simplified procedure but I think it tells everything that needs to be told. Since I have over 200 functions there’s no way I would copy and paste all this boilerplate code. The normal procedure would probably be a #define, one for void functions and one for functions with a return value. Although this works, I would definately prefer another solution (which might not be possible since C++ is a statically typed language).
The point is; I want to generalize this procedure in a clean and efficient way avoiding any boilerplate code. Worth mentioning is that the functions may override the original functions return value, in callbacks not declared as void.
So to strip it to the bones: Program->MyExtension->Plugins&Engine
NOTE: I do not want to use any language but C++, and will use C++11 features if necessary!
EDIT: In case of interest, this is how my modification gets loaded by the program:
extern "C" ModLoad(APITable * apiTable)
{
apiTable->MouseClick = &MyMouseClick;
apiTable->MouseLeave = &MyMouseLeave;
// And so on
// ...
}
If only C++ had a statically-typed way to write generic code that can be customised for different parameters, maybe some kind of template facility? 😉
N.B. I have no idea how you intend to handle return values or what
blockOriginalor the callbacks are meant to do, so this is just a sketch.(Two function templates are needed because the one returning void has a different body, it can’t declare
resto be typevoid.)