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:
1 parent
206ba07a6f
commit
982a1788f1
2 files changed
+44
-52
No files matched your search
+42
-50
@@ -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";
|
||||
|
||||
Reference in new issue
Block a user