hrkz
hrkz

Reputation: 398

Resource manager

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

Answers (2)

const_ref
const_ref

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

Some programmer dude
Some programmer dude

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

Related Questions