Skip to main content
gamedev.net
🔒 Locked

Singletons

Started by Bimble Bob Jan 7, 2007 at 3:04 PM 28 replies 3.2k views
Original Post
Bimble Bob
Bimble Bob
OK I think I understand what a Singleton is. A class which has only one instance. But I was wondering how this concept would apply to games and/or game engines. Anyone got some examples they could explain? It would really help.
It's not a bug... it's a feature!
CandleJack
CandleJack
Pretty much anything that would not make sense to have more than one instance of. A couple examples could be a class to encapsulate the functionality of the main window, or a timer class. It wouldn't make sense to have two application windows, and it wouldn't make sense to be keep track of the time in multiple instances as one is just fine.
CTar
CTar
Singletons are generally considered bad design, because in OOD you shouldn't create a class which there can only be one instance of. One common example is a graphics or input manager because the programmer doesn't think there will be multiple of these, however if you choose to just let it be a normal class and create one instance of it you will be ready for the day you need to create two of them (dual monitors? Dual mouses?). A regular class won't have more overhead, and it's likely to make your design much cleaner. One, IMO, acceptable use of a singleton is for an application/game class since one application should never be more than one application. Also we have the problem that singletons are accessible from anywhere, but they shouldn't be, physics code and matrices shouldn't have access to graphics.
mikeman
mikeman
I've never found a use for a singleton. Singletons are supposed to be necessary for 2 things:

1)Allow for only 1 instance to exist. In that case,I just make a normal class and create only 1 instance. I think going out of my way to make sure I don't create more than one instances by accident is a bit silly.

2)Be accessible from everywhere. By the way, this is the real reason why people use Singletons. In that case, it's a sure sign that I must rethink my design better. But even if I want to go the other way, I just use a global variable or pointer, which does the same thing.
Bimble Bob
Bimble Bob
Thanks for the replies. It's just I've been looking through some open source projects. Seeing how they're designed and laid out. And I kept seeing this word Singleton everywhere. Seems popular for logging systems for some reason :S
It's not a bug... it's a feature!
ToohrVyk
ToohrVyk
As mentioned earlier (with different words), a singleton is a design pattern which corresponds to two distinct requirements:

  • A class must always have exactly one instance present.
  • The class instance is globally available to its users.


Note that the first requirement is a must. "It doesn't really make sense" or "it's not useful" are generally not arguments that are strong enough to warrant establishing the one-instance requirement, because they make one-instance restriction possible, but not necessary. Usual arguments toward a singleton include access to an exclusive resource, such as a device.

If the one-instance is dropped, you basically get a global variable.
mikeman
mikeman
Quote:

Having some classes universally accesible is basically a need when you work in a large project to mantain clean interfaces. Applied to videogames, i.e. is sound to have a TextureManager (mantaining textures cached) as a Singleton, cause if you create new textures, they dont have to know location details, and they must have to know how to load the texture itself. You could pass the texturemanager as every new texture is created, but doing so you need to explictly pass a reference in their constructor, and thats redundant, in terms of number of parameters and given the fact that you only need one entry point to that system, it is the TextureManager features, so Singleton and global accesibility is sound.


Well, I disagree. I really don't see why I need a "universally accessible" TextureManager. Why "universally"? Do I need to access it from my Input classes? From my Physics classes? From my AI classes? From my Sound classes? From my Log classes? If you need access to the texture manager in any other module except your Rendering one, then you're doing something wrong. Passing the TextureManager as a parameter to those classes is not redundant, making the TextureManager object accessible to completely unrelated modules is, and possibly dangerous also. I know many great engines(like OGRE) use Singletons, but that doesn't mean I agree with their use.

