#ifndef ResourceManager_h__ #define ResourceManager_h__ #include #include #include #include #include "Util/UnorderedMapPair.h" #include "Factory.h" class Resource { public: unsigned int TypeID; unsigned int ResourceID; }; class ResourceManager { public: ResourceManager() : m_CurrentResourceTypeID(0), m_Preloading(false) { } // Registers the factory function of a resource type void RegisterType(std::string resourceType, std::function factoryFunction); // Loads a resource and caches it for future use void Preload(std::string resourceType, std::string resourceName); // Checks if a resource is in cache bool IsResourceLoaded(std::string resourceType, std::string resourceName); template // Hot-loads a resource and caches it for future use T* Load(std::string resourceType, std::string resourceName); template // Fetches a preloaded resource T* Fetch(std::string resourceName) const; private: std::unordered_map> m_FactoryFunctions; // type -> factory function std::unordered_map, Resource*> m_ResourceCache; // (type, name) -> resource // TODO: Getters for IDs unsigned int m_CurrentResourceTypeID; std::unordered_map m_ResourceTypeIDs; // Number of resources of a type. Doubles as local ID. std::unordered_map m_ResourceCount; // Flag to suppress hot-load warnings when a preloading resource chain loads another resource bool m_Preloading; unsigned int GetTypeID(std::string resourceType); unsigned int GetNewResourceID(unsigned int typeID); // Internal: Create a resource and cache it Resource* CreateResource(std::string resourceType, std::string resourceName); }; template T* ResourceManager::Load(std::string resourceType, std::string resourceName) { auto it = m_ResourceCache.find(std::make_pair(resourceType, resourceName)); if (it != m_ResourceCache.end()) return static_cast(it->second); if (m_Preloading) { LOG_INFO("Preloading resource \"%s\"", resourceName.c_str()); } else { LOG_WARNING("Hot-loading resource \"%s\"", resourceName.c_str()); } return static_cast(CreateResource(resourceType, resourceName)); } template T* ResourceManager::Fetch(std::string resourceName) const { auto it = m_ResourceCache.find(std::make_pair(resourceType, resourceName)); if (it == m_ResourceCache.end()) { LOG_ERROR("Failed to fetch resource \"%s\": Resource not loaded!", resourceName.c_str()); return nullptr; } else { return static_cast(it->second); } } #endif // ResourceManager_h__