diff --git a/.gitignore b/.gitignore index 8bba2aa..a9acd58 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ CMakeCache.txt cmake_install.cmake Makefile +settings.ini # vcpkg /vcpkg_installed/ @@ -70,7 +71,4 @@ dist_package/ # Local environment files (if any) .env -# Ignore local settings file -settings.ini - # End of .gitignore diff --git a/CMakeLists.txt b/CMakeLists.txt index e64436a..b776fa0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,8 @@ set(TETRIS_SOURCES src/graphics/renderers/SyncLineRenderer.cpp src/graphics/renderers/UIRenderer.cpp src/audio/Audio.cpp + src/audio/AudioManager.cpp + src/renderer/SDLRenderer.cpp src/gameplay/effects/LineEffect.cpp src/audio/SoundEffect.cpp src/video/VideoPlayer.cpp @@ -66,6 +68,7 @@ set(TETRIS_SOURCES src/app/Fireworks.cpp src/app/AssetLoader.cpp src/app/TextureLoader.cpp + src/resources/ResourceManager.cpp src/states/LoadingManager.cpp # State implementations (new) src/states/LoadingState.cpp @@ -201,6 +204,20 @@ if(EXISTS "${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows/include") target_include_directories(spacetris_tests PRIVATE "${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows/include") endif() +# GoogleTest-based board unit tests +find_package(GTest CONFIG REQUIRED) +add_executable(test_board + tests/test_board.cpp + src/logic/Board.cpp +) +target_include_directories(test_board PRIVATE ${CMAKE_SOURCE_DIR}/src) +target_link_libraries(test_board PRIVATE GTest::gtest_main) +add_test(NAME BoardTests COMMAND test_board) + +if(EXISTS "${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows/include") + target_include_directories(test_board PRIVATE "${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows/include") +endif() + # Add new src subfolders to include path so old #includes continue to work target_include_directories(spacetris PRIVATE ${CMAKE_SOURCE_DIR}/src diff --git a/src/app/AssetLoader.cpp b/src/app/AssetLoader.cpp index 95d060e..c9ca0c0 100644 --- a/src/app/AssetLoader.cpp +++ b/src/app/AssetLoader.cpp @@ -1,6 +1,10 @@ #include "app/AssetLoader.h" #include #include +#include "app/TextureLoader.h" + +#include "utils/ImagePathResolver.h" +#include AssetLoader::AssetLoader() = default; @@ -37,6 +41,10 @@ void AssetLoader::shutdown() { m_renderer = nullptr; } +void AssetLoader::setResourceManager(resources::ResourceManager* mgr) { + m_resourceManager = mgr; +} + void AssetLoader::setBasePath(const std::string& basePath) { m_basePath = basePath; } @@ -65,24 +73,25 @@ bool AssetLoader::performStep() { std::string fullPath = m_basePath.empty() ? path : (m_basePath + "/" + path); - SDL_Surface* surf = IMG_Load(fullPath.c_str()); - if (!surf) { - std::lock_guard lk(m_errorsMutex); - m_errors.push_back(std::string("IMG_Load failed: ") + fullPath + " -> " + SDL_GetError()); + // Diagnostic: resolve path and check file existence + const std::string resolved = AssetPath::resolveImagePath(path); + bool exists = false; + try { if (!resolved.empty()) exists = std::filesystem::exists(std::filesystem::u8path(resolved)); } catch (...) { exists = false; } + + // Use TextureLoader to centralize loading and ResourceManager caching + TextureLoader loader(m_loadedTasks, m_currentLoading, m_currentLoadingMutex, m_errors, m_errorsMutex); + loader.setResourceManager(m_resourceManager); + // Pass the original queued path (not the full resolved path) so caching keys stay consistent + SDL_Texture* tex = loader.loadFromImage(m_renderer, path); + if (!tex) { + // errors have been recorded by TextureLoader } else { - SDL_Texture* tex = SDL_CreateTextureFromSurface(m_renderer, surf); - SDL_DestroySurface(surf); - if (!tex) { - std::lock_guard lk(m_errorsMutex); - m_errors.push_back(std::string("CreateTexture failed: ") + fullPath); - } else { - std::lock_guard lk(m_texturesMutex); - auto& slot = m_textures[path]; - if (slot && slot != tex) { - SDL_DestroyTexture(slot); - } - slot = tex; + std::lock_guard lk(m_texturesMutex); + auto& slot = m_textures[path]; + if (slot && slot != tex) { + SDL_DestroyTexture(slot); } + slot = tex; } m_loadedTasks.fetch_add(1, std::memory_order_relaxed); @@ -104,12 +113,17 @@ void AssetLoader::adoptTexture(const std::string& path, SDL_Texture* texture) { return; } + // register in local map and resource manager std::lock_guard lk(m_texturesMutex); auto& slot = m_textures[path]; if (slot && slot != texture) { SDL_DestroyTexture(slot); } slot = texture; + if (m_resourceManager) { + std::shared_ptr sp(texture, [](void* t){ SDL_DestroyTexture(static_cast(t)); }); + m_resourceManager->put(path, sp); + } } float AssetLoader::getProgress() const { diff --git a/src/app/AssetLoader.h b/src/app/AssetLoader.h index fac6128..5ab6470 100644 --- a/src/app/AssetLoader.h +++ b/src/app/AssetLoader.h @@ -6,6 +6,7 @@ #include #include #include +#include "../resources/ResourceManager.h" // Lightweight AssetLoader scaffold. // Responsibilities: @@ -22,6 +23,7 @@ public: void shutdown(); void setBasePath(const std::string& basePath); + void setResourceManager(resources::ResourceManager* mgr); // Queue a texture path (relative to base path) for loading. void queueTexture(const std::string& path); @@ -49,6 +51,7 @@ public: private: SDL_Renderer* m_renderer = nullptr; std::string m_basePath; + resources::ResourceManager* m_resourceManager = nullptr; // queued paths (simple FIFO) std::vector m_queue; diff --git a/src/app/TetrisApp.cpp b/src/app/TetrisApp.cpp index 0bd4d0b..c4bc0eb 100644 --- a/src/app/TetrisApp.cpp +++ b/src/app/TetrisApp.cpp @@ -31,6 +31,7 @@ #include "audio/Audio.h" #include "audio/MenuWrappers.h" #include "audio/SoundEffect.h" +#include "audio/AudioManager.h" #include "core/Config.h" #include "core/Settings.h" @@ -68,6 +69,7 @@ #include "ui/MenuLayout.h" #include "utils/ImagePathResolver.h" +#include "../resources/ResourceManager.h" // ---------- Game config ---------- static constexpr int LOGICAL_W = 1200; @@ -187,6 +189,7 @@ struct TetrisApp::Impl { AssetLoader assetLoader; std::unique_ptr loadingManager; std::unique_ptr textureLoader; + resources::ResourceManager resourceManager; FontAtlas pixelFont; FontAtlas font; @@ -427,6 +430,8 @@ int TetrisApp::Impl::init() // Asset loader (creates SDL_Textures on the main thread) assetLoader.init(renderer); + // Wire resource manager into loader so textures are cached and reused + assetLoader.setResourceManager(&resourceManager); loadingManager = std::make_unique(&assetLoader); // Legacy image loader (used only as a fallback when AssetLoader misses) @@ -436,6 +441,8 @@ int TetrisApp::Impl::init() currentLoadingMutex, assetLoadErrors, assetLoadErrorsMutex); + // Let legacy TextureLoader access the same resource cache + textureLoader->setResourceManager(&resourceManager); // Load scores asynchronously but keep the worker alive until shutdown scoreLoader = std::jthread([this]() { @@ -841,17 +848,19 @@ void TetrisApp::Impl::runLoop() if (e.type == SDL_EVENT_KEY_DOWN && !e.key.repeat) { if (e.key.scancode == SDL_SCANCODE_M) { - Audio::instance().toggleMute(); + if (auto sys = AudioManager::get()) sys->toggleMute(); musicEnabled = !musicEnabled; Settings::instance().setMusicEnabled(musicEnabled); } if (e.key.scancode == SDL_SCANCODE_N) { - Audio::instance().skipToNextTrack(); - if (!musicStarted && Audio::instance().getLoadedTrackCount() > 0) { - musicStarted = true; - musicEnabled = true; - Settings::instance().setMusicEnabled(true); + if (auto sys = AudioManager::get()) { + sys->skipToNextTrack(); + if (!musicStarted && sys->getLoadedTrackCount() > 0) { + musicStarted = true; + musicEnabled = true; + Settings::instance().setMusicEnabled(true); + } } } // K: Toggle sound effects (S is reserved for co-op movement) @@ -1316,10 +1325,14 @@ void TetrisApp::Impl::runLoop() game->softDropBoost(frameMs); if (musicLoadingStarted && !musicLoaded) { - currentTrackLoading = Audio::instance().getLoadedTrackCount(); - if (Audio::instance().isLoadingComplete() || (totalTracks > 0 && currentTrackLoading >= totalTracks)) { - Audio::instance().shuffle(); - musicLoaded = true; + if (auto sys = AudioManager::get()) { + currentTrackLoading = sys->getLoadedTrackCount(); + if (sys->isLoadingComplete() || (totalTracks > 0 && currentTrackLoading >= totalTracks)) { + sys->shuffle(); + musicLoaded = true; + } + } else { + currentTrackLoading = 0; } } @@ -1706,21 +1719,27 @@ void TetrisApp::Impl::runLoop() currentLoadingFile.clear(); } - Audio::instance().init(); - totalTracks = 0; - for (int i = 1; i <= 100; ++i) { - char base[128]; - std::snprintf(base, sizeof(base), "assets/music/music%03d", i); - std::string path = AssetPath::resolveWithExtensions(base, { ".mp3" }); - if (path.empty()) break; - Audio::instance().addTrackAsync(path); - totalTracks++; - } - totalLoadingTasks.store(baseTasks + totalTracks); - if (totalTracks > 0) { - Audio::instance().startBackgroundLoading(); - musicLoadingStarted = true; + if (auto sys = AudioManager::get()) { + sys->init(); + totalTracks = 0; + for (int i = 1; i <= 100; ++i) { + char base[128]; + std::snprintf(base, sizeof(base), "assets/music/music%03d", i); + std::string path = AssetPath::resolveWithExtensions(base, { ".mp3" }); + if (path.empty()) break; + sys->addTrackAsync(path); + totalTracks++; + } + totalLoadingTasks.store(baseTasks + totalTracks); + if (totalTracks > 0) { + sys->startBackgroundLoading(); + musicLoadingStarted = true; + } else { + musicLoaded = true; + } } else { + totalTracks = 0; + totalLoadingTasks.store(baseTasks + totalTracks); musicLoaded = true; } @@ -1785,6 +1804,8 @@ void TetrisApp::Impl::runLoop() nextPanelTex = assetLoader.getTexture(Assets::NEXT_PANEL); holdPanelTex = assetLoader.getTexture(Assets::HOLD_PANEL); + // texture retrieval diagnostics removed + auto ensureTextureSize = [&](SDL_Texture* tex, int& outW, int& outH) { if (!tex) return; if (outW > 0 && outH > 0) return; @@ -1871,10 +1892,20 @@ void TetrisApp::Impl::runLoop() if (totalTracks > 0) { musicProgress = musicLoaded ? 0.7 : std::min(0.7, (double)currentTrackLoading / totalTracks * 0.7); } else { - if (Audio::instance().isLoadingComplete()) { - musicProgress = 0.7; - } else if (Audio::instance().getLoadedTrackCount() > 0) { - musicProgress = 0.35; + if (auto sys = AudioManager::get()) { + if (sys->isLoadingComplete()) { + musicProgress = 0.7; + } else if (sys->getLoadedTrackCount() > 0) { + musicProgress = 0.35; + } else { + Uint32 elapsedMs = SDL_GetTicks() - static_cast(loadStart); + if (elapsedMs > 1500) { + musicProgress = 0.7; + musicLoaded = true; + } else { + musicProgress = 0.0; + } + } } else { Uint32 elapsedMs = SDL_GetTicks() - static_cast(loadStart); if (elapsedMs > 1500) { @@ -1916,7 +1947,7 @@ void TetrisApp::Impl::runLoop() menuTrackLoader = std::jthread([]() { std::string menuTrack = AssetPath::resolveWithExtensions("assets/music/Every Block You Take", { ".mp3" }); if (!menuTrack.empty()) { - Audio::instance().setMenuTrack(menuTrack); + if (auto sys = AudioManager::get()) sys->setMenuTrack(menuTrack); } else { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Menu track not found (Every Block You Take)"); } @@ -1925,9 +1956,9 @@ void TetrisApp::Impl::runLoop() } if (state == AppState::Menu) { - Audio::instance().playMenuMusic(); + if (auto sys = AudioManager::get()) sys->playMenuMusic(); } else { - Audio::instance().playGameMusic(); + if (auto sys = AudioManager::get()) sys->playGameMusic(); } musicStarted = true; } @@ -1936,9 +1967,9 @@ void TetrisApp::Impl::runLoop() static AppState previousState = AppState::Loading; if (state != previousState && musicStarted) { if (state == AppState::Menu && previousState == AppState::Playing) { - Audio::instance().playMenuMusic(); + if (auto sys = AudioManager::get()) sys->playMenuMusic(); } else if (state == AppState::Playing && previousState == AppState::Menu) { - Audio::instance().playGameMusic(); + if (auto sys = AudioManager::get()) sys->playGameMusic(); } } previousState = state; @@ -2712,7 +2743,7 @@ void TetrisApp::Impl::shutdown() } lineEffect.shutdown(); - Audio::instance().shutdown(); + if (auto sys = AudioManager::get()) sys->shutdown(); SoundEffectManager::instance().shutdown(); // Destroy textures before tearing down the renderer/window. diff --git a/src/app/TextureLoader.cpp b/src/app/TextureLoader.cpp index ef9af8e..75d1bf4 100644 --- a/src/app/TextureLoader.cpp +++ b/src/app/TextureLoader.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include "utils/ImagePathResolver.h" TextureLoader::TextureLoader( @@ -45,6 +47,18 @@ SDL_Texture* TextureLoader::loadFromImage(SDL_Renderer* renderer, const std::str const std::string resolvedPath = AssetPath::resolveImagePath(path); setCurrentLoadingFile(resolvedPath.empty() ? path : resolvedPath); + // Check filesystem existence for diagnostics (no console log) + bool fileExists = false; + try { if (!resolvedPath.empty()) fileExists = std::filesystem::exists(std::filesystem::u8path(resolvedPath)); } catch (...) { fileExists = false; } + // If resource manager provided, check cache first using the original asset key (path) + if (resourceManager_) { + if (auto sp = resourceManager_->get(path)) { + clearCurrentLoadingFile(); + loadedTasks_.fetch_add(1); + return sp.get(); + } + } + SDL_Surface* surface = IMG_Load(resolvedPath.c_str()); if (!surface) { { @@ -54,7 +68,7 @@ SDL_Texture* TextureLoader::loadFromImage(SDL_Renderer* renderer, const std::str } loadedTasks_.fetch_add(1); clearCurrentLoadingFile(); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load image %s (resolved: %s): %s", path.c_str(), resolvedPath.c_str(), SDL_GetError()); + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load image %s (resolved: %s) exists=%s: %s", path.c_str(), resolvedPath.c_str(), fileExists ? "yes" : "no", SDL_GetError()); return nullptr; } @@ -66,6 +80,7 @@ SDL_Texture* TextureLoader::loadFromImage(SDL_Renderer* renderer, const std::str } SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); + // surface size preserved in outW/outH; no console log SDL_DestroySurface(surface); if (!texture) { @@ -80,6 +95,15 @@ SDL_Texture* TextureLoader::loadFromImage(SDL_Renderer* renderer, const std::str return nullptr; } + // No texture-size console diagnostics here + + // cache in resource manager if present + if (resourceManager_) { + std::shared_ptr sp(texture, [](void* t){ SDL_DestroyTexture(static_cast(t)); }); + // store under original asset key (path) so callers using logical asset names find them + resourceManager_->put(path, sp); + } + loadedTasks_.fetch_add(1); clearCurrentLoadingFile(); diff --git a/src/app/TextureLoader.h b/src/app/TextureLoader.h index d807fe7..1fbaca7 100644 --- a/src/app/TextureLoader.h +++ b/src/app/TextureLoader.h @@ -6,6 +6,7 @@ #include #include #include +#include "../resources/ResourceManager.h" class TextureLoader { public: @@ -16,6 +17,8 @@ public: std::vector& assetLoadErrors, std::mutex& assetLoadErrorsMutex); + void setResourceManager(resources::ResourceManager* mgr) { resourceManager_ = mgr; } + SDL_Texture* loadFromImage(SDL_Renderer* renderer, const std::string& path, int* outW = nullptr, int* outH = nullptr); private: @@ -28,4 +31,6 @@ private: void setCurrentLoadingFile(const std::string& filename); void clearCurrentLoadingFile(); void recordAssetLoadError(const std::string& message); + + resources::ResourceManager* resourceManager_ = nullptr; }; diff --git a/src/audio/Audio.cpp b/src/audio/Audio.cpp index 582f7b5..15570b5 100644 --- a/src/audio/Audio.cpp +++ b/src/audio/Audio.cpp @@ -118,6 +118,7 @@ static bool decodeMP3(const std::string& path, std::vector& outPCM, int outCh = static_cast(clientFormat.mChannelsPerFrame); return !outPCM.empty(); } + #else static bool decodeMP3(const std::string& path, std::vector& outPCM, int& outRate, int& outCh){ (void)outPCM; (void)outRate; (void)outCh; (void)path; @@ -184,6 +185,8 @@ void Audio::skipToNextTrack(){ void Audio::toggleMute(){ muted=!muted; } void Audio::setMuted(bool m){ muted=m; } +bool Audio::isMuted() const { return muted; } + void Audio::nextTrack(){ if(tracks.empty()) { current = -1; return; } // Try every track once to find a decodable one diff --git a/src/audio/Audio.h b/src/audio/Audio.h index 35f520a..2e1a176 100644 --- a/src/audio/Audio.h +++ b/src/audio/Audio.h @@ -32,29 +32,27 @@ public: void setSoundVolume(float volume) override; bool isMusicPlaying() const override; - // Existing Audio class methods - bool init(); // initialize backend (MF on Windows) - void addTrack(const std::string& path); // decode MP3 -> PCM16 stereo 44100 - void addTrackAsync(const std::string& path); // add track for background loading - void startBackgroundLoading(); // start background thread for loading - void waitForLoadingComplete(); // wait for all tracks to finish loading - bool isLoadingComplete() const; // check if background loading is done - int getLoadedTrackCount() const; // get number of tracks loaded so far - void shuffle(); // randomize order - void start(); // begin playback - void skipToNextTrack(); // advance to the next music track - void toggleMute(); + // Additional IAudioSystem methods (forwarded to concrete implementation) + bool init() override; + void shutdown() override; + void addTrack(const std::string& path) override; + void addTrackAsync(const std::string& path) override; + void startBackgroundLoading() override; + bool isLoadingComplete() const override; + int getLoadedTrackCount() const override; + void start() override; + void skipToNextTrack() override; + void shuffle() override; + void toggleMute() override; + bool isMuted() const override; void setMuted(bool m); - bool isMuted() const { return muted; } - - // Menu music support - void setMenuTrack(const std::string& path); - void playMenuMusic(); - void playGameMusic(); - - // Queue a sound effect to mix over the music (pcm can be mono/stereo, any rate; will be converted) - void playSfx(const std::vector& pcm, int channels, int rate, float volume); - void shutdown(); + void setMenuTrack(const std::string& path) override; + void playMenuMusic() override; + void playGameMusic() override; + void playSfx(const std::vector& pcm, int channels, int rate, float volume) override; + + // Existing Audio class helper methods + void waitForLoadingComplete(); // wait for all tracks to finish loading private: Audio()=default; ~Audio()=default; Audio(const Audio&)=delete; Audio& operator=(const Audio&)=delete; static void SDLCALL streamCallback(void* userdata, SDL_AudioStream* stream, int additional, int total); diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp new file mode 100644 index 0000000..775a4d2 --- /dev/null +++ b/src/audio/AudioManager.cpp @@ -0,0 +1,15 @@ +#include "AudioManager.h" +#include "Audio.h" + +static IAudioSystem* g_audioSystem = nullptr; + +IAudioSystem* AudioManager::get() { + if (!g_audioSystem) { + g_audioSystem = &Audio::instance(); + } + return g_audioSystem; +} + +void AudioManager::set(IAudioSystem* sys) { + g_audioSystem = sys; +} diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h new file mode 100644 index 0000000..ebf078b --- /dev/null +++ b/src/audio/AudioManager.h @@ -0,0 +1,11 @@ +#pragma once + +#include "../core/interfaces/IAudioSystem.h" + +class AudioManager { +public: + // Get the currently registered audio system (may return Audio::instance()) + static IAudioSystem* get(); + // Replace the audio system (for tests or different backends) + static void set(IAudioSystem* sys); +}; diff --git a/src/audio/SoundEffect.cpp b/src/audio/SoundEffect.cpp index ecc34ee..e48393e 100644 --- a/src/audio/SoundEffect.cpp +++ b/src/audio/SoundEffect.cpp @@ -2,6 +2,7 @@ #include "SoundEffect.h" #include #include "audio/Audio.h" +#include "audio/AudioManager.h" #include #include #include @@ -93,7 +94,9 @@ void SimpleAudioPlayer::playSound(const std::vector& pcmData, int chann return; } // Route through shared Audio mixer so SFX always play over music - Audio::instance().playSfx(pcmData, channels, sampleRate, volume); + if (auto sys = AudioManager::get()) { + sys->playSfx(pcmData, channels, sampleRate, volume); + } } bool SoundEffect::loadWAV(const std::string& filePath) { diff --git a/src/core/application/ApplicationManager.cpp b/src/core/application/ApplicationManager.cpp index 9e4da60..546bcd2 100644 --- a/src/core/application/ApplicationManager.cpp +++ b/src/core/application/ApplicationManager.cpp @@ -7,6 +7,7 @@ #include "../interfaces/IInputHandler.h" #include #include "../../audio/Audio.h" +#include "../../audio/AudioManager.h" #include "../../audio/SoundEffect.h" #include "../../persistence/Scores.h" #include "../../states/State.h" @@ -267,7 +268,7 @@ void ApplicationManager::shutdown() { m_running = false; // Stop audio systems before tearing down SDL to avoid aborts/asserts - Audio::instance().shutdown(); + if (auto sys = AudioManager::get()) sys->shutdown(); SoundEffectManager::instance().shutdown(); // Cleanup in reverse order of initialization @@ -381,11 +382,11 @@ bool ApplicationManager::initializeManagers() { // M: Toggle/mute music; start playback if unmuting and not started yet if (!consume && sc == SDL_SCANCODE_M) { - Audio::instance().toggleMute(); + if (auto sys = AudioManager::get()) sys->toggleMute(); m_musicEnabled = !m_musicEnabled; - if (m_musicEnabled && !m_musicStarted && Audio::instance().getLoadedTrackCount() > 0) { - Audio::instance().shuffle(); - Audio::instance().start(); + if (m_musicEnabled && !m_musicStarted && AudioManager::get() && AudioManager::get()->getLoadedTrackCount() > 0) { + AudioManager::get()->shuffle(); + AudioManager::get()->start(); m_musicStarted = true; } consume = true; @@ -393,11 +394,7 @@ bool ApplicationManager::initializeManagers() { // N: Skip to next song in the playlist (or restart menu track) if (!consume && sc == SDL_SCANCODE_N) { - Audio::instance().skipToNextTrack(); - if (!m_musicStarted && Audio::instance().getLoadedTrackCount() > 0) { - m_musicStarted = true; - m_musicEnabled = true; - } + if (auto sys = AudioManager::get()) { sys->skipToNextTrack(); if (!m_musicStarted && sys->getLoadedTrackCount() > 0) { m_musicStarted = true; m_musicEnabled = true; } } consume = true; } @@ -515,13 +512,13 @@ void ApplicationManager::registerServices() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Registered IInputHandler service"); } - // Register Audio system singleton - auto& audioInstance = Audio::instance(); - auto audioPtr = std::shared_ptr