My first focus for LiteGame engine is the most broad kind of architecture, that of modules. When I talk about modules I
reffer to things like the renderer, the sound system, sprite library, entity factory, etc. The peices of code who’s job
is to manage a specific area of work.
A common pattern that I see in my programs is that many modules need their code to be executed in three main stages of
the application:
At startup …onInit()
Once per frame …onTick()
and before exit …onFree()
In the past I have organized things loosely as follows:
#include "module1.h" #include "module2.h" // entry point main( ) { // initalise modules module1_onInit( ); module2_onInit( ); // main game loop while ( game_is_running ) { // update all modules module1_onTick( ); module2_onTick( ); } // release modules module1_onFree( ); module2_onFree( ); }
It dawned on me when starting this engine that this is realy a very ugly structure.
Everytime we add a new module, we have to make changes to this file in four places. On top of that,
we drag the header of each module into our main file, in order to access three of its functions.
Things become more complex still when we start locking the framerate, and load balancing these modules.
A nice solution would be to have some manager that can look after our collection of modules, and call their
functions at the correct times. This also seems like a good place to insert timing code, so that we
can ensure that onTick() can be called at a set rate, giving us a constant tickrate.
An obstacle presents itself, as to how we register these modules at compile time, without any
one centralised point to explicitly register them. I will present a solution, but please write to me if you
know any others, I would love to hear about them.
A nice solution is to (ab)use the way C++ initalizes static data, to execute code that will register
each module before the program even reaches main(). Observe the following:
struct sRegisterModule { sRegisterModule( void (*onInit), void (*onTick), void (*onFree) ) { module_add( onInit, onTick, onFree ); } };
Here we see a class that has only one method, a custom constructor that takes our module entry points as parameter.
When this module is contructed it will pass these functions to the module manager which will register a module, properly.
This doesnt seem all together so usefull until we see what happens when we include the following code inside of our module:
static sRegisterModule module1( module1_onInit, module1_onTick, module1_onFree );
Since module1 is a custom type, global static variable the compiler has to construct it at program launch. Thus the constructor
is executed, and our parameters are passed to the module_add() function. Thus we have found a smart way to give details about our
modules to the module manager in a distributed way.
Then our main() function can be reformed as follows:
#include "module.h" main() { module_initAll(); while( game_is_running ) { module_tick(); } module_freeAll(); }
With this system a module is completely self contained, and simply needs to pull in the module manager library. As far as I can see this is a nice basis to structure farther developments to the engine.
Interesting idea, although the little OOP-guy in my head cried “use an abstract interface class instead of function pointers” all the time while reading. 😉
I use a similar approach in my own work-in-progress engine, but since I want to be able to switch modules without recompiling the whole project, my modules are shared libraries that are dynamically loaded at runtime. This way, I could switch my renderer from OpenGL to DirectX and all I had to do was to add the new renderer and edit a config file. I’m pretty sure, I’ll never actually do that, but I could. 🙂 This also reduces dependencies between modules.
The modules do not register themselves, though. But one could put all modules into their own directory an scan that at startup, registering each module found.
It’s quite nice read, well done!
as I am not the biggest fan of vTables nor function pointers I am looking for some alternatives..
static polimorphism, (http://blog.aaronballman.com/2011/08/static-polymorphism-in-c/ ) is quite nice – I see how it can make component based engine really elegant and clean..
but I am not at the position to definietly say “go with that” as I am having some issues with it.
just something you might find interesting.
will keep you posted 🙂