Jump to content

View more

Image of the Day

Working on an auto spawn system. #gamedev #indiedev #screenshotsaturday https://t.co/Mm2kfekz7b
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

Sign up now

Passing references around internally in the engine

4: Adsense

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 KaiserJohan   Members   


Posted 07 September 2012 - 05:10 AM


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
				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;
				bool mRunning;
				bool mInitialized;
				EngineSettings mEngineSettings;
				/* Managers */
				RenderManagerImpl mRenderManager;
				GameObjectManagerImpl mGameObjectManager;
				/* Factories */
				ThreadingFactory mThreadingFactory;


		 * The most vital parts of the engine, the logging and the memory management,
		 * which must be initialied first and destroyed last.
		class EngineCore
				EngineCore() { }
				~EngineCore() { }
				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?

Edited by KaiserJohan, 07 September 2012 - 05:12 AM.

#2 Faelenor   Members   


Posted 07 September 2012 - 06:32 AM

You should probably have a kind of singleton manager, responsible for the creation and destruction of all singletons, instead of putting them in other classes. They should be pointers instead of plain member variables. That way, you'll be able to control creation and destruction order. I'm not sure if I understood your problem correctly though...

#3 L. Spiro   Members   


Posted 07 September 2012 - 06:52 AM

I strongly urge you to disregard the previous post. If you are using singletons, you are doing something wrong.

Engine initialization typically happens in 2 steps.
First, initialize the memory manager.
Then the window and everything else.

If you don’t have unusual dependencies (why would the memory manager rely on the “EngineCore”?) then there will never be a problem with this. The lowest-level things need to be initialized before the higher-level things (and deleted afterwards).

As for your considerations between when to use references instead of pointers, the rule is simple: If it can never be NULL, use a reference.
If NULL is a valid value to pass, use a pointer.

L. Spiro

#4 Faelenor   Members   


Posted 07 September 2012 - 08:59 AM

Oh well, you're right L. Spiro. It was early, I shouldn't have answered this question as I didn't even understood it correctly... sorry!

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.