Reputation: 398
I'm working on a resource manager for a game engine.
It should be able to manage images, textures, meshes, but this is not the problem. When a resource is loaded, the manager will check if this resource is not already in a "cache" (a ptr is stored in a typical data structure).
I'm wondering what kind of resource I should send back to the user if its already loaded. I was thinking about a const ptr
template <typename T>
const T* getResource(string resourceName)
But it avoid the possibility to modify the resource itself. If I send a non-const ptr, the user will be able to modify the resource which will provoke multiple repercussions.
What about a shared_ptr?
Any advices?
Upvotes: 1
Views: 3817
Reputation: 4096
In my ResourceManager I store a map which takes a std::string
as the lookup and stores a std::unique_ptr<Resource>
.
std::map map<std::string, std::unique_ptr<Resource>>;
Then I have a get function that looks something like this
const Resource& get(const std::string& name)
{
//search map for name, if it exists return it, else construct then return it
auto found = map.find(name);
if(found != map.end())
{
return *found->second;
}
// otherwise construct then return from map
}
I also have an overloaded function that can take extra params(such as texture rectangles for sprite sheets) etc, and another function that just returns Resource&
as opposed to the const one. The const ref one can be used therefore to prevent changing the object elsewhere.
This means that the ResourceManager takes care of the ownership of the resources and if we ensure the resource manager is not destructed before the end of the game application that the resource scope will always be valid. This way of handling resources also prevents having to check if the resources are null before we use them elsewhere in the application(assuming you do some error checking on construction of the resource and the resource is initially in a valid state)
A use case is then as follows
ResourceManager<Texture> texture_manager_;
// If texture.png exists already then we just get a ref
// otherwise it gets constructed, checked for validity, stored in the map
// and then returned as a ref. That way we know the object is in a valid state
Texture tex = texture_manager.get("texture.png");
The final benefit is that this ResourceManager makes use of RAII and everything in the map will be destructed correctly when the ResourceManager goes out of scope(which presumably will be at a controlled point i.e. the end of the application)
Upvotes: 2
Reputation: 409176
A major problem with enabling the user of the resource manager to edit/modify the data, is that the data may need to be enlarged or made smaller.
Instead of having a single getResource
that returns a non-const pointer (shared or not), why not have a getResourse
function which returns a pointer to constant data, and then if the user need to modify that the user have to copy it to some private memory, and modify that, then have a setResource
function to set the new resource data, with correct size.
Upvotes: 2