I disagree with Vittorio about not needing shared ownership of resources and, while I dislike the implementation of shared_ptr
, it can be made to work just fine.
You want shared ownership because, of course, multiple game objects might be using the same resource. More importantly, if you have multiple levels and want to minimum level loading, you need some way to compute the union and intersection of resources needed by both.
One way to do this, which does require something more than just a shared_ptr
, is to allow "loading" a level without resources and letting it take shared ownership of resources it needs. Then unload the old level, removing its ownership. Then, for any resource that still has ownership active but isn't loaded, load the resource.
For a resource A needed by levels 1 and 2, the reference count goes something like:
load level 1
ref=1
load A
load level 2
ref=2
unload level 1
ref=1
For a resource B used by only level 1, it goes like:
load level 1
ref=1
load B
load level 2
ref=1
unload level 1
ref=0 (removed)
And a resource C used by only level 2, it goes like:
load level 1
ref=0 (implicit, as no resource C exists)
load level 2
ref=1
unload level 1
load C
One method might be to have a layer of indirection. You store shared_ptr
to a ResourceHolder
. These holders are also in a list of some kind. When loading a level, you create and hold on to these ResourceHolder
objects. They contain a unique_ptr
to the actual resource (initially nullptr
) and the path or other information needed to eventually load the item.
After loading the new level and unloading the old, you can then iterate through the list of live ResourceHolder
objects, find any that have a nullptr
handle to the actual resource, and then load it. When the shared_ptr
to a ResourceHolder
hits a ref count of 0 and unloads it, it also naturally frees the resource, and you should ensure that it removes itself from the list of live resources.
You can do much better than shared_ptr
but it's a perfectly fine place to start to get up and running. Optimize it into something better later on once you have a working game.