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:
1 parent
32dcf264c4
commit
a3b03b87be
5 files changed
+256
-160
No files matched your search
@@ -42,83 +42,86 @@ namespace GlobalInputs {
|
||||
}
|
||||
|
||||
void onDecZoom() {
|
||||
if (Options::window.fullscreen) { return; }
|
||||
if (Options::window.zoom <= MIN_ZOOM) { return; }
|
||||
Options::window.zoom--;
|
||||
Screen::get().setWindowZoom(Options::window.zoom);
|
||||
Options::saveToFile();
|
||||
Notification::notify(Locale::get().text("input.zoom") + " x" + std::to_string(Options::window.zoom));
|
||||
if (Options::window().fullscreen) { return; }
|
||||
if (Options::window().zoom <= MIN_ZOOM) { return; }
|
||||
const int NEW_ZOOM = Options::window().zoom - 1;
|
||||
Options::setWindowZoom(NEW_ZOOM);
|
||||
Screen::get().setWindowZoom(NEW_ZOOM);
|
||||
Notification::notify(Locale::get().text("input.zoom") + " x" + std::to_string(NEW_ZOOM));
|
||||
}
|
||||
|
||||
void onIncZoom() {
|
||||
if (Options::window.fullscreen) { return; }
|
||||
if (Options::window.zoom >= MAX_ZOOM) { return; }
|
||||
Options::window.zoom++;
|
||||
Screen::get().setWindowZoom(Options::window.zoom);
|
||||
Options::saveToFile();
|
||||
Notification::notify(Locale::get().text("input.zoom") + " x" + std::to_string(Options::window.zoom));
|
||||
if (Options::window().fullscreen) { return; }
|
||||
if (Options::window().zoom >= MAX_ZOOM) { return; }
|
||||
const int NEW_ZOOM = Options::window().zoom + 1;
|
||||
Options::setWindowZoom(NEW_ZOOM);
|
||||
Screen::get().setWindowZoom(NEW_ZOOM);
|
||||
Notification::notify(Locale::get().text("input.zoom") + " x" + std::to_string(NEW_ZOOM));
|
||||
}
|
||||
|
||||
void onFullscreen() {
|
||||
Options::window.fullscreen = !Options::window.fullscreen;
|
||||
Screen::get().setFullscreen(Options::window.fullscreen);
|
||||
Options::saveToFile();
|
||||
notifyLocale(Options::window.fullscreen ? "input.fullscreen_on" : "input.fullscreen_off");
|
||||
const bool NEW_FS = !Options::window().fullscreen;
|
||||
Options::setWindowFullscreen(NEW_FS);
|
||||
Screen::get().setFullscreen(NEW_FS);
|
||||
notifyLocale(NEW_FS ? "input.fullscreen_on" : "input.fullscreen_off");
|
||||
}
|
||||
|
||||
void onToggleVSync() {
|
||||
Options::video.vsync = !Options::video.vsync;
|
||||
Screen::get().setVSync(Options::video.vsync);
|
||||
Options::saveToFile();
|
||||
notifyLocale(Options::video.vsync ? "input.vsync_on" : "input.vsync_off");
|
||||
const bool NEW_VSYNC = !Options::video().vsync;
|
||||
Options::setVideoVSync(NEW_VSYNC);
|
||||
Screen::get().setVSync(NEW_VSYNC);
|
||||
notifyLocale(NEW_VSYNC ? "input.vsync_on" : "input.vsync_off");
|
||||
}
|
||||
|
||||
void onToggleShader() {
|
||||
Options::video.shader.enabled = !Options::video.shader.enabled;
|
||||
const bool NEW_ENABLED = !Options::video().shader.enabled;
|
||||
Options::setShaderEnabled(NEW_ENABLED);
|
||||
reapplyShader();
|
||||
Options::saveToFile();
|
||||
notifyLocale(Options::video.shader.enabled ? "input.shader_on" : "input.shader_off");
|
||||
notifyLocale(NEW_ENABLED ? "input.shader_on" : "input.shader_off");
|
||||
}
|
||||
|
||||
void onNextShader() {
|
||||
Options::video.shader.current_shader = (Options::video.shader.current_shader == "crtpi") ? "postfx" : "crtpi";
|
||||
const std::string NEW_NAME = (Options::video().shader.current_shader == "crtpi") ? "postfx" : "crtpi";
|
||||
Options::setActiveShaderName(NEW_NAME);
|
||||
reapplyShader();
|
||||
Options::saveToFile();
|
||||
Notification::notify(Locale::get().text("input.shader") + ": " + Options::video.shader.current_shader);
|
||||
Notification::notify(Locale::get().text("input.shader") + ": " + NEW_NAME);
|
||||
}
|
||||
|
||||
// Busca l'entrada actual al vector de presets i passa a la següent
|
||||
// (wrap-around). Si no en troba cap s'evita el canvi silenciosament.
|
||||
void onNextPreset() {
|
||||
const bool IS_CRTPI = Options::video.shader.current_shader == "crtpi";
|
||||
const bool IS_CRTPI = Options::video().shader.current_shader == "crtpi";
|
||||
std::string new_preset;
|
||||
if (IS_CRTPI) {
|
||||
if (Options::crtpi_presets.empty()) { return; }
|
||||
auto it = std::ranges::find_if(Options::crtpi_presets,
|
||||
[](const auto& preset) { return preset.name == Options::video.shader.current_crtpi_preset; });
|
||||
std::size_t idx = (it == Options::crtpi_presets.end()) ? 0 : std::distance(Options::crtpi_presets.begin(), it);
|
||||
idx = (idx + 1) % Options::crtpi_presets.size();
|
||||
Options::video.shader.current_crtpi_preset = Options::crtpi_presets[idx].name;
|
||||
const auto& presets = Options::crtpiPresets();
|
||||
if (presets.empty()) { return; }
|
||||
auto it = std::ranges::find_if(presets,
|
||||
[](const auto& preset) { return preset.name == Options::video().shader.current_crtpi_preset; });
|
||||
std::size_t idx = (it == presets.end()) ? 0 : std::distance(presets.begin(), it);
|
||||
idx = (idx + 1) % presets.size();
|
||||
new_preset = presets[idx].name;
|
||||
Options::setCrtPiPreset(new_preset);
|
||||
} else {
|
||||
if (Options::postfx_presets.empty()) { return; }
|
||||
auto it = std::ranges::find_if(Options::postfx_presets,
|
||||
[](const auto& preset) { return preset.name == Options::video.shader.current_postfx_preset; });
|
||||
std::size_t idx = (it == Options::postfx_presets.end()) ? 0 : std::distance(Options::postfx_presets.begin(), it);
|
||||
idx = (idx + 1) % Options::postfx_presets.size();
|
||||
Options::video.shader.current_postfx_preset = Options::postfx_presets[idx].name;
|
||||
const auto& presets = Options::postfxPresets();
|
||||
if (presets.empty()) { return; }
|
||||
auto it = std::ranges::find_if(presets,
|
||||
[](const auto& preset) { return preset.name == Options::video().shader.current_postfx_preset; });
|
||||
std::size_t idx = (it == presets.end()) ? 0 : std::distance(presets.begin(), it);
|
||||
idx = (idx + 1) % presets.size();
|
||||
new_preset = presets[idx].name;
|
||||
Options::setPostFXPreset(new_preset);
|
||||
}
|
||||
reapplyShader();
|
||||
Options::saveToFile();
|
||||
const std::string& name = IS_CRTPI ? Options::video.shader.current_crtpi_preset : Options::video.shader.current_postfx_preset;
|
||||
Notification::notify(Locale::get().text("input.preset") + ": " + name);
|
||||
Notification::notify(Locale::get().text("input.preset") + ": " + new_preset);
|
||||
}
|
||||
|
||||
void onNextScalingMode() {
|
||||
using Mode = Defaults::ScalingMode;
|
||||
Options::video.scaling_mode = static_cast<Mode>((static_cast<int>(Options::video.scaling_mode) + 1) % 5);
|
||||
Screen::get().setScalingMode(Options::video.scaling_mode);
|
||||
Options::saveToFile();
|
||||
const auto NEW_MODE = static_cast<Mode>((static_cast<int>(Options::video().scaling_mode) + 1) % 5);
|
||||
Options::setVideoScalingMode(NEW_MODE);
|
||||
Screen::get().setScalingMode(NEW_MODE);
|
||||
const char* mode_key = nullptr;
|
||||
switch (Options::video.scaling_mode) {
|
||||
switch (NEW_MODE) {
|
||||
case Mode::DISABLED:
|
||||
mode_key = "input.scaling_disabled";
|
||||
break;
|
||||
@@ -139,14 +142,12 @@ namespace GlobalInputs {
|
||||
}
|
||||
|
||||
void onCycleRenderInfo() {
|
||||
const int NEXT = (static_cast<int>(Options::video.render_info_position) + 1) % Defaults::RENDER_INFO_POSITION_COUNT;
|
||||
Options::video.render_info_position = static_cast<Defaults::RenderInfoPosition>(NEXT);
|
||||
Options::saveToFile();
|
||||
const int NEXT = (static_cast<int>(Options::video().render_info_position) + 1) % Defaults::RENDER_INFO_POSITION_COUNT;
|
||||
Options::setVideoRenderInfoPosition(static_cast<Defaults::RenderInfoPosition>(NEXT));
|
||||
}
|
||||
|
||||
void onToggleRenderTime() {
|
||||
Options::video.render_info_show_time = !Options::video.render_info_show_time;
|
||||
Options::saveToFile();
|
||||
Options::setVideoRenderInfoShowTime(!Options::video().render_info_show_time);
|
||||
}
|
||||
|
||||
void onExit() {
|
||||
|
||||
Reference in new issue
Block a user