You are talking that using Singletons make sense to project that involve many people. How would you like it if you were fixing a bug having to do with texture loading, and find out that someone else were loading textures from inside the Input module because,hey, it is accessible from there too? If you decide to change the interface of the Texture Manager, guess how many modules of your program are potentially broken? All of them. If you make an object universally accessible, have fun hunting bugs all over an entire universe(also known as "program").
Sneftel
Sneftel
Quote:
Original post by Dom_152
OK I think I understand what a Singleton is. A class which has only one instance. But I was wondering how this concept would apply to games and/or game engines. Anyone got some examples they could explain? It would really help.

A singleton is a global variable, except that they can be used by people who think that Singletons are OO and global variables aren't. It's a little like keeping Kosher, except that Eric Gamma told you to do it instead of God.
moagstar
moagstar
Quote:
Original post by mikeman
If you need access to the texture manager in any other module except your Rendering one, then you're doing something wrong.


What about a resource management system? Or a network debug system that sends resources over a network to be debugged on another machine? Although in the examples you give it may at first sound a little strange to have access to the texture manager, it's not inconceivable that it might be required elsewhere.

smitty1276
smitty1276
Quote:
Original post by moagstar
What about a resource management system? Or a ...

Well, why would the input system need access to textures? Why not have a ResourceManager base class, and inherited managers for specific types of resources? There is no need for a singleton there.
Daivuk
Daivuk
Read this :).

I was using singleton a lot before. Had a lot of design flaws.
smitty1276
smitty1276
At work we deal with aircraft simulation stuff, and the assumption that there would only be one plane running in a process is one of the biggest pains in the ass that I have to deal with. Everything involving the aircraft state or flight model or any other critical system was implemented, essentially, as a singleton (in many or most cases it is actually static global data structures, but whatever).

Sometimes it may seem like a good idea to use the singleton pattern, but there is no guarantee that it won't cause you a massive headache later.
rip-off
rip-off
I have a texture loader.

Its global, but not a singleton.

I only have one instance of it. This is enforced by ensuring the global pointer doesn't point at anything before instantiation. This means that should I find use for multiple texture loaders, I can do so easily, no client code change required.

Its global because I'm lazy, really. I don't care enough, its not the most important part of my code. I allow myself such short cuts as Im (finally [smile]) trying to finish a game rather than overengineer the perfect solution for myself.

I have other components in my program which have a "single instance" rule, which is enforced at runtime rather than compile time ( well, debug time only due to the nature of assert ). My renderer class cannot have more than one instance simply because it depends on SDL, which currently can only create one window. However the "single instance" rule of the renderer does not leak ino its interface. I have managed to design it well enough that I could have multiple renderers should I want to.

Singletons sounded wonderful when I first heard of them, but I have since realised that they are just fancy globals. I rather just use the global and not decieve myself now.
dmail
dmail
Quote:
Original post by Daivuk
Read this :).

I was using singleton a lot before. Had a lot of design flaws.


Here is a quote from that text which I think is very important and agree with:
Quote:
(Note: I think there are some good uses for the Singleton pattern, but it's so incredibly overused, and serves as such a convenient crutch for people who don't understand OOP, that I figured I'd just take the stance in this article that it's basically Evil.)


Add to this that there are times when a singleton seems to be the answer; yet it is not the only means to an end and the others may be much better.

Now can the admins ban this subject? lol
Sneftel
Sneftel
Quote:
Original post by rip-off
Its global because I'm lazy, really. I don't care enough, its not the most important part of my code. I allow myself such short cuts as Im (finally [smile]) trying to finish a game rather than overengineer the perfect solution for myself.

Good software design is enlightened laziness. No more, no less.
RabblePants
RabblePants
Singletons, just like many other design patterns, can be and are useful when you fully understand what you are doing and what your intent is. I have never encountered a single thing in programming that did not have it's time and place. Singletons, when used poorly, is a poor design. When used intelligently can be a tremendous help in your code / design.

As people have said above already, the two rules for using a singleton are :

(1) Enforce a one-instance rule.
-> This means you can't just declare one instance of the object and assume it's a singleton. You have a global variable, but not a singleton. A singleton actively -prevents- you from creating more than instance.

