refactor(#28): SDLManager rep Config::EngineConfig + on_persist callback

Pas 4/N del hallazgo #28.

SDLManager deixa d'incloure game/options.hpp. El ctor accepta ara una
Config::EngineConfig& (per llegir/mutar window i rendering) i un
opcional std::function<void()> on_persist callback.

Canvis funcionals:
- Es mantenen les mutacions de window.{width,height,zoom_factor,fullscreen}
  però ara sobre cfg_->window en lloc d'Options::window. Comportament
  idèntic perquè Options::window és un alias a engine_config.window.
- toggleVSync deixa de cridar Options::saveToFile() directament i
  invoca on_persist_ si està connectat. El Director li passa una lambda
  que fa la persistència (mantenint sdl_manager agnòstic).
- initWindowAndGpu (free function) rep el vsync inicial per paràmetre.
- Eliminat el ctor per defecte (SDLManager()) que no era cridat des de
  cap call-site del projecte.

Cleanup preexistent surfat per clang-tidy en treure el ctor default:
- finestra_, max_width_, max_height_, max_zoom_ passen a tindre
  default member initializers; eliminat el seu ctor mem-init redundant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 19:35:35 +02:00
parent d118218662
commit fdd34eb943
3 changed files with 114 additions and 134 deletions
+60 -88
View File
@@ -13,95 +13,65 @@
#include "core/defaults.hpp"
#include "core/input/mouse.hpp"
#include "core/rendering/coordinate_transform.hpp"
#include "game/options.hpp"
#include "project.h"
namespace {
auto initWindowAndGpu(SDL_Window** out_window,
Rendering::Renderer& gpu_renderer,
int width, int height, bool fullscreen) -> bool {
// Título estático estilo CCAE. El FPS y el estado de VSync los muestra
// el DebugOverlay (toggle F11), no la barra de título.
const std::string TITLE = std::format("© 2026 {} — JailDesigner",
Project::LONG_NAME);
auto initWindowAndGpu(SDL_Window** out_window,
Rendering::Renderer& gpu_renderer,
int width,
int height,
bool fullscreen,
int initial_vsync) -> bool {
// Título estático estilo CCAE. El FPS y el estado de VSync los muestra
// el DebugOverlay (toggle F11), no la barra de título.
const std::string TITLE = std::format("© 2026 {} — JailDesigner",
Project::LONG_NAME);
SDL_WindowFlags flags = SDL_WINDOW_RESIZABLE;
if (fullscreen) {
flags = static_cast<SDL_WindowFlags>(flags | SDL_WINDOW_FULLSCREEN);
SDL_WindowFlags flags = SDL_WINDOW_RESIZABLE;
if (fullscreen) {
flags = static_cast<SDL_WindowFlags>(flags | SDL_WINDOW_FULLSCREEN);
}
SDL_Window* window = SDL_CreateWindow(TITLE.c_str(), width, height, flags);
if (window == nullptr) {
std::cerr << "Error creant finestra: " << SDL_GetError() << '\n';
return false;
}
if (!fullscreen) {
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
}
// Inicializar el FrameRenderer (claim del window + pipeline de líneas).
if (!gpu_renderer.init(window,
static_cast<float>(Defaults::Game::WIDTH),
static_cast<float>(Defaults::Game::HEIGHT))) {
std::cerr << "Error inicialitzant GpuFrameRenderer\n";
SDL_DestroyWindow(window);
return false;
}
gpu_renderer.setVSync(initial_vsync != 0);
// Cargar parámetros del postpro desde el resource pack. Si el YAML falta
// o falla, el loader devuelve los defaults built-in (bloom suave + flicker
// sutil + background verde tenue).
gpu_renderer.setPostFx(Config::PostFx::load("config/postfx.yaml"));
*out_window = window;
return true;
}
SDL_Window* window = SDL_CreateWindow(TITLE.c_str(), width, height, flags);
if (window == nullptr) {
std::cerr << "Error creant finestra: " << SDL_GetError() << '\n';
return false;
}
if (!fullscreen) {
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
}
// Inicializar el FrameRenderer (claim del window + pipeline de líneas).
if (!gpu_renderer.init(window,
static_cast<float>(Defaults::Game::WIDTH),
static_cast<float>(Defaults::Game::HEIGHT))) {
std::cerr << "Error inicialitzant GpuFrameRenderer\n";
SDL_DestroyWindow(window);
return false;
}
gpu_renderer.setVSync(Options::rendering.vsync != 0);
// Cargar parámetros del postpro desde el resource pack. Si el YAML falta
// o falla, el loader devuelve los defaults built-in (bloom suave + flicker
// sutil + background verde tenue).
gpu_renderer.setPostFx(Config::PostFx::load("config/postfx.yaml"));
*out_window = window;
return true;
}
} // namespace
SDLManager::SDLManager()
: finestra_(nullptr),
current_width_(Defaults::Window::WIDTH),
current_height_(Defaults::Window::HEIGHT),
is_fullscreen_(false),
max_width_(1920),
max_height_(1080),
zoom_factor_(Defaults::Window::BASE_ZOOM),
windowed_width_(Defaults::Window::WIDTH),
windowed_height_(Defaults::Window::HEIGHT),
max_zoom_(1.0F) {
if (!SDL_Init(SDL_INIT_VIDEO)) {
std::cerr << "Error inicialitzant SDL3: " << SDL_GetError() << '\n';
return;
}
calculateMaxWindowSize();
if (!initWindowAndGpu(&finestra_, gpu_renderer_, current_width_, current_height_, false)) {
SDL_Quit();
return;
}
updateViewport();
std::cout << "SDL3 inicialitzat: " << current_width_ << "x" << current_height_
<< " (logic: " << Defaults::Game::WIDTH << "x"
<< Defaults::Game::HEIGHT << ")" << '\n';
}
SDLManager::SDLManager(int width, int height, bool fullscreen)
: finestra_(nullptr),
SDLManager::SDLManager(int width, int height, bool fullscreen, Config::EngineConfig& cfg, std::function<void()> on_persist)
: cfg_(&cfg),
on_persist_(std::move(on_persist)),
current_width_(width),
current_height_(height),
is_fullscreen_(fullscreen),
max_width_(1920),
max_height_(1080),
zoom_factor_(static_cast<float>(width) / Defaults::Window::WIDTH),
windowed_width_(width),
windowed_height_(height),
max_zoom_(1.0F) {
windowed_height_(height) {
if (!SDL_Init(SDL_INIT_VIDEO)) {
std::cerr << "Error inicialitzant SDL3: " << SDL_GetError() << '\n';
return;
@@ -109,7 +79,7 @@ SDLManager::SDLManager(int width, int height, bool fullscreen)
calculateMaxWindowSize();
if (!initWindowAndGpu(&finestra_, gpu_renderer_, current_width_, current_height_, is_fullscreen_)) {
if (!initWindowAndGpu(&finestra_, gpu_renderer_, current_width_, current_height_, is_fullscreen_, cfg_->rendering.vsync)) {
SDL_Quit();
return;
}
@@ -194,9 +164,9 @@ void SDLManager::applyZoom(float new_zoom) {
windowed_width_ = new_width;
windowed_height_ = new_height;
Options::window.width = new_width;
Options::window.height = new_height;
Options::window.zoom_factor = zoom_factor_;
cfg_->window.width = new_width;
cfg_->window.height = new_height;
cfg_->window.zoom_factor = zoom_factor_;
std::cout << "Zoom: " << zoom_factor_ << "x ("
<< new_width << "x" << new_height << ")" << '\n';
@@ -216,9 +186,9 @@ void SDLManager::updateViewport() {
offset_y = std::max(offset_y, 0);
gpu_renderer_.setViewport(static_cast<float>(offset_x),
static_cast<float>(offset_y),
static_cast<float>(scaled_width),
static_cast<float>(scaled_height));
static_cast<float>(offset_y),
static_cast<float>(scaled_width),
static_cast<float>(scaled_height));
std::cout << "Viewport: " << scaled_width << "x" << scaled_height
<< " @ (" << offset_x << "," << offset_y << ") [scale=" << scale << "]"
@@ -288,7 +258,7 @@ void SDLManager::toggleFullscreen() {
<< windowed_width_ << "x" << windowed_height_ << ")" << '\n';
}
Options::window.fullscreen = is_fullscreen_;
cfg_->window.fullscreen = is_fullscreen_;
Mouse::setForceHidden(is_fullscreen_);
}
@@ -334,7 +304,9 @@ void SDLManager::present() {
}
void SDLManager::toggleVSync() {
Options::rendering.vsync = (Options::rendering.vsync == 1) ? 0 : 1;
gpu_renderer_.setVSync(Options::rendering.vsync != 0);
Options::saveToFile();
cfg_->rendering.vsync = (cfg_->rendering.vsync == 1) ? 0 : 1;
gpu_renderer_.setVSync(cfg_->rendering.vsync != 0);
if (on_persist_) {
on_persist_();
}
}