Files
spacetris/src/core/AssetManager.h

129 lines
4.4 KiB
C++

#pragma once
#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <string>
#include <unordered_map>
#include <memory>
#include <functional>
// Forward declarations
class FontAtlas;
class Audio;
class SoundEffectManager;
/**
* AssetManager - Centralized resource management following SOLID principles
*
* Responsibilities:
* - Texture loading and management (BMP, PNG via SDL)
* - Font loading and caching (TTF via FontAtlas)
* - Audio resource coordination (MP3 via Audio, WAV via SoundEffectManager)
* - Resource lifecycle management (loading, caching, cleanup)
* - Error handling and fallback mechanisms
*
* Design Principles:
* - Single Responsibility: Only handles asset loading/management
* - Open/Closed: Easy to extend with new asset types
* - Dependency Inversion: Uses interfaces for audio systems
* - Interface Segregation: Separate methods for different asset types
*/
class AssetManager {
public:
AssetManager();
~AssetManager();
// Lifecycle management
bool initialize(SDL_Renderer* renderer);
void shutdown();
// Texture management
SDL_Texture* loadTexture(const std::string& id, const std::string& filepath);
SDL_Texture* getTexture(const std::string& id) const;
bool unloadTexture(const std::string& id);
void setDefaultTexturePath(const std::string& path) { m_defaultTexturePath = path; }
// Font management
bool loadFont(const std::string& id, const std::string& filepath, int baseSize = 24);
FontAtlas* getFont(const std::string& id) const;
bool unloadFont(const std::string& id);
void setDefaultFontPath(const std::string& path) { m_defaultFontPath = path; }
// Audio management (coordinates with existing Audio and SoundEffectManager)
bool loadMusicTrack(const std::string& filepath);
bool loadSoundEffect(const std::string& id, const std::string& filepath);
bool loadSoundEffectWithFallback(const std::string& id, const std::string& baseName);
void startBackgroundMusicLoading();
bool isMusicLoadingComplete() const;
int getLoadedMusicTrackCount() const;
// Batch loading operations
struct LoadingTask {
enum Type { TEXTURE, FONT, MUSIC, SOUND_EFFECT };
Type type;
std::string id;
std::string filepath;
int fontSize = 24; // For fonts only
};
void addLoadingTask(const LoadingTask& task);
void executeLoadingTasks(std::function<void(float)> progressCallback = nullptr);
void clearLoadingTasks();
void update(float deltaTime); // New: Progressive loading update
// Loading progress tracking
bool isLoadingComplete() const;
float getLoadingProgress() const;
size_t getTotalLoadingTasks() const { return m_totalLoadingTasks; }
size_t getCompletedLoadingTasks() const { return m_completedLoadingTasks; }
// Resource queries
size_t getTextureCount() const { return m_textures.size(); }
size_t getFontCount() const { return m_fonts.size(); }
bool isResourceLoaded(const std::string& id) const;
// Error handling
std::string getLastError() const { return m_lastError; }
void clearLastError() { m_lastError.clear(); }
// Asset path utilities
static std::string getAssetPath(const std::string& relativePath);
static bool fileExists(const std::string& filepath);
private:
// Resource storage
std::unordered_map<std::string, SDL_Texture*> m_textures;
std::unordered_map<std::string, std::unique_ptr<FontAtlas>> m_fonts;
std::vector<LoadingTask> m_loadingTasks;
// Loading progress tracking
size_t m_totalLoadingTasks = 0;
size_t m_completedLoadingTasks = 0;
bool m_loadingComplete = false;
// Progressive loading state
bool m_isProgressiveLoading = false;
size_t m_currentTaskIndex = 0;
Uint64 m_lastLoadTime = 0;
bool m_musicLoadingStarted = false;
float m_musicLoadingProgress = 0.0f;
// System references
SDL_Renderer* m_renderer;
Audio* m_audioSystem; // Pointer to singleton
SoundEffectManager* m_soundSystem; // Pointer to singleton
// Configuration
std::string m_defaultTexturePath;
std::string m_defaultFontPath;
std::string m_lastError;
bool m_initialized;
// Helper methods
SDL_Texture* loadTextureFromFile(const std::string& filepath);
bool validateRenderer() const;
void setError(const std::string& error);
void logInfo(const std::string& message) const;
void logError(const std::string& message) const;
};