(2) Accessible from anywhere, or most anywhere.

Now, anybody that has ever worked in a team larger than, say, 4 people know that programmers (especially programmers new to a project) will break rules they're not aware of. Programmers are generally smart enough to see a singleton and go "Hmm, this object is going through a lot of effort to prevent me from making another instance. Maybe I should look at other options first.."

At my job and my home projects, I code / design code always keeping in mind the possibility of a new programmer coming on board. Will this programmer understand our idiosyncrasies? Or do we have to actively prevent this new hypothetical programmer from making mistakes that will kill our engine? This also prevents us from doing the same thing (raise of hands of people who looked at their own code of 6+ months ago and had no idea what the heck its doing? *raises hand*)

So it's protection from you, me, and any new programmer coming onto your project.

Now, (2) is interesting as well. If you have a singleton object that may very well be used by a large number of your subsystems, then having it globally accessible is acceptable.

This does not mean it's acceptable for your "Input" module to load textures, and you or your lead or someone should keep tabs on that, but it does mean that your Render Module, Logic Module, Network Module, File Module, etc can load resources globally.

If someone makes a singleton where that singleton is used in one place, I'm gonna shoot him in the knee. But if it s good reason to be used in many many different places (multiple modules, subsystems, and so on) then it's ok and reasonable imo.

There's a time and place for everything in code.. you just have to be smart about it. There is no "this is always always always bad" rule. Even goto's have their place ;) Haven't found it yet, but they do :)

[Edited by - Grafalgar on January 8, 2007 2:17:15 PM]
nitramus
nitramus
We are using singleton design pattern in our BJS game for resource management (textures, sounds, fonts). Works well. The great thing about it is that we do not have to keep references to resource managers in these managed items.

At the start, we haven't been using any singleton DP and some developers naturally started writing their own "pseudo-singleton-design-patterns" for some classes. Instead of continuing in that trend (it would lead us to hell, I can guarantee that), we did a template class and if someone wanted to make his class to be a singleton, he used this template => better bugs hunting (...and we hunted many of them!), common design.

And singleton is not accessible from everywhere - it depends on your #include. Why would we put #include "texturemanager.h" into our input module, for example? We simply didn't.

IMO, better than writing our own singleton DP would be to use boost library, for example.
Sneftel
Sneftel
Quote:
Original post by nitramus
We are using singleton design pattern in our BJS game for resource management (textures, sounds, fonts). Works well. The great thing about it is that we do not have to keep references to resource managers in these managed items.

What advantages has the use of singletons over global variables produced?
Bob Janova
Bob Janova
A singleton is a class of which it is only ever possible to have one instance, and that instance can be obtained through a static method on the class. That effectively makes it a global variable, so all the usual warnings about global variables apply.

The reason you'll see a lot of vitriol thrown at them is because a worryingly large number of people think 'Oh yes, my code is OO'; if you use singletons then you're not writing OO code, and you should step back and see if you really want a global. Occasionally you will, but a lot of singletons is a sign of bad design.

IMHO, only an Application/Game class and perhaps a logger should be singletons (you should only ever have one application per application, duh, and arguably only one logger). But even a logger probably shouldn't be; you are likely to only want one, but why restrict it to that? Cover classes for exclusive-access devices would also make sense, but you don't need those very often writing games (except the graphics card, which is dealt for you by DX anyway).
songho
songho
Quote:
Original post by Dom_152
Thanks for the replies. It's just I've been looking through some open source projects. Seeing how they're designed and laid out. And I kept seeing this word Singleton everywhere. Seems popular for logging systems for some reason :S

Other popular example of singleton is a printer spooler. Singleton should be used in condition that you don't know:
1) when it will be initialized
and
2) who is calling from.

I think that a resource manager doesn't need singleton pattern, because the above 2 conditions are obvious.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.