fixed main screen

This commit is contained in:
2025-12-17 18:13:59 +01:00
parent 3264672be0
commit cecf5cf68e
6 changed files with 479 additions and 147 deletions

122
src/app/AssetLoader.cpp Normal file
View File

@ -0,0 +1,122 @@
#include "app/AssetLoader.h"
#include <SDL3_image/SDL_image.h>
#include <algorithm>
AssetLoader::AssetLoader() = default;
AssetLoader::~AssetLoader() {
shutdown();
}
void AssetLoader::init(SDL_Renderer* renderer) {
m_renderer = renderer;
}
void AssetLoader::shutdown() {
// Destroy textures
{
std::lock_guard<std::mutex> lk(m_texturesMutex);
for (auto &p : m_textures) {
if (p.second) SDL_DestroyTexture(p.second);
}
m_textures.clear();
}
// Clear queue and errors
{
std::lock_guard<std::mutex> lk(m_queueMutex);
m_queue.clear();
}
{
std::lock_guard<std::mutex> lk(m_errorsMutex);
m_errors.clear();
}
m_totalTasks = 0;
m_loadedTasks = 0;
m_renderer = nullptr;
}
void AssetLoader::setBasePath(const std::string& basePath) {
m_basePath = basePath;
}
void AssetLoader::queueTexture(const std::string& path) {
{
std::lock_guard<std::mutex> lk(m_queueMutex);
m_queue.push_back(path);
}
m_totalTasks.fetch_add(1, std::memory_order_relaxed);
}
bool AssetLoader::performStep() {
std::string path;
{
std::lock_guard<std::mutex> lk(m_queueMutex);
if (m_queue.empty()) return true;
path = m_queue.front();
m_queue.erase(m_queue.begin());
}
{
std::lock_guard<std::mutex> lk(m_currentLoadingMutex);
m_currentLoading = path;
}
std::string fullPath = m_basePath.empty() ? path : (m_basePath + "/" + path);
SDL_Surface* surf = IMG_Load(fullPath.c_str());
if (!surf) {
std::lock_guard<std::mutex> lk(m_errorsMutex);
m_errors.push_back(std::string("IMG_Load failed: ") + fullPath + " -> " + SDL_GetError());
} else {
SDL_Texture* tex = SDL_CreateTextureFromSurface(m_renderer, surf);
SDL_DestroySurface(surf);
if (!tex) {
std::lock_guard<std::mutex> lk(m_errorsMutex);
m_errors.push_back(std::string("CreateTexture failed: ") + fullPath);
} else {
std::lock_guard<std::mutex> lk(m_texturesMutex);
m_textures[path] = tex;
}
}
m_loadedTasks.fetch_add(1, std::memory_order_relaxed);
{
std::lock_guard<std::mutex> lk(m_currentLoadingMutex);
m_currentLoading.clear();
}
// Return true when no more queued tasks
{
std::lock_guard<std::mutex> lk(m_queueMutex);
return m_queue.empty();
}
}
float AssetLoader::getProgress() const {
int total = m_totalTasks.load(std::memory_order_relaxed);
if (total <= 0) return 1.0f;
int loaded = m_loadedTasks.load(std::memory_order_relaxed);
return static_cast<float>(loaded) / static_cast<float>(total);
}
std::vector<std::string> AssetLoader::getAndClearErrors() {
std::lock_guard<std::mutex> lk(m_errorsMutex);
std::vector<std::string> out = m_errors;
m_errors.clear();
return out;
}
SDL_Texture* AssetLoader::getTexture(const std::string& path) const {
std::lock_guard<std::mutex> lk(m_texturesMutex);
auto it = m_textures.find(path);
if (it == m_textures.end()) return nullptr;
return it->second;
}
std::string AssetLoader::getCurrentLoading() const {
std::lock_guard<std::mutex> lk(m_currentLoadingMutex);
return m_currentLoading;
}

64
src/app/AssetLoader.h Normal file
View File

@ -0,0 +1,64 @@
#pragma once
#include <SDL3/SDL.h>
#include <string>
#include <vector>
#include <mutex>
#include <atomic>
#include <unordered_map>
// Lightweight AssetLoader scaffold.
// Responsibilities:
// - Queue textures to load (main thread) and perform incremental loads via performStep().
// - Store loaded SDL_Texture* instances and provide accessors.
// - Collect loading errors thread-safely.
// NOTE: All SDL texture creation MUST happen on the thread that owns the SDL_Renderer.
class AssetLoader {
public:
AssetLoader();
~AssetLoader();
void init(SDL_Renderer* renderer);
void shutdown();
void setBasePath(const std::string& basePath);
// Queue a texture path (relative to base path) for loading.
void queueTexture(const std::string& path);
// Perform a single loading step (load one queued asset).
// Returns true when all queued tasks are complete, false otherwise.
bool performStep();
// Progress in [0,1]. If no tasks, returns 1.0f.
float getProgress() const;
// Retrieve and clear accumulated error messages.
std::vector<std::string> getAndClearErrors();
// Get a loaded texture (or nullptr if not loaded).
SDL_Texture* getTexture(const std::string& path) const;
// Return currently-loading path (empty when idle).
std::string getCurrentLoading() const;
private:
SDL_Renderer* m_renderer = nullptr;
std::string m_basePath;
// queued paths (simple FIFO)
std::vector<std::string> m_queue;
mutable std::mutex m_queueMutex;
std::unordered_map<std::string, SDL_Texture*> m_textures;
mutable std::mutex m_texturesMutex;
std::vector<std::string> m_errors;
mutable std::mutex m_errorsMutex;
std::atomic<int> m_totalTasks{0};
std::atomic<int> m_loadedTasks{0};
std::string m_currentLoading;
mutable std::mutex m_currentLoadingMutex;
};