In my engine I thought about passing around references internally between the different subsystems rather than pointers. I liked the idea because I wouldn't bother with checking for null-ptrs == less code, it looks clean and I don't have to bother about the subsystems lifetime as they are tied to the Engine object.
But, I realised early on, initialization of the subsystems might be tricky due to some subsystems depend on others. I singled out two systems (so far) the memory and logging, that are common to all the (again, so far) subsystems.
I put those into a private class "EngineCore", as they would be constructed first and destroyed last.
Each other subsystem might have reference to those two.
Below is what it looks like so far:
class Engine : EngineCore
{
public:
Engine();
~Engine();
bool Init();
bool Start();
bool Stop();
bool Destroy();
bool isRunning();
void Tick();
/* Managers */
EngineSettings& GetEngineSettings();
IMemoryManager& GetMemoryManager();
IRenderManager& GetRenderManager();
IGameObjectManager& GetGameObjectManager();
ILogManager& GetLogger();
/* Factories */
IThreadingFactory& GetThreadingFactory();
#ifdef ANDROID
static JNIEnv* mJNIEnv;
#endif
private:
bool mRunning;
bool mInitialized;
EngineSettings mEngineSettings;
/* Managers */
RenderManagerImpl mRenderManager;
GameObjectManagerImpl mGameObjectManager;
/* Factories */
ThreadingFactory mThreadingFactory;
};
and
/*
* The most vital parts of the engine, the logging and the memory management,
* which must be initialied first and destroyed last.
*/
class EngineCore
{
public:
EngineCore() { }
~EngineCore() { }
protected:
LogManagerImpl mLog;
MemoryManagerImpl mMemoryManager;
};
so I can setup for example the ThreadingFactory (and in turn its members) for example like:
ThreadingFactory::ThreadingFactory(ILogManager& logger, IMemoryAllocator& memAllocator) : mMemoryAllocator(memAllocator), mLogger(logger),
mCreatedThreads(memAllocator), mCreatedMutexes(memAllocator), mCreatedCondVars(memAllocator), mCreatedThreadPools(memAllocator)
{
}
Now I have not gotten very far, but when I realised I had to put a special case for the Memory manager and LoggingManager, I started to get a bad feeling that later down the road, some wierd coupling between two subsystems might happen and I wouldn't know if I could avoid it.
So my question is, is it a sound design solution/hack to put the two core-systems into an EngineCore, and will this design eventually bite me later down the road?
EDIT: Im pasting the stuff directly from google code and the code segments are wierdly formated... why is this?