Is this a safe pattern for auto-registration?
Hey,
I’m trying to have various components in my game pre-register themselves upon startup of the game. I’m using this pattern:
Here’s my registration code that is in one .cpp file. The register_init() function is available from anywhere:
std::vector&get_init() { static std::vector goods; return goods; } bool register_init(Init *v) { get_init().push_back(v); return true; }
Here’s how I auto-register some init code from some other file by calling register init to initialize a variable:
int _is_levedit_init = register_init(new LeveditInit());
Is there some case where this would NOT work or is somehow a really bad idea? Or is there some pattern that is better to use?
-Phil
October 26th, 2011 at 12:10 pm
I think it should work just fine. As another approach for auto registration I saw, it was usage of intrusive list and adding current object to the list in constructor.
October 26th, 2011 at 12:11 pm
After a bit of thought, this all seems like a misguided idea.
This seems much safer and more predictable. It’s not “automagic” but it requires less keystrokes to attain the same effect. So that’s more of a win in my book.
#define DOINIT(v) void v##_init(Game &g);v##_init(g);
void game_init(Game &g) {
DOINIT(levplay);
DOINIT(levedit);
}
October 26th, 2011 at 11:12 pm
That would be my suggestion as well. Way easier to manage an explicit list of system inits in one place. Both for dependencies and code clarity, I think your second solution is much better.
October 26th, 2011 at 11:19 pm
Actually, one change I’d suggest is this:
#define DOINIT(v) void v(Game &g);v(g);
void game_init(Game &g) {
DOINIT(levplay_init);
DOINIT(levedit_init);
}
… So when you search the code for levplay_init, it has two hits: the function itself and the call from game_init. Otherwise at some point in the future (speaking from experience here), you’ll spend a few moments confused about why your levedit_init function isn’t referenced from anywhere and it’ll take a callstack to figure it out.
October 26th, 2011 at 11:22 pm
Don’t the two approaches do the same thing? I don’t see what was automatic about the first approach. But then, I am a bit slow.
October 27th, 2011 at 12:47 pm
@dukope good call. Explicit is always better than implicit.
@Danyal the first approach actually added stuff to a vector prior to main() being called by using static / global variables.