move into firmware subfolder
Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
108
firmware/src/manager/ResourceManager.cpp
Normal file
108
firmware/src/manager/ResourceManager.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "ResourceManager.h"
|
||||
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
#include <memory>
|
||||
#include <ranges>
|
||||
|
||||
ResourceManager &ResourceManager::Instance()
|
||||
{
|
||||
static ResourceManager instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
ResourceManager::ResourceManager()
|
||||
{
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "ResourceManager instance created.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor for the ResourceManager
|
||||
* Cleans up all loaded textures and frees memory
|
||||
*/
|
||||
ResourceManager::~ResourceManager()
|
||||
{
|
||||
for (const auto &texture : m_textures | std::views::values)
|
||||
{
|
||||
if (texture != nullptr)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
}
|
||||
m_textures.clear();
|
||||
}
|
||||
|
||||
std::string ResourceManager::GetResourcePath(const std::string &fileName)
|
||||
{
|
||||
const auto basePath_c = SDL_GetBasePath();
|
||||
if (!basePath_c)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error retrieving base path: %s", SDL_GetError());
|
||||
// Fallback to relative path as a last resort
|
||||
// Warning: This only works reliably if the working directory is correct
|
||||
// (e.g., when debugging from IDE)
|
||||
return fileName; // Fallback (unsafe)
|
||||
}
|
||||
|
||||
const std::string basePath(basePath_c);
|
||||
|
||||
std::string fullPath = basePath;
|
||||
#ifdef __APPLE__
|
||||
// Special handling for macOS bundle structure
|
||||
// Navigate from /Contents/MacOS/ to /Contents/Resources/
|
||||
size_t lastSlash = fullPath.find_last_of('/');
|
||||
if (lastSlash != std::string::npos)
|
||||
{
|
||||
fullPath = fullPath.substr(0, lastSlash); // Remove executable name
|
||||
lastSlash = fullPath.find_last_of('/');
|
||||
if (lastSlash != std::string::npos)
|
||||
{
|
||||
fullPath = fullPath.substr(0, lastSlash + 1); // Go to Contents folder
|
||||
fullPath += "Resources/";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback if structure is unexpected
|
||||
fullPath = basePath; // Use original base path
|
||||
fullPath += "Resources/"; // And try with this
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback for unexpected path structure
|
||||
fullPath = basePath;
|
||||
fullPath += "Resources/";
|
||||
}
|
||||
#else
|
||||
// For other platforms (Windows, Linux, etc.)
|
||||
// Use standard assets folder
|
||||
fullPath += "assets/";
|
||||
#endif
|
||||
|
||||
return fullPath + fileName;
|
||||
}
|
||||
|
||||
|
||||
SDL_Texture *ResourceManager::GetTextureByName(SDL_Renderer *renderer, const std::string &path)
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
// Check if texture is already in cache
|
||||
if (const auto search = m_textures.find(GetResourcePath(path)); search != m_textures.end())
|
||||
{
|
||||
return search->second;
|
||||
}
|
||||
|
||||
// Load new texture
|
||||
SDL_Texture *texture = IMG_LoadTexture(renderer, GetResourcePath(path).c_str());
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load %s -> %s", GetResourcePath(path).c_str(),
|
||||
SDL_GetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Store texture in cache
|
||||
m_textures[path] = texture;
|
||||
return texture;
|
||||
}
|
59
firmware/src/manager/ResourceManager.h
Normal file
59
firmware/src/manager/ResourceManager.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
class ResourceManager
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Returns the singleton instance of the ResourceManager
|
||||
* @return Reference to the ResourceManager instance
|
||||
*/
|
||||
static ResourceManager &Instance();
|
||||
|
||||
ResourceManager(const ResourceManager &) = delete;
|
||||
ResourceManager &operator=(const ResourceManager &) = delete;
|
||||
ResourceManager(ResourceManager &&) = delete;
|
||||
ResourceManager &operator=(ResourceManager &&) = delete;
|
||||
|
||||
~ResourceManager();
|
||||
|
||||
/**
|
||||
* @brief Loads a texture or returns an already loaded texture
|
||||
* @param renderer The SDL_Renderer used to load the texture
|
||||
* @param path Path to the texture file (relative to resource directory)
|
||||
* @return Pointer to the loaded SDL_Texture or nullptr on error
|
||||
*
|
||||
* This function implements a caching system for textures. If a texture
|
||||
* has already been loaded, it returns it from the cache. Otherwise,
|
||||
* it loads the texture and stores it in the cache. Access is thread-safe
|
||||
* through mutex protection.
|
||||
*/
|
||||
SDL_Texture *GetTextureByName(SDL_Renderer *renderer, const std::string &path);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Constructor for the ResourceManager
|
||||
* Initializes a new instance and logs its creation
|
||||
*/
|
||||
ResourceManager();
|
||||
|
||||
/**
|
||||
* @brief Determines the full resource path for a file
|
||||
* @param fileName Name of the resource file
|
||||
* @return Complete path to the resource
|
||||
*
|
||||
* This function handles platform-specific paths (especially macOS) and
|
||||
* constructs the correct path to resources. For macOS, it considers the
|
||||
* bundle structure (.app/Contents/Resources/).
|
||||
*/
|
||||
static std::string GetResourcePath(const std::string &fileName);
|
||||
|
||||
std::unordered_map<std::string, SDL_Texture *> m_textures;
|
||||
|
||||
mutable std::mutex m_mutex;
|
||||
};
|
Reference in New Issue
Block a user