From 7ffbffe170326eb8e21fa96e5374ba6b68370db6 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Tue, 20 Jun 2023 23:25:39 -0400 Subject: [PATCH] settings_enums: More aggressively use macros This lets us define an enum and all the textual representations of its values in one swing. All for the price of some ugly macros. --- src/common/settings_enums.h | 500 +++++++++++------------------------- 1 file changed, 149 insertions(+), 351 deletions(-) diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index f3d76b927..71515257a 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -3,15 +3,72 @@ #pragma once -#include #include -#include -#include -#include +#include +#include #include "common/common_types.h" namespace Settings { +template +struct Canonicalization { + static constexpr std::vector> Get(); +}; + +#define PAIR_45(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_46(N, __VA_ARGS__)) +#define PAIR_44(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_45(N, __VA_ARGS__)) +#define PAIR_43(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_44(N, __VA_ARGS__)) +#define PAIR_42(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_43(N, __VA_ARGS__)) +#define PAIR_41(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_42(N, __VA_ARGS__)) +#define PAIR_40(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_41(N, __VA_ARGS__)) +#define PAIR_39(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_40(N, __VA_ARGS__)) +#define PAIR_38(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_39(N, __VA_ARGS__)) +#define PAIR_37(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_38(N, __VA_ARGS__)) +#define PAIR_36(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_37(N, __VA_ARGS__)) +#define PAIR_35(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_36(N, __VA_ARGS__)) +#define PAIR_34(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_35(N, __VA_ARGS__)) +#define PAIR_33(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_34(N, __VA_ARGS__)) +#define PAIR_32(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_33(N, __VA_ARGS__)) +#define PAIR_31(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_32(N, __VA_ARGS__)) +#define PAIR_30(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_31(N, __VA_ARGS__)) +#define PAIR_29(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_30(N, __VA_ARGS__)) +#define PAIR_28(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_29(N, __VA_ARGS__)) +#define PAIR_27(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_28(N, __VA_ARGS__)) +#define PAIR_26(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_27(N, __VA_ARGS__)) +#define PAIR_25(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_26(N, __VA_ARGS__)) +#define PAIR_24(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_25(N, __VA_ARGS__)) +#define PAIR_23(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_24(N, __VA_ARGS__)) +#define PAIR_22(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_23(N, __VA_ARGS__)) +#define PAIR_21(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_22(N, __VA_ARGS__)) +#define PAIR_20(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_21(N, __VA_ARGS__)) +#define PAIR_19(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_20(N, __VA_ARGS__)) +#define PAIR_18(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_19(N, __VA_ARGS__)) +#define PAIR_17(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_18(N, __VA_ARGS__)) +#define PAIR_16(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_17(N, __VA_ARGS__)) +#define PAIR_15(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_16(N, __VA_ARGS__)) +#define PAIR_14(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_15(N, __VA_ARGS__)) +#define PAIR_13(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_14(N, __VA_ARGS__)) +#define PAIR_12(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_13(N, __VA_ARGS__)) +#define PAIR_11(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_12(N, __VA_ARGS__)) +#define PAIR_10(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_11(N, __VA_ARGS__)) +#define PAIR_9(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_10(N, __VA_ARGS__)) +#define PAIR_8(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_9(N, __VA_ARGS__)) +#define PAIR_7(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_8(N, __VA_ARGS__)) +#define PAIR_6(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_7(N, __VA_ARGS__)) +#define PAIR_5(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_6(N, __VA_ARGS__)) +#define PAIR_4(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_5(N, __VA_ARGS__)) +#define PAIR_3(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_4(N, __VA_ARGS__)) +#define PAIR_2(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_3(N, __VA_ARGS__)) +#define PAIR_1(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_2(N, __VA_ARGS__)) +#define PAIR(N, X, ...) {#X, static_cast(N::X)} __VA_OPT__(, PAIR_1(N, __VA_ARGS__)) + +#define ENUM(NAME, ...) \ + enum class NAME : u32 { __VA_ARGS__ }; \ + template <> \ + constexpr std::vector> Canonicalization::Get() { \ + return {PAIR(NAME, __VA_ARGS__)}; \ + } + enum class AudioEngine : u32 { Auto, Cubeb, @@ -19,380 +76,121 @@ enum class AudioEngine : u32 { Null, }; -enum class AudioMode : u32 { - Mono, - Stereo, - Surround, -}; +template <> +constexpr std::vector> Canonicalization::Get() { + return { + {"auto", static_cast(AudioEngine::Auto)}, + {"cubeb", static_cast(AudioEngine::Cubeb)}, + {"sdl2", static_cast(AudioEngine::Sdl2)}, + {"null", static_cast(AudioEngine::Null)}, + }; +} -enum class Language : u32 { - Japanese, - EnglishAmerican, - French, - German, - Italian, - Spanish, - Chinese, - Korean, - Dutch, - Portuguese, - Russian, - Taiwanese, - EnglishBritish, - FrenchCanadian, - SpanishLatin, - ChineseSimplified, - ChineseTraditional, - PortugueseBrazilian, -}; +ENUM(AudioMode, Mono, Stereo, Surround); -enum class Region : u32 { - Japan, - Usa, - Europe, - Australia, - China, - Korea, - Taiwan, -}; +ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch, + Portuguese, Russian, Taiwanese, EnglishBritish, FrenchCanadian, SpanishLatin, + ChineseSimplified, ChineseTraditional, PortugueseBrazilian); -enum class TimeZone : u32 { - Auto, - Default, - CET, - CST6CDT, - Cuba, - EET, - Egypt, - Eire, - EST, - EST5EDT, - GB, - GBEire, - GMT, - GMTPlusZero, - GMTMinusZero, - GMTZero, - Greenwich, - Hongkong, - HST, - Iceland, - Iran, - Israel, - Jamaica, - Japan, - Kwajalein, - Libya, - MET, - MST, - MST7MDT, - Navajo, - NZ, - NZCHAT, - Poland, - Portugal, - PRC, - PST8PDT, - ROC, - ROK, - Singapore, - Turkey, - UCT, - Universal, - UTC, - W_SU, - WET, - Zulu, -}; +ENUM(Region, Japan, Usa, Europe, Australia, China, Korea, Taiwan); -enum class AnisotropyMode : u32 { - Automatic = 0, - Default = 1, - X2 = 2, - X4 = 3, - X8 = 4, - X16 = 5, -}; +ENUM(TimeZone, Auto, Default, CET, CST6CDT, Cuba, EET, Egypt, Eire, EST, EST5EDT, GB, GBEire, GMT, + GMTPlusZero, GMTMinusZero, GMTZero, Greenwich, Hongkong, HST, Iceland, Iran, Israel, Jamaica, + Japan, Kwajalein, Libya, MET, MST, MST7MDT, Navajo, NZ, NZCHAT, Poland, Portugal, PRC, PST8PDT, + ROC, ROK, Singapore, Turkey, UCT, Universal, UTC, W_SU, WET, Zulu); -enum class AstcDecodeMode : u32 { - Cpu = 0, - Gpu = 1, - CpuAsynchronous = 2, -}; +ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16); -enum class AstcRecompression : u32 { - Uncompressed = 0, - Bc1 = 1, - Bc3 = 2, -}; +ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous); -enum class VSyncMode : u32 { - Immediate = 0, - Mailbox = 1, - Fifo = 2, - FifoRelaxed = 3, -}; +ENUM(AstcRecompression, Uncompressed, Bc1, Bc3); -enum class RendererBackend : u32 { - OpenGL = 0, - Vulkan = 1, - Null = 2, -}; +ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed); -enum class ShaderBackend : u32 { - Glsl = 0, - Glasm = 1, - SpirV = 2, -}; +ENUM(RendererBackend, OpenGL, Vulkan, Null); -enum class GpuAccuracy : u32 { - Normal = 0, - High = 1, - Extreme = 2, -}; +ENUM(ShaderBackend, Glsl, Glasm, SpirV); -enum class CpuAccuracy : u32 { - Auto = 0, - Accurate = 1, - Unsafe = 2, - Paranoid = 3, -}; +ENUM(GpuAccuracy, Normal, High, Extreme); -enum class FullscreenMode : u32 { - Borderless = 0, - Exclusive = 1, -}; +ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid); -enum class NvdecEmulation : u32 { - Off = 0, - Cpu = 1, - Gpu = 2, -}; +ENUM(FullscreenMode, Borderless, Exclusive); -enum class ResolutionSetup : u32 { - Res1_2X = 0, - Res3_4X = 1, - Res1X = 2, - Res3_2X = 3, - Res2X = 4, - Res3X = 5, - Res4X = 6, - Res5X = 7, - Res6X = 8, - Res7X = 9, - Res8X = 10, -}; +ENUM(NvdecEmulation, Off, Cpu, Gpu); -enum class ScalingFilter : u32 { - NearestNeighbor = 0, - Bilinear = 1, - Bicubic = 2, - Gaussian = 3, - ScaleForce = 4, - Fsr = 5, - LastFilter = Fsr, -}; +ENUM(ResolutionSetup, Res1_2X, Res3_4X, Res1X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, + Res8X); -enum class AntiAliasing : u32 { - None = 0, - Fxaa = 1, - Smaa = 2, - LastAA = Smaa, -}; +ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, ScaleForce, Fsr, LastFilter); -enum class AspectRatio : u32 { - R16_9, - R4_3, - R21_9, - R16_10, - Stretch, -}; +ENUM(AntiAliasing, None, Fxaa, Smaa, LastAA); -#define X(ENUM, NAME) \ - { (#NAME), static_cast(ENUM::NAME) } - -static const std::map> canonicalizations = { - {typeid(AudioEngine), - { - {"auto", static_cast(AudioEngine::Auto)}, - {"cubeb", static_cast(AudioEngine::Cubeb)}, - {"sdl2", static_cast(AudioEngine::Sdl2)}, - {"null", static_cast(AudioEngine::Null)}, - }}, - {typeid(AudioMode), - { - X(AudioMode, Mono), - X(AudioMode, Stereo), - X(AudioMode, Surround), - }}, - {typeid(Language), - { - X(Language, Japanese), - X(Language, EnglishAmerican), - X(Language, French), - X(Language, German), - X(Language, Italian), - X(Language, Spanish), - X(Language, Chinese), - X(Language, Korean), - X(Language, Dutch), - X(Language, Portuguese), - X(Language, Russian), - X(Language, Taiwanese), - X(Language, EnglishBritish), - X(Language, FrenchCanadian), - X(Language, SpanishLatin), - X(Language, ChineseSimplified), - X(Language, ChineseTraditional), - X(Language, PortugueseBrazilian), - }}, - {typeid(Region), - { - X(Region, Japan), - X(Region, Usa), - X(Region, Europe), - X(Region, Australia), - X(Region, China), - X(Region, Korea), - X(Region, Taiwan), - }}, - {typeid(TimeZone), - { - X(TimeZone, Auto), X(TimeZone, Default), X(TimeZone, CET), - X(TimeZone, CST6CDT), X(TimeZone, Cuba), X(TimeZone, EET), - X(TimeZone, Egypt), X(TimeZone, Eire), X(TimeZone, EST5EDT), - X(TimeZone, GB), X(TimeZone, GBEire), X(TimeZone, GMT), - X(TimeZone, GMTPlusZero), X(TimeZone, GMTMinusZero), X(TimeZone, GMTZero), - X(TimeZone, Greenwich), X(TimeZone, Hongkong), X(TimeZone, HST), - X(TimeZone, Iceland), X(TimeZone, Iran), X(TimeZone, Israel), - X(TimeZone, Jamaica), X(TimeZone, Japan), X(TimeZone, Kwajalein), - X(TimeZone, Libya), X(TimeZone, MET), X(TimeZone, MST), - X(TimeZone, MST7MDT), X(TimeZone, Navajo), X(TimeZone, NZ), - X(TimeZone, NZCHAT), X(TimeZone, Poland), X(TimeZone, Portugal), - X(TimeZone, PRC), X(TimeZone, ROC), X(TimeZone, ROK), - X(TimeZone, Singapore), X(TimeZone, Turkey), X(TimeZone, UCT), - X(TimeZone, Universal), X(TimeZone, UTC), X(TimeZone, W_SU), - X(TimeZone, WET), X(TimeZone, Zulu), - }}, - {typeid(AnisotropyMode), - { - X(AnisotropyMode, Automatic), - X(AnisotropyMode, Default), - X(AnisotropyMode, X2), - X(AnisotropyMode, X4), - X(AnisotropyMode, X8), - X(AnisotropyMode, X16), - }}, - {typeid(AstcDecodeMode), - { - X(AstcDecodeMode, Cpu), - X(AstcDecodeMode, Gpu), - X(AstcDecodeMode, CpuAsynchronous), - }}, - {typeid(AstcRecompression), - { - X(AstcRecompression, Uncompressed), - X(AstcRecompression, Bc1), - X(AstcRecompression, Bc3), - }}, - {typeid(VSyncMode), - { - X(VSyncMode, Immediate), - X(VSyncMode, Mailbox), - X(VSyncMode, Fifo), - X(VSyncMode, FifoRelaxed), - }}, - {typeid(RendererBackend), - { - X(RendererBackend, OpenGL), - X(RendererBackend, Vulkan), - X(RendererBackend, Null), - }}, - {typeid(ShaderBackend), - { - X(ShaderBackend, Glsl), - X(ShaderBackend, Glasm), - X(ShaderBackend, SpirV), - }}, - {typeid(GpuAccuracy), - { - X(GpuAccuracy, Normal), - X(GpuAccuracy, High), - X(GpuAccuracy, Extreme), - }}, - {typeid(CpuAccuracy), - { - X(CpuAccuracy, Auto), - X(CpuAccuracy, Accurate), - X(CpuAccuracy, Unsafe), - X(CpuAccuracy, Paranoid), - }}, - {typeid(FullscreenMode), - { - X(FullscreenMode, Borderless), - X(FullscreenMode, Exclusive), - }}, - {typeid(NvdecEmulation), - { - X(NvdecEmulation, Off), - X(NvdecEmulation, Cpu), - X(NvdecEmulation, Gpu), - }}, - {typeid(ResolutionSetup), - { - X(ResolutionSetup, Res1_2X), - X(ResolutionSetup, Res3_4X), - X(ResolutionSetup, Res1X), - X(ResolutionSetup, Res3_2X), - X(ResolutionSetup, Res2X), - X(ResolutionSetup, Res3X), - X(ResolutionSetup, Res4X), - X(ResolutionSetup, Res5X), - X(ResolutionSetup, Res6X), - X(ResolutionSetup, Res7X), - X(ResolutionSetup, Res8X), - }}, - {typeid(ScalingFilter), - { - X(ScalingFilter, NearestNeighbor), - X(ScalingFilter, Bilinear), - X(ScalingFilter, Bicubic), - X(ScalingFilter, Gaussian), - X(ScalingFilter, ScaleForce), - X(ScalingFilter, Fsr), - }}, - {typeid(AntiAliasing), - { - X(AntiAliasing, None), - X(AntiAliasing, Fxaa), - X(AntiAliasing, Smaa), - }}, - {typeid(AspectRatio), - { - X(AspectRatio, R16_9), - X(AspectRatio, R4_3), - X(AspectRatio, R21_9), - X(AspectRatio, R16_10), - X(AspectRatio, Stretch), - }}}; - -#undef X - -static const std::string invalid_string{"(invalid setting)"}; +ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); template -const std::string& CanonicalizeEnum(Type id) { - auto& group = canonicalizations.at(typeid(Type)); +constexpr std::string CanonicalizeEnum(Type id) { + const auto group = Canonicalization::Get(); for (auto& [name, value] : group) { if (static_cast(value) == id) { return name; } } - return invalid_string; + return "unknown"; } template -static Type ToEnum(const std::string& canonicalization) { - return static_cast(canonicalizations.at(typeid(Type)).at(canonicalization)); +constexpr Type ToEnum(const std::string& canonicalization) { + const auto group = Canonicalization::Get(); + for (auto& [name, value] : group) { + if (name == canonicalization) { + return static_cast(value); + } + } + return {}; } } // namespace Settings + +#undef ENUM +#undef PAIR +#undef PAIR_1 +#undef PAIR_2 +#undef PAIR_3 +#undef PAIR_4 +#undef PAIR_5 +#undef PAIR_6 +#undef PAIR_7 +#undef PAIR_8 +#undef PAIR_9 +#undef PAIR_10 +#undef PAIR_12 +#undef PAIR_13 +#undef PAIR_14 +#undef PAIR_15 +#undef PAIR_16 +#undef PAIR_17 +#undef PAIR_18 +#undef PAIR_19 +#undef PAIR_20 +#undef PAIR_22 +#undef PAIR_23 +#undef PAIR_24 +#undef PAIR_25 +#undef PAIR_26 +#undef PAIR_27 +#undef PAIR_28 +#undef PAIR_29 +#undef PAIR_30 +#undef PAIR_32 +#undef PAIR_33 +#undef PAIR_34 +#undef PAIR_35 +#undef PAIR_36 +#undef PAIR_37 +#undef PAIR_38 +#undef PAIR_39 +#undef PAIR_40 +#undef PAIR_42 +#undef PAIR_43 +#undef PAIR_44 +#undef PAIR_45