fixed main screen
This commit is contained in:
122
src/app/AssetLoader.cpp
Normal file
122
src/app/AssetLoader.cpp
Normal 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
64
src/app/AssetLoader.h
Normal 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;
|
||||
};
|
||||
Reference in New Issue
Block a user