/* * ResourceManager.cpp * * Created on: Nov 7, 2016 * Author: tibi */ #include #include #include #include #include #include #include #include #define FONTID(id,size) (id * 1000 + size) #define FONTID_SIZE(fontid) (fontid % 1000) #define FONTID_ID(fontid) (fontid / 1000) using namespace farmlands::graphics::backend; namespace farmlands { namespace resources { ResourceManager ResourceManager::s_instance; ResourceManager& ResourceManager::instance() { return s_instance; } ResourceManager::ResourceManager() : m_loadedResources(new LoadedResource[sizeof(RInfo) / sizeof(RInfo[0])]) { for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++) m_loadedResources[i].loaded = false; } ResourceManager::~ResourceManager() { // Unload resources for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++) { if (m_loadedResources[i].loaded) { switch(RInfo[i].type) { case ResourceType::Texture: SDL_DestroyTexture(m_loadedResources[i].texture.texture); SDL_FreeSurface(m_loadedResources[i].texture.surface); break; default: std::cerr << "Warning: Cannot free resource " << i << " of type " << (int)RInfo[i].type << "\n"; break; } } } delete[] m_loadedResources; // Unload fonts for (auto pair : m_fontCache) { TTF_CloseFont(pair.second); } } void ResourceManager::initialize() { } void ResourceManager::loadMainMenu() { } void ResourceManager::loadGame() { GameState::current().config = storage::parse(R::Config::Default); GameState::current().scene = storage::parse(R::Scenes::Game); GameState::current().scene->root.onCreate(); storage::parseCollection(R::Items::Tools, GameState::current().itemPrefabs); storage::parseCollection(R::Items::Weapons, GameState::current().itemPrefabs); } std::string ResourceManager::getPath(ResourceId resourceId) { Assert(resourceId >= 0 && resourceId < sizeof(RInfo) / sizeof(RInfo[0]), "Resource id out of bounds."); boost::filesystem::path resPath(ASSETS_DIR); resPath.append(RInfo[resourceId].path); return resPath.native(); } ResourceId ResourceManager::getId(std::string resPathStr) { boost::filesystem::path resPath(resPathStr); for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++) { boost::filesystem::path iPath (RInfo[i].path); if (resPath == iPath) return i; } return (ResourceId)-1; } TTF_Font* ResourceManager::font(ResourceId fontId, int pointSize) { Assert(RInfo[fontId].type == ResourceType::Font, "Resource must be a font"); // Do not load if already loaded auto it = m_fontCache.find(FONTID(fontId, pointSize)); if (it != m_fontCache.end()) return it->second; // Open font std::string fontPath = getPath(fontId); TTF_Font* font = TTF_OpenFont(fontPath.c_str(), pointSize); if (!font) THROW(utils::ResourceLoadException, "Could not load font " + fontPath); // Cache font m_fontCache.emplace(FONTID(fontId, pointSize), font); return font; } SDL_Texture* ResourceManager::texture(ResourceId textureId) { Assert(RInfo[textureId].type == ResourceType::Texture, "Resource must be a texture"); // See if already loaded if (!m_loadedResources[textureId].loaded) { // Open file std::string texturePath = getPath(textureId); SDL_Surface* surface = IMG_Load(texturePath.c_str()); if (surface == NULL) THROW(utils::ResourceLoadException, "Failed to load texture " + texturePath); SDL_Texture* texture = SDL_CreateTextureFromSurface(SdlRenderer::instance().internalRenderer(), surface); if (texture == NULL) THROW(utils::ResourceLoadException, "Failed to create texture " + texturePath); // Add to loaded resources m_loadedResources[textureId].texture.surface = surface; m_loadedResources[textureId].texture.texture = texture; m_loadedResources[textureId].loaded = true; } return m_loadedResources[textureId].texture.texture; } } /* namespace storage */ } /* namespace farmlands */