1

I'm creating a Resource Manager for my game engine. Basically it have an unordered_map that stores the path of the resource as key and as value it stores the loaded resource.

This is the code responsible for loading assets.

std::shared_ptr<T> LoadAsset(const String& _path)
{
    if (auto asset = m_assets.find(_path); asset != m_assets.end()) {
        return std::static_pointer_cast<T>(asset->second);
    }

    auto asset = std::move(LoadAssetInternal(_path));
    if (!asset) {
        return nullptr;
    }

    m_assets[_path] = std::move(asset);

    return std::static_pointer_cast<T>(m_assets[_path]);
}

The problem is that when I call the LoadAsset method, the returned shared_ptr variable always has 2 strong ref when I delete the variable holding the resource the ref count goes to 1 and the resource is never freed by the end of the program.

Exemple:

auto tex = LoadAsset<Texture>("Data/Textures/Foo.tga"); // Strong refs = 2
tex = nullptr; // Strong refs = 1 and the loaded Foo.tga is never freed.

Brian Batista
  • 67
  • 1
  • 6
  • Can you make a [mcve]? – HolyBlackCat Dec 06 '19 at 13:31
  • 2
    You want to avoid reading only those resources of which you know that someone is still actively using them (and otherwise, you are willing to re-load the resource)? Then keep just a `weak_ptr` of the resource in your cache. – j6t Dec 06 '19 at 13:34
  • There are two owners of the shared object - `tex` and your cache table. – molbdnilo Dec 06 '19 at 13:36
  • 1
    If you don't want the `m_assets` container to keep objects alive, store `weak_ptr` in there instead of `shared_ptr`. Otherwise, you need to explicitly remove the reference from the asset cache. – Useless Dec 06 '19 at 13:39

1 Answers1

1

Just create a function that runs at the end of your games main loop. Something like this

void PurgeAssets() {
    for (auto i = m_assets.begin(); i != m_assets.end();) {
        if (i->second.unique()) {
            i = m_assets.erase(i);
        }
        else {
            ++i;
        }
    }
}
Girspoon
  • 96
  • 5