concept of a new engine

Started by
11 comments, last by CTar 17 years, 7 months ago
Hello, Community I'm just soliciting your advice on how I should be writing my engine. Right now, I have all my debugging utilities in separate classes, ie LogFile, Exception, Assert, MemoryManager, etc. But I was just wondering if it is better to take advantage of inheritance and create one main class like Object and stick all of this stuff into it, and have every class inherit from it. Would there be an immediate slowdown because of it? Thanks for any advice[smile], exorcist_bob
Advertisement
This COM style 'inherit absolutely everything' mentality is great(ish) for many applications, but over-OOPing your code is generally a bad idea for games programming. There are arguments for and against it, but you'll probably find that most people in this forum prefer to have global objects rather than a single global instance of a class to encapsulate base functionality.

Unless your engine is special somehow and will benefit greatly from the 'IUnknown' setup, I recommend you concentrate your efforts on making it work, rather than making it abstract 'nicely'. Game engines, unlike many business applications, tend not to have several tiers of classes that are all subtly but significantly different: Your AI agent will be radically different from your mesh object, which, in turn, will be radically different from the network socket and camera class. When the core components of your engine are so diverse, there is little to be gained and much deadwood to carry around using the proposed model.

Regards
Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
I just thought that something like this might be useful:

class Object{protected:virtual void Dump() = 0;}class Something: public Object{private://Have to override this, since it is pure virtualvoid Dump(){//Dump all the variables in this class}};


Since Object would be common to all classes, if I threw an exception, all dumps of all active instances of all classes inherited by Object would execute their Dump() routines. Or isn't this feasible?[sad]

Thanks,
exorcist_bob
It's feasible, but not all that useful.
The fact that each class that derives from Object would have to override Dump() in their own unique way means that you aren't saving yourself much effort at all. A more popular base functionality to put in an 'object' class is reference counting, which has its advocates, but is also unnecessary, in this programmer's opinion.

If you really want to use inheritance in your engine, nobody is stopping you, and it probably won't cause you any problems - maybe it'll even solve some. It's just that most wouldn't consider the benefits to outweight the costs.

Regards
Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Thanks for your replies, Admiral!

Would this cause a significant slowdown? I have heard both sides of the story. Some say that inheritance is slow and should be avoided, but I have also heard that the slowdown is barely significant.

Thanks,
exorcist_bob
You're over complicating your logging. Just use global functions, not everything needs to be a class. Otherwise (bet you're using a horrid and evil singleton for it...) you're doing a lot of extra typing for nothing.

Example:
Log::Get().Write(...);

or..
Log(...);

You pick which would be easier and more likely to be used? ;-)

Remember, even if its just for you, KISS.
Quote:Original post by exorcist_bob
Would this cause a significant slowdown? I have heard both sides of the story. Some say that inheritance is slow and should be avoided, but I have also heard that the slowdown is barely significant.


There is absolutely no slowdown with inheritance. The only thing that introduces a slight slowdown are virtual members.

-----------------Always look on the bright side of Life!
Quote:Original post by Anonymous Poster
You're over complicating your logging. Just use global functions, not everything needs to be a class. Otherwise (bet you're using a horrid and evil singleton for it...) you're doing a lot of extra typing for nothing.

Example:
Log::Get().Write(...);

or..
Log(...);

You pick which would be easier and more likely to be used? ;-)

Remember, even if its just for you, KISS.


But it is more that just that. If I can get this to work, if something goes wrong in one part of the engine, it forces all instances of classes to dump their var states. This base class would include logging, exception throwing, assertions, and memory management. This way, I think I would be able to dump a lot of useful information.

PS. I'm not using a singleton. In fact, there isn't a single global variable or function in the engine yet. As for your example, couldn't you use just a #define, if you didn't want to type all that?

Thanks for your help,
exorcist_bob
How would inheriting from a common base class help your design? As I see it, you'd make your design worse because you completely ignore separation of concerns and information hiding. The "dumping" you talk about shouldn't force all classes to dump their contents, instead you should have a base class called dumpable or something like that, so that the functionality of dumping is seperate and optional. I assume you want to make a logging a part of the common base class because you need an easy way to access the logging facilities, in that case a global, monostate or singleton would be just as good (but not optimal). As I see it there is absolutely no reason to make logging a part of the common base class. The common base class shouldn't depend on assertions or memory management either, the implementation of classes could depend on the assertion and memory management system, but don't force this unnecessary dependency onto all of your classes.

Could you please tell us exactly why you believe this new design is better? Inheritance doesn't just make your program more object oriented if that's what you believe.
With EVERYONE here opposing me, I doubt this will make any difference.

It is my personal belief that it is hard to track where something went wrong, and causes your engine to crash, since a lot of times, you don't run a full-fledged game in the vc++ debugger. Since everything that handles a given set of data has the potential to mess it up, as an engine gets larger, it becomes harder and harder to track something down, and soon, you forget where it going and has gone. By forcing everything to dump data to a file, I believe it will be easier to track down and eliminate it. I think that the easiest way to do this is with a base class that all classes must inherit from. Since I can't call a pure virtual function in a base class, I have to call it from all classes that inherit from it.

// test_inheritance.cpp : Defines the entry point for the console application.//#include "stdafx.h"using namespace std;#define DumpClass() if(m_bMustDump) Dump()class base{public:	base()	{	};	~base()	{	};	void Exception()	{		m_bMustDump = true;	};protected:	virtual void Dump() = 0;	static bool m_bMustDump;};class derived1: public base{public:	~derived1()	{		DumpClass();	};private:	void Dump()	{		cout << "derived1" << endl;	};};class derived2: public base{public:	~derived2()	{		DumpClass();	};private:	virtual void Dump()	{		cout << "derived2" << endl;	};};class derived3: public derived2{public:	~derived3()	{		DumpClass();	};private:	void Dump()	{		cout << "derived3" << endl;	};};bool base::m_bMustDump = false;int _tmain(int argc, _TCHAR* argv[]){	{		derived1 d1;		derived2 d2;		derived3 d3;		d1.Exception();	};	char ch;	cin >> ch;	return 0;}


Thanks,
exorcist_bob

This topic is closed to new replies.

Advertisement