#pragma once #include <memory> #include <unordered_map> #include "../Resource.h" #include "../api/Asset.h" #include "Manager.h" namespace crepe { /** * \brief Owner of concrete Resource instances * * ResourceManager caches concrete Resource instances per Asset. Concrete resources are * destroyed at the end of scenes by default, unless the game programmer marks them as * persistent. */ class ResourceManager : public Manager { public: ResourceManager(Mediator & mediator); virtual ~ResourceManager(); // dbg_trace private: //! Cache entry struct CacheEntry { //! Concrete resource instance std::unique_ptr<Resource> resource = nullptr; //! Prevent ResourceManager::clear from removing this entry bool persistent = false; }; //! Internal cache std::unordered_map<const Asset, CacheEntry> resources; /** * \brief Ensure a cache entry exists for this asset and return a mutable reference to it * * \param asset Asset the concrete resource is instantiated from * * \returns Mutable reference to cache entry */ CacheEntry & get_entry(const Asset & asset); public: /** * \brief Mark a resource as persistent (i.e. used across multiple scenes) * * \param asset Asset the concrete resource is instantiated from * \param persistent Whether this resource is persistent (true=keep, false=destroy) */ void set_persistent(const Asset & asset, bool persistent); /** * \brief Retrieve reference to concrete Resource by Asset * * \param asset Asset the concrete resource is instantiated from * \tparam Resource Concrete derivative of Resource * * This class instantiates the concrete resource if it is not yet stored in the internal * cache, or returns a reference to the cached resource if it already exists. * * \returns Reference to concrete resource * * \throws std::runtime_error if the \c Resource parameter does not match with the actual * type of the resource stored in the cache for this Asset */ template <typename Resource> Resource & get(const Asset & asset); //! Clear non-persistent resources from cache void clear(); //! Clear all resources from cache regardless of persistence void clear_all(); }; } // namespace crepe #include "ResourceManager.hpp"