Let's design a tiny engine

Started by
18 comments, last by Clash 19 years, 10 months ago
With all my engine design problems lately, I've devided to strip it down to a few systems that I know how to work with. The overall design is still what I'm questioning. Here is what I want the stripped down system to do: 1. User opens "game" 2. A script file is called 3. Results of the script file are displayed. I'm very OO, so the objects I want to create are Direct3D, Kernel, Script, and Texture. The Kernel will contain a Direct3D and Script instance. Direct3D will take care of blitting and flipping buffers, and Script will basically be a script handler. For test purposes, I'll create a script that just creates a textured quad on the screen and moves it down from top to center. What would be my best design options here? Should I make Direct3D a singleton? Should anything else be a singleton? Should I avoid them? I'd like to implement this without singletons since that's what I'm told is best, but how would I go about this?
Advertisement
Speaking from my experience with making engines, implement the sound, scripting, and screen interfaces as singletons.
HOW DO I MAKE GAMES?READ THIS:http://www.lupinegames.com/articles/path_to_dev.html
I must admit, I don't know what a singleton is. What is it? I'm curious, as I've heard people say it before but I felt too foolish to ask. =)
-Vendal Thornheart=) Programming for a better tomorrow... well,for a better simulated tomorrow. ;)
A singleton ensure that a class has only one instance and provide a global point of access to it.

There are many ways to create a singleton, here is a way to do it:

//Ok this is the Sound class, a singletonclass Sound{protected:  static Sound *Instance;public:  static Sound *Inst()  {    if(Instance==NULL) Instance = new Sound;    return Instance;  }  void Init();  void PlaySound(int id);  void Shutdown();};Sound *Sound::Instance=0;//Set the instance pointer to null


Now here's how you can use your singleton ANYWHERE in your program.

//Let's say this is GameEngine.cppvoid Engine::Init(){  Sound::Inst()->Init();}void Engine::DoFrame(){  Sound::Inst()->PlaySound(53);  //Do other stuff...  Sound::Inst()->PlaySound(33);}


You never have to create any object externally since the class will dynamically create the object by itself when calling the static function Inst() for the first time.

The problem right now is that the dynamically created 'Instance' won't be deleted.
I would add a "delete Instance;" in the Shutdown function of the class Sound and make sure to not forget to call it... but I believe there's a better way to delete the instance.
Unfortunatly I rarely use Singletons so I don't really know..

But I suggest you to do some search on google for singletons, there are a lot of info about them...

One last thing, here's a great article for building an engine:
http://www.gamedev.net/reference/programming/features/enginuity1/
I don't like that article. It's way too advanced for what I'm trying to do right now. He goes way into server/client architecture, smart pointers, etc. I'm not even trying to implement memory management yet.
Fascinating! Okay, so it's like "Shared" classes in the .NET framework then. That's cool! Very useful... I'll have to remember that! =)
-Vendal Thornheart=) Programming for a better tomorrow... well,for a better simulated tomorrow. ;)
No good ever came from singletons in my experience. It seems that everyone goes through a singleton obsession phase, then realizes they are crap, and just uses a global like they should have in the first place. I've never had a legitimite use for a singleton, and rarely seen others have them. For what I was using them for, globals did the exact same job, without the hassle across DLLs. 'Shared' is equivilent to 'static'.

edit: In my limited experience with VB.Net, where I've seen Shared it is the same thing as static. I'm not sure exactly what you mean by Shared clasess. If you mean that every member is Shared, or you can accomplish the same thing by putting Shared in front of the class declaration, then yes, it is the same as static.
Quote:Original post by Kibble
No good ever came from singletons in my experience. It seems that everyone goes through a singleton obsession phase, then realizes they are crap, and just uses a global like they should have in the first place. I've never had a legitimite use for a singleton, and rarely seen others have them. For what I was using them for, globals did the exact same job, without the hassle across DLLs. 'Shared' is equivilent to 'static'.

edit: In my limited experience with VB.Net, where I've seen Shared it is the same thing as static. I'm not sure exactly what you mean by Shared clasess. If you mean that every member is Shared, or you can accomplish the same thing by putting Shared in front of the class declaration, then yes, it is the same as static.


Ok, let's say I make an object Direct3DO{}, it's a singleton, and for now just has a pointer to the direct3d9 interface.

Aside from the obvious example problems(creating an object with 1 member...), can you tell me why it'd be a better method to just create the pointer in the global space? EITHER WAY I have to release it myself, so I just don't see the argument against singletons.
its simple, dont create an object in global space.
Instead, assuming C++ here, on init of your main 'kernel' create reference counted smart pointers to the various subsystems and pass them down the line to things which are required (or even pass a pointer to the 'kernel' and give it a 'getSound' etc set of functions). The use of reference counted smart pointers is to stop your objects becoming deleted by mistake somehow and crashing everything out.

This forces you to think about your design and what needs what instead of having a bunch of global objects you can access from anywhere and temping you into silly hacks and not thinking about the design and the interfaces properly.

I fell into the above trap on my last project so i speak from experiance, once it was done I realised the only section which I could fully justify being a singleton was the error loggin system because i truely did need to get to that from anywhere in the code, everything else had logicaly points where I would need it.
That post was after a 14 hour shift (QA) so I apologize if it comes accross wrong.

Are you saying create the object, for example:

class Direct3D{ ...stuff}


...then create an instance of that object in the global space? If so, then I'm stuck again. Many things need access to the Direct3D object. Where I get stuck is this. I'm making an engine before I make the game. Now when I make the game, I can create an instance of Direct3D in the game source and work from it. The problem is that many other objects in my engine ALSO need access to the Direct3D object. When I'm writing objects such as Texture, it needs access as well. Do you make a Kernel object that houses everything, and do it all through there? Even still, I'd have to DERIVE my Texture object from the kernel for it to have access to the instance of Direct3D created in the kernel. The only solution I have found is singletons, but I'd be overjoyed to hear the solution to my problem without them. It'd probably teach me a lot and make me a more robust programmer, but most people aren't willing to share how they design.

This topic is closed to new replies.

Advertisement