Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Don't forget to read Tuesday's email newsletter for your chance to win a free copy of Construct 2!


Passing references around internally in the engine


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   -  Reputation: 1200

Like
0Likes
Like

Posted 07 September 2012 - 05:10 AM

Hello,

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?

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


Sponsor:

#2 Faelenor   Members   -  Reputation: 396

Like
-3Likes
Like

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   Crossbones+   -  Reputation: 14001

Like
4Likes
Like

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
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#4 Faelenor   Members   -  Reputation: 396

Like
2Likes
Like

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.



PARTNERS