This is the resource manager architecture that my game engine uses. The only other type I could think of was the templated sort that Shamino suggested. The problem there is that each resource is constructed differently and so you cannot create a virtual function for creation because you have no idea what parameters, if any, the resource will need.
What I like about this system is that you can easily construct any type of resource you want and as long as it is derived from the base resource class it will work fine.
To cleanup the entire system all you have to do is delete the derived resource manager class. So essentially in a game you would call this in the ShutDown() or Cleanup() function for the engine. This would then iterate the huge vector in the main manager class and properly cleanup the resources.
The Add() function returns the index of the object in the vector so that it can be accessed later. Lightweight wrappers can then be created for each object type. These wrappers would be to simply remember the indices for each different object type. So a CTextureMgr would have a vector that contained all of the indices into the main vector for all CTexture objects.
So if your master vector looked like this:
0 - CTexture
1 - CD3DXMesh
2 - CDXSoundSegment
3 - CD3DXMesh
4 - CTexture
...
The various object manager vectors would look like this:
CTexMgr - 0,4
CD3DXMeshMgr - 1,3
CDXSoundSegmentMgr - 2
Here is some code to illustrate the basic system:
Comments? Criticisms? Suggestions?Code:// ResMgrTest.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <vector> #include <conio.h> class BaseResource { public: BaseResource() { printf("Creating BaseResource\n"); } virtual ~BaseResource() { printf("Destroying BaseResource\n\n"); } }; class DerivedResource:public BaseResource { public: DerivedResource() {printf("Creating DerivedResource\n"); } virtual ~DerivedResource() { printf("Destroying DerivedResource\n"); } }; class DerivedResource2:public BaseResource { public: DerivedResource2() {printf("Creating DerivedResource2\n"); } virtual ~DerivedResource2() { printf("Destroying DerivedResource2\n"); } }; class DerivedResource3:public BaseResource { public: DerivedResource3() {printf("Creating DerivedResource3\n"); } virtual ~DerivedResource3() { printf("Destroying DerivedResource3\n"); } }; class BaseMgr { protected: std::vector<BaseResource *> m_vResources; public: BaseMgr() {printf("Creating BaseMgr\n"); } virtual ~BaseMgr() { printf("Destroying BaseMgr\n\n"); for (int i=0;i<m_vResources.size();i++) { delete m_vResources[i]; } } void Add(BaseResource *pObj) { printf("Adding resource to BaseMgr\n"); m_vResources.push_back(pObj); } }; class DerivedMgr:public BaseMgr { public: DerivedMgr() {printf("Creating DerivedMgr\n"); } virtual ~DerivedMgr() { printf("Destroying DerivedMgr\n"); } }; int _tmain(int argc, _TCHAR* argv[]) { //Create the master manager class DerivedMgr *pMgr=new DerivedMgr(); printf("\n"); //Create 2 DerivedResource objects and add to master vector for (int i=0;i<2;i++) { DerivedResource *pRes=new DerivedResource(); pMgr->Add(pRes); printf("\n"); } //Create 2 DerivedResource2 objects and add to master vector for (int i=0;i<2;i++) { DerivedResource2 *pRes2=new DerivedResource2(); pMgr->Add(pRes2); printf("\n"); } //Create 2 DerivedResource3 objects and add to master vector for (int i=0;i<2;i++) { DerivedResource3 *pRes3=new DerivedResource3(); pMgr->Add(pRes3); printf("\n"); } //Wait for a key printf("\n ** Press any key to shut down the resource system **\n\n"); getch(); //Clean up the entire system delete pMgr; //Wait for a key getch(); return 0; }
I'm about to fully implement this system to my game engine so I need some input from some of you that have tried to do resource management in your engines.