Sign in to follow this  

Singleton D3D resource manager

This topic is 4216 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

Hey all, In coding my game UI, I've now come to the point where I'm implementing a button/combo box to change resolution. I have managed to get the device to reset correctly, restoring all resources afterwards, but it has hit me that keeping track of all my D3D resources (such as index and vertex buffers) is quite a pain when they aren't centralized in some manner as I ahve to manually locate all objects and release/restore any D3D resources they may contain. To that end, I've been thinking about creating a singleton class that looks after creation and distribution of vertex and index buffers, such that I can give this class Release/Restore functions that have access to all index and vertex buffers in one place, this would allow me to release resources, reset the device and restore resources in only a few function calls. I already have a design like this in place for textures, but this situation is a little different because textures may be used many times in many different objects, so a centralized resource makes more sense in this case, index and vretex buffers I think tend to be more unique, so I'm not sure if this is the best idea or not. This does however seem to be much easier to track than having them scattered in many different objects. Objects can then access their buffers by an ID of some sort (integer or string based) when needed. Now, I'm not sure this sits particularly well with object oriented design and I'm wondering if it might cause me problems in other areas of the program in future... does anyone have any opinions on this idea? If so I'd be grateful to hear them! Is a singleton design a bad idea in this case, or acceptable given the ease of use that would result? Many thanks, Steve

Share this post


Link to post
Share on other sites
I'm not sure I'd have objects access buffers via ID. It seems (at first glance) that it would probably be better to have objects deal with buffers as normal, but just manage a centralized list of (preferably smart) pointers to each.

Share this post


Link to post
Share on other sites
So effectively, you're suggesting that objects 'register' (by providing a smart pointer to the buffers) with a class that maintains a central list of buffers (presumably still a singleton)?

I had actually thought of that, but efectively it does the same thing, surely? You then run into complications if an object does not get registered correctly as it then does not get released/restored and the device reset will fail. I worry that this may be introduce a source of future problems rather than helping to solve the problem any better. Perhaps I am overlooking something or misunderstanding? Maybe it has other benefits that I'm missing!

Best wishes,

Steve

Share this post


Link to post
Share on other sites
Eh? I don't know how your setup is. If the VB/IB creation/destruction is nicely encapsulated, (de)registration is trivial and safe. It just seems (to me) that abstracting to ID is going backwards. Design to usage, not to exception.

Share this post


Link to post
Share on other sites
About singletons itself:
Is there a special reason why you want to use a pattern like a singleton over a static class? If not: use a static class(I mean: a class with only static members).

And about the manager:
I know it's probably because of your design right now that you can't imagine yourself that you need more than 1 resource manager, but from a design-point-of-view that might change in the future(because you might want to separate two types of resources into two managers, so it's easier to search for them for example).
eg. You might have a resource manager for UI stuff and one for 3D stuff.

Personally, I would just make a resource manager class(not static, not singleton) and make one static ResourceManager object in your UI baseclass(or some other suitable place).

Share this post


Link to post
Share on other sites
The question is not about singletons, it's more about managing resources so that when the device is lost and re-created, all the resources are released and recreated without having to handle that manually. Why do people always have to bring back the old "singleton is evil" flame everytime ?

Anyway, it's true that VB / IB tends to be unique, on the contrary of textures which can be re-used. But that doesn't meen it's wrong putting them in a resource manager. In my "engine" I consider as a resource, anything that has to be released / reloaded each time the device is lost.

So I have a virtual class like :

class IResouce
{
protected:
IResource(void);
virtual ~ IResource(void);

public:
virtual HRESULT OnCreateDevice(IDirect3DDevice9 * pd3dDevice, ...);
virtual HRESULT OnResetDevice(IDirect3DDevice9 * pd3dDevice, ...);
virtual void OnLostDevice(void);
virtual void OnDestroyDevice(void);
};

My textures, VB, IB, even state blocks and shaders inherit from this interface and implement these methods.

I then use a resource manager (in the form of a static class : static members + static methods, but a singleton or a "normal" class is allright too) which returns an ID for each resource created(*)
The main point is that when you handle VBs / IBs and other resources via a manager, you don't have to care about device lost. You have an ID, and you know that whatever you do, unless you remove the resource from the manager, it's always valid.


(*)This ID is actually the place of the resource in the resource array (for fast retrieval of the resource)


I hope it helps.

Share this post


Link to post
Share on other sites
Thanks for the link, that does help explain the pro and cons (though mainly cons!!) in a clear manner. I can understand the need to possibly add another type of resource manager later on, and I shall take that on board with my design.

I guess I'd gone with the singleton simply to centralize the resources, I still think that some sort of centralization is a good thing, I still think some kind of automatic centralization would be a good thing, I prefer to leave as little to chance as possible, and having to manually (in my air hockey game) go:

for(int i=0;i<Pucks.size();i++)
Pucks[i].ReleaseResources();

Arena.ReleaseResources();
PlayerShuffler.ReleaseResources();
EnemyShuffler.ReleaseResources();
ParticleManager.ReleaseResources();

D3D9Device.Reset()

for(int i=0;i<Pucks.size();i++)
Pucks[i].RestoreResources();

Arena.RestoreResources();
PlayerShuffler.RestoreResources();
EnemyShuffler.RestoreResources();
ParticleManager.RestoreResources();

Seems like unneccessary work compared to:

ResourceManager.ReleaseResources();
D3D9Device.Reset();
ResourceManager.RestoreResources();

That's all I'm trying to avoid.

Maybe it's about time I implemented a factory patterned class for creation of game entities, I guess with this the buffers could be added to a list automatically upon creation so I don't forget any time I add a new object to the code.

Cheers for the help so far :) Always good to get a second opinion.

Steve

*EDIT* Thanks Paic for that reply. I do agree that the whole subject of patterns and OOP can be a bit flammable, but I can see some sense in the posted link. I think it can be argued both ways and can make sense from both perspectives.

I find that most of the time, I know what the best method really is but I don't always have the coding experience to be sure, so I blunder through with what I know for definite (in this case, the ease of use of singletons... it does the job in a simple case and sometimes that is all you need).

In this case, I think I probably should do away with the singleton as I can now see other ways of achieving the same thing in a better and more flexible manner. On the other hand I don't want to code the worlds most generic engine, so I shall certainly keep it simple and not go crazy with it!!

Share this post


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