refactor(game): COUP-03 + CONV-02 encapsulate Options state behind setters

L'estat mutable d'Options (window, video, audio, locale, presets, paths)
es mou a un anonymous namespace dins options.cpp. L'API pública del
namespace passa a ser:

- Getters const-ref: window(), video(), audio(), locale(),
  configVersion(), postfxPresets(), crtpiPresets().
- Setters específics que muten i persisteixen via saveToFile():
  setWindowZoom, setWindowFullscreen, setVideoVSync,
  setVideoScalingMode, setVideoRenderInfoPosition,
  setVideoRenderInfoShowTime, setShaderEnabled, setActiveShaderName,
  setPostFXPreset, setCrtPiPreset.

Els setters NO notifiquen els subsistemes: el caller (global_inputs.cpp)
crida explícitament Screen::setWindowZoom, reapplyShader, etc. La part
"observers" del audit es deixa WONTFIX justificat — notificar des
d'Options invertiria la direcció Director→Screen/Audio i Options
aprenria del layout dels subsistemes.

CONV-02 tanca al pas: la part Options dels "globals sense observers"
queda resolta amb la nova encapsulació. Map::* (l'altra meitat de
CONV-02) ja s'havia tancat amb PATCH-07.

Smoke tests 13/13 OK; log Game start → Bye! sota xvfb-run +
SDL_VIDEODRIVER=dummy + SIGINT idèntic al baseline de main.
clang-tidy i cppcheck nets sobre els fitxers modificats.

Refs: docs/audit-game.md (COUP-03, CONV-02, INCONS-01).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
JailDesignerandClaude Opus 4.7 committed 2026-04-22 08:37:59 +02:00
1 parent 32dcf264c4
commit a3b03b87be
5 files changed
+256 -160

No files matched your search

+32 -13
View File
@@ -13,6 +13,15 @@
// del config.yaml. Els subsistemes (Screen, Audio, ...) reben structs tipats
// a través dels build*Config(), de manera que no queden acoblats a aquest
// namespace ni al format concret del fitxer.
//
// L'estat mutable viu en un anonymous namespace dins d'`options.cpp`: els
// callers el llegeixen via getters const-ref (`window()`, `video()`, ...) i
// el muten via setters específics que persisteixen a config.yaml. Els
// setters NO notifiquen els subsistemes (Screen/Audio): el caller (típic.
// `core/input/global_inputs.cpp`) crida després el setter del subsistema.
// Aquesta asimetria preserva la direcció `Director → Screen/Audio` i evita
// que Options aprenga del layout dels subsistemes (decisió WONTFIX d'aquest
// refactor: veure docs/audit-game.md → COUP-03).
namespace Options {
struct Window {
@@ -95,20 +104,30 @@ namespace Options {
Sound sound{};
};
// --- Estat global (inline vars per a que una sola definició viva a tot
// el programa sense necessitar un .cpp extra per a cada una) ---
inline std::string config_version{};
inline std::string config_file_path{};
inline std::string postfx_file_path{};
inline std::string crtpi_file_path{};
inline std::string locale{Defaults::I18n::LOCALE};
inline Window window{};
inline Video video{};
inline Audio audio{};
inline std::vector<PostFXPreset> postfx_presets{};
inline std::vector<CrtPiPreset> crtpi_presets{};
// --- Getters de l'estat (read-only) ---
[[nodiscard]] auto window() -> const Window&;
[[nodiscard]] auto video() -> const Video&;
[[nodiscard]] auto audio() -> const Audio&;
[[nodiscard]] auto locale() -> const std::string&;
[[nodiscard]] auto configVersion() -> const std::string&;
[[nodiscard]] auto postfxPresets() -> const std::vector<PostFXPreset>&;
[[nodiscard]] auto crtpiPresets() -> const std::vector<CrtPiPreset>&;
// --- API pública ---
// --- Setters: muten + persisteixen a config.yaml ---
// No notifiquen els subsistemes; el caller ha de propagar el canvi al
// subsistema corresponent (p.ex. Screen::setWindowZoom) per separat.
void setWindowZoom(int value);
void setWindowFullscreen(bool value);
void setVideoVSync(bool value);
void setVideoScalingMode(Defaults::ScalingMode value);
void setVideoRenderInfoPosition(Defaults::RenderInfoPosition value);
void setVideoRenderInfoShowTime(bool value);
void setShaderEnabled(bool value);
void setActiveShaderName(const std::string& value); // "postfx" | "crtpi"
void setPostFXPreset(const std::string& value);
void setCrtPiPreset(const std::string& value);
// --- API pública: càrrega/desament de fitxers ---
void setConfigFile(const std::string& path);
auto loadFromFile() -> bool;
auto saveToFile() -> bool;