DUP-01: pipeline unificat de presets PostFX i CrtPi a options.cpp
Afegits `loadPresetsFromFile<T>` i `savePresetsToFile<T>` a l'anonymous namespace; els quatre entry-points passen a ser one-liners que injecten parse/write/defaults per tipus. Abans eren dues còpies del mateix codi diferenciades només pel tipus concret de preset. Els YAML regenerats són byte-a-byte idèntics als anteriors (el formatter i els comentaris es preserven).
This commit is contained in:
1 parent
ab7a79dc50
commit
505c20dabc
2 files changed
+95
-88
No files matched your search
+2
-2
@@ -20,7 +20,7 @@ Els IDs es mantenen estables una vegada assignats. Cada entrada apunta al fitxer
|
|||||||
|----|-------|-------|
|
|----|-------|-------|
|
||||||
| HC-03 | Geometria del mapa cablejada a `map.hpp` (bloqueja "pirámide a pirámide") | DONE |
|
| HC-03 | Geometria del mapa cablejada a `map.hpp` (bloqueja "pirámide a pirámide") | DONE |
|
||||||
| COUP-01 | `core/` inclou `game/ui/notification_presets.hpp` (dependència invertida) | DONE |
|
| COUP-01 | `core/` inclou `game/ui/notification_presets.hpp` (dependència invertida) | DONE |
|
||||||
| DUP-01 | PostFX i CrtPi són dos pipelines duplicats a `options.cpp` | PENDING |
|
| DUP-01 | PostFX i CrtPi són dos pipelines duplicats a `options.cpp` | DONE |
|
||||||
| PATCH-04 | Reescriure silenciosament `config.yaml` al fallar parseig o versió | PENDING |
|
| PATCH-04 | Reescriure silenciosament `config.yaml` al fallar parseig o versió | PENDING |
|
||||||
| HC-01 | `SPEED_PX_PER_S`, caixa de col·lisió i rutes d'assets cablejades | PENDING |
|
| HC-01 | `SPEED_PX_PER_S`, caixa de col·lisió i rutes d'assets cablejades | PENDING |
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ Els IDs es mantenen estables una vegada assignats. Cada entrada apunta al fitxer
|
|||||||
|
|
||||||
| ID | Fitxer:línia | Troballa | Severitat | Estat | Notes |
|
| ID | Fitxer:línia | Troballa | Severitat | Estat | Notes |
|
||||||
|----|--------------|----------|-----------|-------|-------|
|
|----|--------------|----------|-----------|-------|-------|
|
||||||
| DUP-01 | `options.cpp:152-335,443-547` | PostFX i CrtPi tenen `default*Presets/parse*Preset/write*Preset/load*FromFile/save*ToFile/set*File` duplicats | Importante | PENDING | Template `PresetStore<T>` amb serialitzadors per camp |
|
| DUP-01 | `options.cpp:152-335,443-547` | PostFX i CrtPi tenen `default*Presets/parse*Preset/write*Preset/load*FromFile/save*ToFile/set*File` duplicats | Importante | DONE | Afegits `loadPresetsFromFile<T>` i `savePresetsToFile<T>` a l'anonymous namespace; els 4 entry-points passen a ser one-liners que injecten parse/write/defaults per tipus. Els fitxers `postfx.yaml`/`crtpi.yaml` regenerats són idèntics a l'anterior. `std::cerr` manté el comportament — INCONS-02 el corregirà |
|
||||||
| DUP-02 | `player.cpp:100-140` | `snapToHorizontalLane` i `snapToVerticalLane` són el mateix algorisme amb eixos permutats | Importante | PENDING | Unificar en `snapToLane(Axis, delta_time)` |
|
| DUP-02 | `player.cpp:100-140` | `snapToHorizontalLane` i `snapToVerticalLane` són el mateix algorisme amb eixos permutats | Importante | PENDING | Unificar en `snapToLane(Axis, delta_time)` |
|
||||||
| DUP-03 | `options.cpp:14-62` | Tres parelles `enumToString`/`enumFromString` amb la mateixa forma | Menor | PENDING | Taula `constexpr` + helpers genèrics |
|
| DUP-03 | `options.cpp:14-62` | Tres parelles `enumToString`/`enumFromString` amb la mateixa forma | Menor | PENDING | Taula `constexpr` + helpers genèrics |
|
||||||
| DUP-04 | `options.cpp:79-149` | Cada `parse*` repeteix `if (node.contains) { ... get_value<T> }` | Menor | PENDING | Helper `readField<T>(node, key, dst)` |
|
| DUP-04 | `options.cpp:79-149` | Cada `parse*` repeteix `if (node.contains) { ... get_value<T> }` | Menor | PENDING | Helper `readField<T>(node, key, dst)` |
|
||||||
|
|||||||
+93
-86
@@ -334,6 +334,73 @@ namespace {
|
|||||||
out << " enable_sharper: " << (preset.enable_sharper ? "true" : "false") << "\n";
|
out << " enable_sharper: " << (preset.enable_sharper ? "true" : "false") << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pipeline genèric de càrrega de presets: si el fitxer no existeix o és
|
||||||
|
// invàlid (no deserialitza, manca `presets:`, no és seqüència, queda
|
||||||
|
// buit), es restauren els defaults via `defaults_fn` i es reescriu via
|
||||||
|
// `save_fn`. Unifica PostFX i CrtPi — abans eren dues còpies del mateix
|
||||||
|
// codi que només diferien en el tipus concret de preset.
|
||||||
|
template <typename T>
|
||||||
|
auto loadPresetsFromFile(
|
||||||
|
const std::string& path,
|
||||||
|
std::vector<T>& presets,
|
||||||
|
std::vector<T> (*defaults_fn)(),
|
||||||
|
void (*parse_fn)(const fkyaml::node&, T&),
|
||||||
|
bool (*save_fn)(),
|
||||||
|
const char* kind_label) -> bool {
|
||||||
|
if (path.empty()) { return false; }
|
||||||
|
|
||||||
|
const std::string CONTENT = readFileOrEmpty(path);
|
||||||
|
if (CONTENT.empty()) {
|
||||||
|
presets = defaults_fn();
|
||||||
|
return save_fn();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
auto yaml = fkyaml::node::deserialize(CONTENT);
|
||||||
|
if (!yaml.contains("presets") || !yaml["presets"].is_sequence()) {
|
||||||
|
presets = defaults_fn();
|
||||||
|
return save_fn();
|
||||||
|
}
|
||||||
|
presets.clear();
|
||||||
|
for (const auto& preset_node : yaml["presets"]) {
|
||||||
|
T preset;
|
||||||
|
parse_fn(preset_node, preset);
|
||||||
|
presets.push_back(preset);
|
||||||
|
}
|
||||||
|
if (presets.empty()) {
|
||||||
|
presets = defaults_fn();
|
||||||
|
return save_fn();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "Options: error parsejant " << kind_label << ": " << e.what() << '\n';
|
||||||
|
std::cerr << "Options: reescrivint el fitxer amb presets per defecte.\n";
|
||||||
|
presets = defaults_fn();
|
||||||
|
return save_fn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pipeline genèric d'escriptura: capçalera de comentari + `presets:` +
|
||||||
|
// una entrada per preset via `write_fn`. `config_key_note` és la segona
|
||||||
|
// línia de comentari que recorda amb quin camp de config.yaml han de
|
||||||
|
// coincidir els noms.
|
||||||
|
template <typename T>
|
||||||
|
auto savePresetsToFile(
|
||||||
|
const std::string& path,
|
||||||
|
const std::vector<T>& presets,
|
||||||
|
void (*write_fn)(std::ostringstream&, const T&),
|
||||||
|
const char* header_comment,
|
||||||
|
const char* config_key_note) -> bool {
|
||||||
|
if (path.empty()) { return false; }
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "# " << header_comment << "\n";
|
||||||
|
out << "# " << config_key_note << "\n";
|
||||||
|
out << "presets:\n";
|
||||||
|
for (const auto& preset : presets) {
|
||||||
|
write_fn(out, preset);
|
||||||
|
}
|
||||||
|
return writeFile(path, out.str());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace Options {
|
namespace Options {
|
||||||
@@ -445,52 +512,22 @@ namespace Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto loadPostFXFromFile() -> bool {
|
auto loadPostFXFromFile() -> bool {
|
||||||
if (postfx_file_path.empty()) { return false; }
|
return loadPresetsFromFile<PostFXPreset>(
|
||||||
|
postfx_file_path,
|
||||||
const std::string CONTENT = readFileOrEmpty(postfx_file_path);
|
postfx_presets,
|
||||||
if (CONTENT.empty()) {
|
&defaultPostFXPresets,
|
||||||
postfx_presets = defaultPostFXPresets();
|
&parsePostFXPreset,
|
||||||
return savePostFXToFile();
|
&savePostFXToFile,
|
||||||
}
|
"postfx.yaml");
|
||||||
|
|
||||||
try {
|
|
||||||
auto yaml = fkyaml::node::deserialize(CONTENT);
|
|
||||||
if (!yaml.contains("presets") || !yaml["presets"].is_sequence()) {
|
|
||||||
postfx_presets = defaultPostFXPresets();
|
|
||||||
return savePostFXToFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
postfx_presets.clear();
|
|
||||||
for (const auto& preset_node : yaml["presets"]) {
|
|
||||||
PostFXPreset preset;
|
|
||||||
parsePostFXPreset(preset_node, preset);
|
|
||||||
postfx_presets.push_back(preset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (postfx_presets.empty()) {
|
|
||||||
postfx_presets = defaultPostFXPresets();
|
|
||||||
return savePostFXToFile();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
std::cerr << "Options: error parsejant postfx.yaml: " << e.what() << '\n';
|
|
||||||
std::cerr << "Options: reescrivint el fitxer amb presets per defecte.\n";
|
|
||||||
postfx_presets = defaultPostFXPresets();
|
|
||||||
return savePostFXToFile();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto savePostFXToFile() -> bool {
|
auto savePostFXToFile() -> bool {
|
||||||
if (postfx_file_path.empty()) { return false; }
|
return savePresetsToFile<PostFXPreset>(
|
||||||
|
postfx_file_path,
|
||||||
std::ostringstream out;
|
postfx_presets,
|
||||||
out << "# Presets PostFX per a AEE 2026. Editable a mà.\n";
|
&writePostFXPreset,
|
||||||
out << "# Els noms han de coincidir amb config.yaml > video.shader.current_postfx_preset.\n";
|
"Presets PostFX per a AEE 2026. Editable a mà.",
|
||||||
out << "presets:\n";
|
"Els noms han de coincidir amb config.yaml > video.shader.current_postfx_preset.");
|
||||||
for (const auto& preset : postfx_presets) {
|
|
||||||
writePostFXPreset(out, preset);
|
|
||||||
}
|
|
||||||
return writeFile(postfx_file_path, out.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCrtPiFile(const std::string& path) {
|
void setCrtPiFile(const std::string& path) {
|
||||||
@@ -498,52 +535,22 @@ namespace Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto loadCrtPiFromFile() -> bool {
|
auto loadCrtPiFromFile() -> bool {
|
||||||
if (crtpi_file_path.empty()) { return false; }
|
return loadPresetsFromFile<CrtPiPreset>(
|
||||||
|
crtpi_file_path,
|
||||||
const std::string CONTENT = readFileOrEmpty(crtpi_file_path);
|
crtpi_presets,
|
||||||
if (CONTENT.empty()) {
|
&defaultCrtPiPresets,
|
||||||
crtpi_presets = defaultCrtPiPresets();
|
&parseCrtPiPreset,
|
||||||
return saveCrtPiToFile();
|
&saveCrtPiToFile,
|
||||||
}
|
"crtpi.yaml");
|
||||||
|
|
||||||
try {
|
|
||||||
auto yaml = fkyaml::node::deserialize(CONTENT);
|
|
||||||
if (!yaml.contains("presets") || !yaml["presets"].is_sequence()) {
|
|
||||||
crtpi_presets = defaultCrtPiPresets();
|
|
||||||
return saveCrtPiToFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
crtpi_presets.clear();
|
|
||||||
for (const auto& preset_node : yaml["presets"]) {
|
|
||||||
CrtPiPreset preset;
|
|
||||||
parseCrtPiPreset(preset_node, preset);
|
|
||||||
crtpi_presets.push_back(preset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crtpi_presets.empty()) {
|
|
||||||
crtpi_presets = defaultCrtPiPresets();
|
|
||||||
return saveCrtPiToFile();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
std::cerr << "Options: error parsejant crtpi.yaml: " << e.what() << '\n';
|
|
||||||
std::cerr << "Options: reescrivint el fitxer amb presets per defecte.\n";
|
|
||||||
crtpi_presets = defaultCrtPiPresets();
|
|
||||||
return saveCrtPiToFile();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto saveCrtPiToFile() -> bool {
|
auto saveCrtPiToFile() -> bool {
|
||||||
if (crtpi_file_path.empty()) { return false; }
|
return savePresetsToFile<CrtPiPreset>(
|
||||||
|
crtpi_file_path,
|
||||||
std::ostringstream out;
|
crtpi_presets,
|
||||||
out << "# Presets CRT-Pi per a AEE 2026. Editable a mà.\n";
|
&writeCrtPiPreset,
|
||||||
out << "# Els noms han de coincidir amb config.yaml > video.shader.current_crtpi_preset.\n";
|
"Presets CRT-Pi per a AEE 2026. Editable a mà.",
|
||||||
out << "presets:\n";
|
"Els noms han de coincidir amb config.yaml > video.shader.current_crtpi_preset.");
|
||||||
for (const auto& preset : crtpi_presets) {
|
|
||||||
writeCrtPiPreset(out, preset);
|
|
||||||
}
|
|
||||||
return writeFile(crtpi_file_path, out.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto buildActiveShader() -> Rendering::ShaderType {
|
auto buildActiveShader() -> Rendering::ShaderType {
|
||||||
|
|||||||
Reference in new issue
Block a user