diff --git a/source/core/audio/audio.cpp b/source/core/audio/audio.cpp index 06f4192..9e8c5ea 100644 --- a/source/core/audio/audio.cpp +++ b/source/core/audio/audio.cpp @@ -31,15 +31,14 @@ auto Audio::get() -> Audio* { return Audio::instance.get(); } Audio::Audio(const Config& config) : config_(config) { initSDLAudio(); } -// Destructor -Audio::~Audio() { - Ja::quit(); -} +// Destructor: engine_ és std::unique_ptr, el seu dtor tanca el device SDL i +// desregistra Ja::Engine::active_. Cap crida explícita necessària. +Audio::~Audio() = default; -// Mètode principal: l'estat de la música el manté Ja (única font de veritat), -// per tant no cal cap sincronització aquí. +// Mètode principal: l'estat de la música el manté el motor (única font de +// veritat), per tant no cal cap sincronització aquí. void Audio::update() { - Ja::update(); + if (instance && instance->engine_) { instance->engine_->update(); } } // Reprodueix la música per nom (amb crossfade opcional) @@ -78,70 +77,70 @@ void Audio::playMusic(Ja::Music* music, const int loop, const int crossfade_ms) void Audio::playMusicInternal(Ja::Music* music, const int loop, const int crossfade_ms) { const bool CURRENTLY_PLAYING = (getMusicState() == MusicState::PLAYING); if (crossfade_ms > 0 && CURRENTLY_PLAYING) { - Ja::crossfadeMusic(music, crossfade_ms, loop); + engine_->crossfadeMusic(music, crossfade_ms, loop); } else { if (CURRENTLY_PLAYING) { - Ja::stopMusic(); + engine_->stopMusic(); } - Ja::playMusic(music, loop); + engine_->playMusic(music, loop); } music_.loop = (loop != 0); } -// Pausa la música (l'estat el transiciona Ja::pauseMusic) -// NOLINTNEXTLINE(readability-make-member-function-const) — muta Ja::current_music->state +// Pausa la música (l'estat el transiciona Engine::pauseMusic) +// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const void Audio::pauseMusic() { if (music_enabled_ && getMusicState() == MusicState::PLAYING) { - Ja::pauseMusic(); + engine_->pauseMusic(); } } -// Continua la música pausada (l'estat el transiciona Ja::resumeMusic) -// NOLINTNEXTLINE(readability-make-member-function-const) — muta Ja::current_music->state +// Continua la música pausada (l'estat el transiciona Engine::resumeMusic) +// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const void Audio::resumeMusic() { if (music_enabled_ && getMusicState() == MusicState::PAUSED) { - Ja::resumeMusic(); + engine_->resumeMusic(); } } -// Detiene la música (l'estat el transiciona Ja::stopMusic) -// NOLINTNEXTLINE(readability-make-member-function-const) — muta Ja::current_music/outgoing_music +// Atura la música (l'estat el transiciona Engine::stopMusic) +// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const void Audio::stopMusic() { if (music_enabled_) { - Ja::stopMusic(); + engine_->stopMusic(); } } // Reprodueix un so per nom -// NOLINTNEXTLINE(readability-make-member-function-const) — muta globals de Ja::channels +// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const void Audio::playSound(const std::string& name, Group group) { if (sound_enabled_) { - Ja::playSound(AudioResource::getSound(name), 0, static_cast(group)); + engine_->playSound(AudioResource::getSound(name), 0, static_cast(group)); } } // Reprodueix un so per punter directe -// NOLINTNEXTLINE(readability-make-member-function-const) — muta globals de Ja::channels +// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const void Audio::playSound(Ja::Sound* sound, Group group) { if (sound_enabled_ && sound != nullptr) { - Ja::playSound(sound, 0, static_cast(group)); + engine_->playSound(sound, 0, static_cast(group)); } } // Atura tots els sons -// NOLINTNEXTLINE(readability-make-member-function-const) — muta globals de Ja::channels +// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const void Audio::stopAllSounds() { if (sound_enabled_) { - Ja::stopChannel(-1); + engine_->stopChannel(-1); } } // Fa una fosa de sortida de la música -// NOLINTNEXTLINE(readability-make-member-function-const) — muta Ja::outgoing_music/incoming_fade +// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const void Audio::fadeOutMusic(int milliseconds) { if (music_enabled_ && getMusicState() == MusicState::PLAYING) { - Ja::fadeOutMusic(milliseconds); + engine_->fadeOutMusic(milliseconds); } } @@ -149,7 +148,8 @@ void Audio::fadeOutMusic(int milliseconds) { // exposa Audio (INVALID/DISABLED de Ja col·lapsen a STOPPED — la capa d'usuari // només vol saber si està sonant, pausat o parat). auto Audio::getMusicState() -> MusicState { - switch (Ja::getMusicState()) { + if (!instance || !instance->engine_) { return MusicState::STOPPED; } + switch (instance->engine_->getMusicState()) { case Ja::MusicState::PLAYING: return MusicState::PLAYING; case Ja::MusicState::PAUSED: @@ -171,15 +171,15 @@ auto Audio::effectiveVolume(float volume, bool channel_enabled) const -> float { } // Estableix el volum dels sons (float 0.0..1.0) -// NOLINTNEXTLINE(readability-make-member-function-const) — muta Ja::sound_volume[] i canals actius +// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const void Audio::setSoundVolume(float sound_volume, Group group) { - Ja::setSoundVolume(effectiveVolume(sound_volume, sound_enabled_), static_cast(group)); + engine_->setSoundVolume(effectiveVolume(sound_volume, sound_enabled_), static_cast(group)); } // Estableix el volum de la música (float 0.0..1.0) -// NOLINTNEXTLINE(readability-make-member-function-const) — muta Ja::music_volume i stream actual +// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const void Audio::setMusicVolume(float music_volume) { - Ja::setMusicVolume(effectiveVolume(music_volume, music_enabled_)); + engine_->setMusicVolume(effectiveVolume(music_volume, music_enabled_)); } // Aplica una nova configuració (substitueix la config cachejada i reaplica enables/volums) @@ -212,14 +212,14 @@ void Audio::enableMusic(bool value) { setMusicVolume(config_.music_volume); } -// Inicialitza SDL Audio +// Inicialitza SDL Audio i el motor Ja::Engine owned. void Audio::initSDLAudio() { if (!SDL_Init(SDL_INIT_AUDIO)) { std::fprintf(stderr, "Audio: SDL_AUDIO could not initialize! SDL Error: %s\n", SDL_GetError()); - } else { - Ja::init(Defaults::Audio::FREQUENCY, Defaults::Audio::FORMAT, Defaults::Audio::CHANNELS); - sound_enabled_ = config_.sound_enabled; - music_enabled_ = config_.music_enabled; - enable(config_.enabled); + return; } + engine_ = std::make_unique(Defaults::Audio::FREQUENCY, Defaults::Audio::FORMAT, Defaults::Audio::CHANNELS); + sound_enabled_ = config_.sound_enabled; + music_enabled_ = config_.music_enabled; + enable(config_.enabled); } diff --git a/source/core/audio/audio.hpp b/source/core/audio/audio.hpp index 4d21c2f..f64254a 100644 --- a/source/core/audio/audio.hpp +++ b/source/core/audio/audio.hpp @@ -6,9 +6,13 @@ #include // Per a string #include // Per a move -// Forward-declares per no incloure core/audio/jail_audio.hpp al header (conté -// l'engine complet de streaming amb stb_vorbis). +// Forward-declares per no incloure core/audio/jail_audio.hpp al header. Els +// tres símbols (Music/Sound per al punter que exposa la API i Engine per al +// std::unique_ptr membre) s'usen només per punter al header, així que +// el forward-decl basta. El ~Audio() en .cpp veu la definició completa i +// instancia correctament el dtor de l'unique_ptr. namespace Ja { + class Engine; struct Music; struct Sound; } // namespace Ja @@ -126,9 +130,10 @@ class Audio { // --- Variables membre --- static std::unique_ptr