DUP-03+HC-07: enum↔string per taula a options.cpp

Tres parelles de `*ToString`/`*FromString` substituïdes per tres taules
`constexpr std::array<pair<Enum, string_view>, N>` i dos helpers plantilla
(`enumToString`, `enumFromString`). La primera entrada de cada taula és
el fallback quan l'enum és desconegut o el text no casa: així els valors
"letterbox"/"nearest"/"off" només apareixen una vegada. Resol també HC-07.
This commit is contained in:
JailDesigner committed 2026-04-20 18:01:19 +02:00
1 parent 206ba07a6f
commit 982a1788f1
2 files changed
+44 -52

No files matched your search

+42 -50
View File
@@ -1,64 +1,56 @@
#include "game/options.hpp"
#include <algorithm>
#include <array>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <string_view>
#include <utility>
#include "external/fkyaml_node.hpp"
#include "utils/defines.hpp"
namespace {
auto scalingModeToString(Defaults::ScalingMode mode) -> const char* {
switch (mode) {
case Defaults::ScalingMode::DISABLED:
return "disabled";
case Defaults::ScalingMode::STRETCH:
return "stretch";
case Defaults::ScalingMode::LETTERBOX:
return "letterbox";
case Defaults::ScalingMode::OVERSCAN:
return "overscan";
case Defaults::ScalingMode::INTEGER:
return "integer";
// Taules enum ↔ string per a la serialització a YAML. La primera entrada
// és el fallback quan l'enum no té nom conegut o el text no casa amb
// cap entrada coneguda — per això `LETTERBOX`/`NEAREST`/`OFF` encapçalen.
constexpr std::array SCALING_MODE_NAMES = {
std::pair{Defaults::ScalingMode::LETTERBOX, std::string_view{"letterbox"}},
std::pair{Defaults::ScalingMode::DISABLED, std::string_view{"disabled"}},
std::pair{Defaults::ScalingMode::STRETCH, std::string_view{"stretch"}},
std::pair{Defaults::ScalingMode::OVERSCAN, std::string_view{"overscan"}},
std::pair{Defaults::ScalingMode::INTEGER, std::string_view{"integer"}},
};
constexpr std::array TEXTURE_FILTER_NAMES = {
std::pair{Defaults::TextureFilter::NEAREST, std::string_view{"nearest"}},
std::pair{Defaults::TextureFilter::LINEAR, std::string_view{"linear"}},
};
constexpr std::array RENDER_INFO_POSITION_NAMES = {
std::pair{Defaults::RenderInfoPosition::OFF, std::string_view{"off"}},
std::pair{Defaults::RenderInfoPosition::TOP, std::string_view{"top"}},
std::pair{Defaults::RenderInfoPosition::BOTTOM, std::string_view{"bottom"}},
};
// Helpers generics: el fallback és la primera entrada de la taula.
template <typename Enum, std::size_t N>
auto enumToString(const std::array<std::pair<Enum, std::string_view>, N>& table, Enum value) -> const char* {
for (const auto& [e, name] : table) {
if (e == value) { return name.data(); }
}
return "letterbox";
return table.front().second.data();
}
auto scalingModeFromString(const std::string& text) -> Defaults::ScalingMode {
if (text == "disabled") { return Defaults::ScalingMode::DISABLED; }
if (text == "stretch") { return Defaults::ScalingMode::STRETCH; }
if (text == "overscan") { return Defaults::ScalingMode::OVERSCAN; }
if (text == "integer") { return Defaults::ScalingMode::INTEGER; }
return Defaults::ScalingMode::LETTERBOX;
}
auto filterToString(Defaults::TextureFilter filter) -> const char* {
return filter == Defaults::TextureFilter::LINEAR ? "linear" : "nearest";
}
auto filterFromString(const std::string& text) -> Defaults::TextureFilter {
return text == "linear" ? Defaults::TextureFilter::LINEAR : Defaults::TextureFilter::NEAREST;
}
auto renderInfoPositionToString(Defaults::RenderInfoPosition pos) -> const char* {
switch (pos) {
case Defaults::RenderInfoPosition::TOP:
return "top";
case Defaults::RenderInfoPosition::BOTTOM:
return "bottom";
case Defaults::RenderInfoPosition::OFF:
return "off";
template <typename Enum, std::size_t N>
auto enumFromString(const std::array<std::pair<Enum, std::string_view>, N>& table, const std::string& text) -> Enum {
for (const auto& [e, name] : table) {
if (name == text) { return e; }
}
return "off";
}
auto renderInfoPositionFromString(const std::string& text) -> Defaults::RenderInfoPosition {
if (text == "top") { return Defaults::RenderInfoPosition::TOP; }
if (text == "bottom") { return Defaults::RenderInfoPosition::BOTTOM; }
return Defaults::RenderInfoPosition::OFF;
return table.front().first;
}
auto readFileOrEmpty(const std::string& path) -> std::string {
@@ -124,13 +116,13 @@ namespace {
const auto& node = yaml["video"];
if (node.contains("vsync")) { Options::video.vsync = node["vsync"].get_value<bool>(); }
if (node.contains("scaling_mode")) {
Options::video.scaling_mode = scalingModeFromString(node["scaling_mode"].get_value<std::string>());
Options::video.scaling_mode = enumFromString(SCALING_MODE_NAMES, node["scaling_mode"].get_value<std::string>());
}
if (node.contains("texture_filter")) {
Options::video.texture_filter = filterFromString(node["texture_filter"].get_value<std::string>());
Options::video.texture_filter = enumFromString(TEXTURE_FILTER_NAMES, node["texture_filter"].get_value<std::string>());
}
if (node.contains("render_info_position")) {
Options::video.render_info_position = renderInfoPositionFromString(node["render_info_position"].get_value<std::string>());
Options::video.render_info_position = enumFromString(RENDER_INFO_POSITION_NAMES, node["render_info_position"].get_value<std::string>());
}
if (node.contains("render_info_show_time")) {
Options::video.render_info_show_time = node["render_info_show_time"].get_value<bool>();
@@ -485,9 +477,9 @@ namespace Options {
out << "video:\n";
out << " vsync: " << (video.vsync ? "true" : "false") << "\n";
out << " scaling_mode: \"" << scalingModeToString(video.scaling_mode) << "\"\n";
out << " texture_filter: \"" << filterToString(video.texture_filter) << "\"\n";
out << " render_info_position: \"" << renderInfoPositionToString(video.render_info_position) << "\"\n";
out << " scaling_mode: \"" << enumToString(SCALING_MODE_NAMES, video.scaling_mode) << "\"\n";
out << " texture_filter: \"" << enumToString(TEXTURE_FILTER_NAMES, video.texture_filter) << "\"\n";
out << " render_info_position: \"" << enumToString(RENDER_INFO_POSITION_NAMES, video.render_info_position) << "\"\n";
out << " render_info_show_time: " << (video.render_info_show_time ? "true" : "false") << "\n";
out << " gpu:\n";
out << " acceleration: " << (video.gpu.acceleration ? "true" : "false") << "\n";