#pragma once #include #include #include #include #include #include // 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 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 m_textures; std::unordered_map> m_fonts; std::vector 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; };