feat(core/audio): music-ended callback (CONV-03)
Ja::Engine exposa setOnMusicEnded(std::function<void()>). Quan updateCurrentMusic detecta que la pista actual ha acabat de drenar (times == 0 && stream buit) s'atura primer via stopMusic i després s'invoca el callback — així un eventual playMusic des del callback pot començar amb l'engine en estat net. Audio proxeia amb setOnMusicEnded. Contracte documentat: s'executa al mateix thread que Audio::update (render loop); no fer operacions blocants. Cap consumidor actualment; només exposa l'API per quan calgui. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
4e0dcfe739
commit
2ec6fd23b6
4 files changed
+31
-5
No files matched your search
@@ -144,6 +144,14 @@ void Audio::fadeOutMusic(int milliseconds) {
|
||||
}
|
||||
}
|
||||
|
||||
// Registra un callback que el motor dispararà quan la pista actual acabi de
|
||||
// drenar (times == 0 + stream buit). S'executa al mateix thread que
|
||||
// Audio::update (render loop); els consumidors no poden fer I/O blocant.
|
||||
// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_
|
||||
void Audio::setOnMusicEnded(std::function<void()> callback) {
|
||||
if (engine_) { engine_->setOnMusicEnded(std::move(callback)); }
|
||||
}
|
||||
|
||||
// Consulta directament l'estat a Ja i el projecta al subconjunt d'estats que
|
||||
// exposa Audio (INVALID/DISABLED de Ja col·lapsen a STOPPED — la capa d'usuari
|
||||
// només vol saber si està sonant, pausat o parat).
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath> // Per a std::lround
|
||||
#include <cstdint> // Per a int8_t, uint8_t
|
||||
#include <memory> // Per a std::unique_ptr
|
||||
#include <string> // Per a string
|
||||
#include <utility> // Per a move
|
||||
#include <cmath> // Per a std::lround
|
||||
#include <cstdint> // Per a int8_t, uint8_t
|
||||
#include <functional> // Per a std::function
|
||||
#include <memory> // Per a std::unique_ptr
|
||||
#include <string> // Per a string
|
||||
#include <utility> // Per a move
|
||||
|
||||
// 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
|
||||
@@ -74,6 +75,7 @@ class Audio {
|
||||
void resumeMusic(); // Continua la música pausada
|
||||
void stopMusic(); // Aturar completament la música
|
||||
void fadeOutMusic(int milliseconds); // Fosa de sortida de la música (muta globals de Ja)
|
||||
void setOnMusicEnded(std::function<void()> callback); // Callback disparat quan la pista actual acaba de drenar (CONV-03)
|
||||
|
||||
// --- Control de sons ---
|
||||
void playSound(const std::string& name, Group group = Group::GAME); // Reproduir so puntual per nom (muta globals de Ja)
|
||||
|
||||
@@ -151,7 +151,11 @@ namespace Ja {
|
||||
|
||||
pumpMusic(current_music_);
|
||||
if (current_music_->times == 0 && SDL_GetAudioStreamAvailable(current_music_->stream) == 0) {
|
||||
// La pista ha acabat de drenar naturalment. L'aturem primer (deixa
|
||||
// l'engine en estat consistent) i llavors invoquem el callback;
|
||||
// així un eventual playMusic des del callback comença net.
|
||||
stopMusic();
|
||||
if (on_music_ended_) { on_music_ended_(); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,6 +323,10 @@ namespace Ja {
|
||||
return music_volume_;
|
||||
}
|
||||
|
||||
void Engine::setOnMusicEnded(std::function<void()> callback) {
|
||||
on_music_ended_ = std::move(callback);
|
||||
}
|
||||
|
||||
void Engine::onMusicDeleted(const Music* music) {
|
||||
if (music == nullptr) { return; }
|
||||
if (current_music_ == music) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -133,6 +134,12 @@ namespace Ja {
|
||||
void crossfadeMusic(Music* music, int crossfade_ms, int loop = -1);
|
||||
[[nodiscard]] auto getMusicState() const -> MusicState;
|
||||
auto setMusicVolume(float volume) -> float;
|
||||
// Registra un callback que es disparà quan la música actual acabi de
|
||||
// drenar naturalment (times == 0 + stream buit). Es crida DESPRÉS de
|
||||
// stopMusic, així que el callback pot invocar playMusic sense córrer.
|
||||
// S'executa al mateix thread que Engine::update (render loop); no fer
|
||||
// operacions blocants.
|
||||
void setOnMusicEnded(std::function<void()> callback);
|
||||
// Notifica al motor que un Music s'està destruint: si és el current_music
|
||||
// s'atura abans que els seus recursos (stream/vorbis) deixin de ser vàlids.
|
||||
void onMusicDeleted(const Music* music);
|
||||
@@ -166,6 +173,7 @@ namespace Ja {
|
||||
SDL_AudioDeviceID sdl_audio_device_{0};
|
||||
OutgoingMusic outgoing_music_;
|
||||
FadeState incoming_fade_;
|
||||
std::function<void()> on_music_ended_;
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming) — convenció projecte: private static amb sufix _
|
||||
static Engine* active_;
|
||||
|
||||
Reference in new issue
Block a user