refactor(core/audio): template forEachTargetChannel (DUP-05)

pauseChannel, resumeChannel i stopChannel repetien tres vegades la
cadena "if channel == -1 forEach(channels) else if 0<=channel<MAX
apply()". S'extreu a forEachTargetChannel(channel, fn) i cada funció es
queda només amb la lògica per canal — pausar, reprendre, destruir.

Substitueix codi gairebé idèntic triplicat per una declaració de per
què fa el que fa cada funció.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
JailDesignerandClaude Opus 4.7 committed 2026-04-20 12:07:07 +02:00
1 parent dee00a8de7
commit 6a1ed37242
2 files changed
+19 -33

No files matched your search

+1 -1
View File
@@ -34,7 +34,7 @@ Los IDs se mantienen estables una vez asignados. Cada entrada apunta al(los) fic
| DUP-02 | `audio.cpp:172-185` | `setSoundVolume`/`setMusicVolume` idéntica estructura de clamp+gate+producto | Menor | DONE | `effectiveVolume(volume, channel_enabled)` privat; els dos setters deleguen |
| DUP-03 | `jail_audio.hpp:196-222` | `updateOutgoingFade`/`updateIncomingFade` comparten la curva lineal | Menor | DONE | `fadeProgress(FadeState&)` concentra la corba en un sol lloc; també cobreix `duration_ms <= 0` com a 1.0 |
| DUP-04 | `jail_audio.hpp:391-471` | `fadeOutMusic`/`crossfadeMusic` repiten "destruir outgoing + pre-fill + robar stream + reset vorbis" | Importante | DONE | `stealCurrentIntoOutgoing(duration_ms)` concentra el robatori; `fadeOutMusic` i `crossfadeMusic` hi deleguen. També homogeneïtza `outgoing.fade.active = false` en la destrucció (abans era inconsistent) |
| DUP-05 | `jail_audio.hpp:575-631` | `pauseChannel`/`resumeChannel`/`stopChannel` repiten dispatch `channel==-1 / [0,MAX)` | Menor | PENDING | Helper `forEachTargetChannel(int, fn)` |
| DUP-05 | `jail_audio.hpp:575-631` | `pauseChannel`/`resumeChannel`/`stopChannel` repiten dispatch `channel==-1 / [0,MAX)` | Menor | DONE | Template `forEachTargetChannel(channel, fn)`; cada funció només descriu què fa per canal |
## 2. Hardcoding
+18 -32
View File
@@ -569,45 +569,40 @@ namespace Ja {
delete sound;
}
// Aplica `fn` als canals objectiu: tots si channel == -1, o només el d'índex
// vàlid si està dins [0, MAX_SIMULTANEOUS_CHANNELS). Centralitza el dispatch
// "tots vs un" que pauseChannel/resumeChannel/stopChannel repetien.
template <typename Fn>
inline void forEachTargetChannel(const int channel, Fn&& fn) {
if (channel == -1) {
for (auto& ch : channels) { fn(ch); }
} else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) {
fn(channels[channel]);
}
}
inline void pauseChannel(const int channel) {
if (!sound_enabled) { return; }
if (channel == -1) {
for (auto& ch : channels) {
forEachTargetChannel(channel, [](Channel& ch) {
if (ch.state == ChannelState::PLAYING) {
ch.state = ChannelState::PAUSED;
SDL_UnbindAudioStream(ch.stream);
}
}
} else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) {
if (channels[channel].state == ChannelState::PLAYING) {
channels[channel].state = ChannelState::PAUSED;
SDL_UnbindAudioStream(channels[channel].stream);
}
}
});
}
inline void resumeChannel(const int channel) {
if (!sound_enabled) { return; }
if (channel == -1) {
for (auto& ch : channels) {
forEachTargetChannel(channel, [](Channel& ch) {
if (ch.state == ChannelState::PAUSED) {
ch.state = ChannelState::PLAYING;
SDL_BindAudioStream(sdl_audio_device, ch.stream);
}
}
} else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) {
if (channels[channel].state == ChannelState::PAUSED) {
channels[channel].state = ChannelState::PLAYING;
SDL_BindAudioStream(sdl_audio_device, channels[channel].stream);
}
}
});
}
inline void stopChannel(const int channel) {
if (channel == -1) {
for (auto& ch : channels) {
forEachTargetChannel(channel, [](Channel& ch) {
if (ch.state != ChannelState::FREE) {
if (ch.stream != nullptr) { SDL_DestroyAudioStream(ch.stream); }
ch.stream = nullptr;
@@ -615,16 +610,7 @@ namespace Ja {
ch.pos = 0;
ch.sound = nullptr;
}
}
} else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) {
if (channels[channel].state != ChannelState::FREE) {
if (channels[channel].stream != nullptr) { SDL_DestroyAudioStream(channels[channel].stream); }
channels[channel].stream = nullptr;
channels[channel].state = ChannelState::FREE;
channels[channel].pos = 0;
channels[channel].sound = nullptr;
}
}
});
}
inline auto getChannelState(const int channel) -> ChannelState {