Jump to content
  • Advertisement
Sign in to follow this  
Waaayoff

Resource managers as singletons?

This topic is 2636 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Right now my (simple) app has 2 managers. A VertexBufferManager and a VertexDeclarationManager. The first handles creating and fitting multiple meshes into single vertex buffers. The second one handles creating Vertex Declaration. I don't want to create more than one similar declaration simply because it makes sorting renderables easier later on. A simple pointer check.

Now as far as i can see, creating more than one instance of these will break their functionality. One reason for me to use Singletons.

Another reason is accessibility. I have a procedural TreeGenerator class which needs access to these two managers. It will also need access to a TextureManager and perhaps an IndexBufferManager. I don't really want to keep passing all these managers around. Another reason for me to use Singletons.

So my questions are:
1) Is the use of Singletons justified in the case of managers?
2) Should i NOT be using all these managers in the first place? (Please suggest an alternative)?

Share this post


Link to post
Share on other sites
Advertisement
1. No. A singleton gains you nothing other than trying to cover for someone maybe doing something wrong in the future.

2. Yes, you have too many mangers. Those pieces of functionality could be happy rolled up into a single 'renderable' manager type class which sets up a 'renderable' instance which lets the classes which depend on it work on it. There is no reason to have a seperate index buffer or vertex buffer manager; what possible use case do you have which require that seperation? Same with the vertex declarations; you won't need many anyway and they are generally tied to shaders so probably should be managed with them.

The worry about 'passing them to loads of systems' is a non-issue as with a properly designed system very few classes will need to be aware of the existance of these things; they will deal with 'renderables' to represent themselves in the scene and that's it. They wont' care about buffers etc in the slightest.

Share this post


Link to post
Share on other sites
In addition to what phanom said, I think i should just point out that it seems your [color=#1C2837][size=2]VertexBufferManager and VertexDeclarationManager are actually procedural API's. Rather than using a singleton for procedural API's you should use free functions (if your language supports them, e.g .c++) or static methods (if it does not, e.g. c#).

Share this post


Link to post
Share on other sites
You're forgetting the second criterion for using a singleton pattern: global access is required. Not wanting to pass objects around is not the same as requiring global access. And, as stated above, you really shouldn't need to pass them around all that much.

Share this post


Link to post
Share on other sites
I would agree with phantom that these should not be separate managers. They are specific to triangle meshes and should be somehow related to the code that handles these.

In general I have found that if the only name that makes sense for a class is a WhateverManager (especially if you are tempted to make it a singleton or global), it usually means that you are approaching the problem incorrectly.

For vertex/index buffers I don't think anything should be directly accessing them except for your mesh class and renderer class. The mesh class worries about constructing/updating its vertex/index buffers and the renderer worries about uploading/displaying the buffers through the graphics API. I'm sure there are other good ways of doing this depending on your requirements but this, to me, seems like the simplest solution.

Share this post


Link to post
Share on other sites

Another reason is accessibility. I have a procedural TreeGenerator class which needs access to these two managers. It will also need access to a TextureManager and perhaps an IndexBufferManager. I don't really want to keep passing all these managers around. Another reason for me to use Singletons.


"accessibility" is an excuse used by lazy typists who fancy themselves programmers.

Good programmers realize that passing such parameters is A Good Thing (TM) which makes tracking dependencies easy by requiring that they are explicitly stated. In stating them explicitly, the programmer is forced to acknowledge the dependency, and to consider with each injection of the dependency whether it is a desirable one. This has a cooling effect on the tendency of global state, such as singletons, to take root in systems where it does not belong, and provides a conduit for refactoring later on.

It should be annoying to "keep passing all these managers around" as you say it is -- but global state and singletons only help to cover the odor of this code-smell; they don't address the cause -- just the symptoms (and poorly at that). Having to pass managers hither and thither all over creation is a sign that your design is poor -- specifically, it is usually a sign that you have grouped responsibilities poorly and/or have defined them at an incorrect scope withing your application. To simply patch over this with a singleton is tantamount to willful negligence, because you are choosing to harm the stability, testability, and refactorability of the code base in order to provide yourself all the convenience of having addressed the problem, without actually having addressed the problem.

In general, unless you're writing device drivers or something, there's no reason you should ever create a singleton.


Now, its just occurred to me that you haven't stated which language we're talking about, and it seems that most of the advice here, mine included, is assuming C++ where the C++ notion of a singleton has (rightfully) an especially bad reputation. Do be aware that other languages have different notions of precisely what a singleton is, and many of those languages make them less dangerous, at least from an implementation standpoint, but one should always still be wary of the deleterious effect that any form of global state has on code stability, testability, refactorability, and understandability.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!