I've refined my resource management system to use the factory pattern. In the design I opted not to use the templated factory pattern and instead am using the parameterized creation pattern.
Current design:
- CResource - base class for all resources - resource classes derive from this class to extend resource functionality
- CResMgr - resource manager class - maintains a cache of most recently used resources
- ResCreator - creation class for all resources - no resources that can be added to the cache can be instantiated outside of this class
- Resources are indentified in the cache via a random ID
There are several problems popping up and I'm not sure of an elegant way to solve them
- If resources are identified by their ID and their ID is assigned at run-time, how do I account for objects that use the same texture? In the current system the duplicate textures would be assigned unique IDs and would occupy two locations in the cache. Since the IDs are assigned at run-time, a mesh object cannot know the ID of its associated texture and thus cannot know if its texture is already in the cache.
- The only way to account for user created resources is to override the create function in a class derived from ResCreator.
- The parameterized solution resolves to a switch inside of ResCreator::Create() and ResCreator::CreateFromFile().
- Since ResCreator must be able to create all resources yet all resources must only be created from within ResCreator, ResCreator then must be friends of the CResource derived classes. I'm not a huge fan of friend classes but could not figure out another way to do this.
The first problem could be solved using strings or multiple IDs but I would lose the efficiency of a std::map. Since resources are located by their engine-assigned ID and not by their actual resource ID, attempting to find out if a resource existed in the cache or not would be quite slow.
Non-negotiables
- Resources must have a centralized way of being created, destroyed, and added/removed to/from the cache.
- The cache must maintain most recently requested resources
- The cache must maintain the requested size, or very close to it.
- The cache absolutely can never exceed the maximum size.
- Identical resources should resolve to the same ID.
To illustrate here is an in-engine example. There is a mesh A that uses texture A that needs to be rendered and/or updated. Since this mesh uses texture A both the A mesh data and the A texture will be in the cache since the mesh class will request these from the cache. If they are not in the cache they will be created and added by the creator class. If another mesh B uses texture A it should ideally use the same texture as mesh A. It will NOT use the same mesh data since this causes a multitude of other issues.
Any suggestions?