settings: Give indices to enums

This commit is contained in:
lat9nq 2023-06-21 21:41:06 -04:00
parent ecc1feff64
commit e7f01128f1
3 changed files with 36 additions and 6 deletions

View File

@ -220,6 +220,11 @@ public:
*/ */
[[nodiscard]] virtual constexpr bool Ranged() const = 0; [[nodiscard]] virtual constexpr bool Ranged() const = 0;
/**
* @returns The index of the enum if the underlying setting type is an enum, else max of u32.
*/
[[nodiscard]] virtual constexpr u32 EnumIndex() const = 0;
/* /*
* Switchable settings * Switchable settings
*/ */

View File

@ -11,8 +11,9 @@
namespace Settings { namespace Settings {
template <typename T> template <typename T>
struct Canonicalization { struct EnumMetadata {
static constexpr std::vector<std::pair<std::string, T>> Get(); static constexpr std::vector<std::pair<std::string, T>> Canonicalizations();
static constexpr u32 Index();
}; };
#define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__)) #define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__))
@ -65,10 +66,17 @@ struct Canonicalization {
#define ENUM(NAME, ...) \ #define ENUM(NAME, ...) \
enum class NAME : u32 { __VA_ARGS__ }; \ enum class NAME : u32 { __VA_ARGS__ }; \
template <> \ template <> \
constexpr std::vector<std::pair<std::string, NAME>> Canonicalization<NAME>::Get() { \ constexpr std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \
return {PAIR(NAME, __VA_ARGS__)}; \ return {PAIR(NAME, __VA_ARGS__)}; \
} \
template <> \
constexpr u32 EnumMetadata<NAME>::Index() { \
return __COUNTER__; \
} }
// AudioEngine must be specified discretely due to having existing but slightly different
// canonicalizations
// TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id
enum class AudioEngine : u32 { enum class AudioEngine : u32 {
Auto, Auto,
Cubeb, Cubeb,
@ -77,7 +85,8 @@ enum class AudioEngine : u32 {
}; };
template <> template <>
constexpr std::vector<std::pair<std::string, AudioEngine>> Canonicalization<AudioEngine>::Get() { constexpr std::vector<std::pair<std::string, AudioEngine>>
EnumMetadata<AudioEngine>::Canonicalizations() {
return { return {
{"auto", AudioEngine::Auto}, {"auto", AudioEngine::Auto},
{"cubeb", AudioEngine::Cubeb}, {"cubeb", AudioEngine::Cubeb},
@ -86,6 +95,13 @@ constexpr std::vector<std::pair<std::string, AudioEngine>> Canonicalization<Audi
}; };
} }
template <>
constexpr u32 EnumMetadata<AudioEngine>::Index() {
// This is just a sufficiently large number that is more than the number of other enums declared
// here
return 100;
}
ENUM(AudioMode, Mono, Stereo, Surround); ENUM(AudioMode, Mono, Stereo, Surround);
ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch, ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch,
@ -130,7 +146,7 @@ ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
template <typename Type> template <typename Type>
constexpr std::string CanonicalizeEnum(Type id) { constexpr std::string CanonicalizeEnum(Type id) {
const auto group = Canonicalization<Type>::Get(); const auto group = EnumMetadata<Type>::Canonicalizations();
for (auto& [name, value] : group) { for (auto& [name, value] : group) {
if (value == id) { if (value == id) {
return name; return name;
@ -141,7 +157,7 @@ constexpr std::string CanonicalizeEnum(Type id) {
template <typename Type> template <typename Type>
constexpr Type ToEnum(const std::string& canonicalization) { constexpr Type ToEnum(const std::string& canonicalization) {
const auto group = Canonicalization<Type>::Get(); const auto group = EnumMetadata<Type>::Canonicalizations();
for (auto& [name, value] : group) { for (auto& [name, value] : group) {
if (name == canonicalization) { if (name == canonicalization) {
return value; return value;

View File

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <limits>
#include <map> #include <map>
#include <optional> #include <optional>
#include <stdexcept> #include <stdexcept>
@ -197,6 +198,14 @@ public:
return std::type_index(typeid(Type)); return std::type_index(typeid(Type));
} }
constexpr u32 EnumIndex() const override {
if constexpr (std::is_enum<Type>()) {
return EnumMetadata<Type>::Index();
} else {
return std::numeric_limits<u32>::max();
}
}
virtual std::string MinVal() const override { virtual std::string MinVal() const override {
return this->ToString(minimum); return this->ToString(minimum);
} }