diff options
| -rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/common/settings.cpp | 5 | ||||
| -rw-r--r-- | src/common/settings_setting.h | 77 |
3 files changed, 51 insertions, 32 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index e205055e6..bf97d9ba2 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -205,6 +205,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") | |||
| 205 | -Werror=unreachable-code-aggressive | 205 | -Werror=unreachable-code-aggressive |
| 206 | ) | 206 | ) |
| 207 | target_compile_definitions(common PRIVATE | 207 | target_compile_definitions(common PRIVATE |
| 208 | # Clang 14 and earlier have errors when explicitly instantiating Settings::Setting | ||
| 208 | $<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,15>:CANNOT_EXPLICITLY_INSTANTIATE> | 209 | $<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,15>:CANNOT_EXPLICITLY_INSTANTIATE> |
| 209 | ) | 210 | ) |
| 210 | endif() | 211 | endif() |
diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 78fa99113..59d24a053 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | namespace Settings { | 26 | namespace Settings { |
| 27 | 27 | ||
| 28 | // Clang 14 and earlier have errors when explicitly instantiating these classes | ||
| 28 | #ifndef CANNOT_EXPLICITLY_INSTANTIATE | 29 | #ifndef CANNOT_EXPLICITLY_INSTANTIATE |
| 29 | #define SETTING(TYPE, RANGED) template class Setting<TYPE, RANGED> | 30 | #define SETTING(TYPE, RANGED) template class Setting<TYPE, RANGED> |
| 30 | #define SWITCHABLE(TYPE, RANGED) template class SwitchableSetting<TYPE, RANGED> | 31 | #define SWITCHABLE(TYPE, RANGED) template class SwitchableSetting<TYPE, RANGED> |
| @@ -113,11 +114,11 @@ void LogSettings() { | |||
| 113 | 114 | ||
| 114 | for (const auto& setting : settings) { | 115 | for (const auto& setting : settings) { |
| 115 | if (setting->Id() == values.yuzu_token.Id()) { | 116 | if (setting->Id() == values.yuzu_token.Id()) { |
| 116 | // Hide the token secret, which could be used to share patreon builds | 117 | // Hide the token secret, for security reasons. |
| 117 | continue; | 118 | continue; |
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | std::string name = fmt::format( | 121 | const auto name = fmt::format( |
| 121 | "{:c}{:c} {}.{}", setting->ToString() == setting->DefaultToString() ? '-' : 'M', | 122 | "{:c}{:c} {}.{}", setting->ToString() == setting->DefaultToString() ? '-' : 'M', |
| 122 | setting->UsingGlobal() ? '-' : 'C', TranslateCategory(category), | 123 | setting->UsingGlobal() ? '-' : 'C', TranslateCategory(category), |
| 123 | setting->GetLabel()); | 124 | setting->GetLabel()); |
diff --git a/src/common/settings_setting.h b/src/common/settings_setting.h index 2e708fa0d..959b4f3f9 100644 --- a/src/common/settings_setting.h +++ b/src/common/settings_setting.h | |||
| @@ -34,6 +34,10 @@ public: | |||
| 34 | * @param default_val Initial value of the setting, and default value of the setting | 34 | * @param default_val Initial value of the setting, and default value of the setting |
| 35 | * @param name Label for the setting | 35 | * @param name Label for the setting |
| 36 | * @param category_ Category of the setting AKA INI group | 36 | * @param category_ Category of the setting AKA INI group |
| 37 | * @param specialization_ Suggestion for how frontend implemetations represent this in a config | ||
| 38 | * @param save_ Suggests that this should or should not be saved to a frontend config file | ||
| 39 | * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded | ||
| 40 | * @param other_setting_ A second Setting to associate to this one in metadata | ||
| 37 | */ | 41 | */ |
| 38 | explicit Setting(Linkage& linkage, const Type& default_val, const std::string& name, | 42 | explicit Setting(Linkage& linkage, const Type& default_val, const std::string& name, |
| 39 | enum Category category_, u32 specialization_ = Specialization::Default, | 43 | enum Category category_, u32 specialization_ = Specialization::Default, |
| @@ -54,6 +58,10 @@ public: | |||
| 54 | * @param max_val Sets the maximum allowed value of the setting | 58 | * @param max_val Sets the maximum allowed value of the setting |
| 55 | * @param name Label for the setting | 59 | * @param name Label for the setting |
| 56 | * @param category_ Category of the setting AKA INI group | 60 | * @param category_ Category of the setting AKA INI group |
| 61 | * @param specialization_ Suggestion for how frontend implemetations represent this in a config | ||
| 62 | * @param save_ Suggests that this should or should not be saved to a frontend config file | ||
| 63 | * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded | ||
| 64 | * @param other_setting_ A second Setting to associate to this one in metadata | ||
| 57 | */ | 65 | */ |
| 58 | explicit Setting(Linkage& linkage, const Type& default_val, const Type& min_val, | 66 | explicit Setting(Linkage& linkage, const Type& default_val, const Type& min_val, |
| 59 | const Type& max_val, const std::string& name, enum Category category_, | 67 | const Type& max_val, const std::string& name, enum Category category_, |
| @@ -93,18 +101,19 @@ public: | |||
| 93 | } | 101 | } |
| 94 | 102 | ||
| 95 | [[nodiscard]] constexpr bool IsEnum() const override { | 103 | [[nodiscard]] constexpr bool IsEnum() const override { |
| 96 | return std::is_enum<Type>::value; | 104 | return std::is_enum_v<Type>; |
| 97 | } | 105 | } |
| 98 | 106 | ||
| 99 | protected: | 107 | protected: |
| 100 | std::string ToString(const Type& value_) const { | 108 | [[nodiscard]] std::string ToString(const Type& value_) const { |
| 101 | if constexpr (std::is_same<Type, std::string>()) { | 109 | if constexpr (std::is_same_v<Type, std::string>) { |
| 102 | return value_; | 110 | return value_; |
| 103 | } else if constexpr (std::is_same<Type, std::optional<u32>>()) { | 111 | } else if constexpr (std::is_same_v<Type, std::optional<u32>>) { |
| 104 | return value_.has_value() ? std::to_string(*value_) : "none"; | 112 | return value_.has_value() ? std::to_string(*value_) : "none"; |
| 105 | } else if constexpr (std::is_same<Type, bool>()) { | 113 | } else if constexpr (std::is_same_v<Type, bool>) { |
| 106 | return value_ ? "true" : "false"; | 114 | return value_ ? "true" : "false"; |
| 107 | } else if constexpr (std::is_same<Type, AudioEngine>()) { | 115 | } else if constexpr (std::is_same_v<Type, AudioEngine>) { |
| 116 | // Compatibility with old AudioEngine setting being a string | ||
| 108 | return CanonicalizeEnum(value_); | 117 | return CanonicalizeEnum(value_); |
| 109 | } else { | 118 | } else { |
| 110 | return std::to_string(static_cast<u64>(value_)); | 119 | return std::to_string(static_cast<u64>(value_)); |
| @@ -118,7 +127,7 @@ public: | |||
| 118 | * | 127 | * |
| 119 | * @returns The current setting as a std::string | 128 | * @returns The current setting as a std::string |
| 120 | */ | 129 | */ |
| 121 | std::string ToString() const override { | 130 | [[nodiscard]] std::string ToString() const override { |
| 122 | return ToString(this->GetValue()); | 131 | return ToString(this->GetValue()); |
| 123 | } | 132 | } |
| 124 | 133 | ||
| @@ -127,7 +136,7 @@ public: | |||
| 127 | * | 136 | * |
| 128 | * @returns The default value as a string. | 137 | * @returns The default value as a string. |
| 129 | */ | 138 | */ |
| 130 | std::string DefaultToString() const override { | 139 | [[nodiscard]] std::string DefaultToString() const override { |
| 131 | return ToString(default_value); | 140 | return ToString(default_value); |
| 132 | } | 141 | } |
| 133 | 142 | ||
| @@ -159,19 +168,19 @@ public: | |||
| 159 | * | 168 | * |
| 160 | * @param input The desired value | 169 | * @param input The desired value |
| 161 | */ | 170 | */ |
| 162 | void LoadString(const std::string& input) override { | 171 | void LoadString(const std::string& input) override final { |
| 163 | if (input.empty()) { | 172 | if (input.empty()) { |
| 164 | this->SetValue(this->GetDefault()); | 173 | this->SetValue(this->GetDefault()); |
| 165 | return; | 174 | return; |
| 166 | } | 175 | } |
| 167 | try { | 176 | try { |
| 168 | if constexpr (std::is_same<Type, std::string>()) { | 177 | if constexpr (std::is_same_v<Type, std::string>) { |
| 169 | this->SetValue(input); | 178 | this->SetValue(input); |
| 170 | } else if constexpr (std::is_same<Type, std::optional<u32>>()) { | 179 | } else if constexpr (std::is_same_v<Type, std::optional<u32>>) { |
| 171 | this->SetValue(static_cast<u32>(std::stoul(input))); | 180 | this->SetValue(static_cast<u32>(std::stoul(input))); |
| 172 | } else if constexpr (std::is_same<Type, bool>()) { | 181 | } else if constexpr (std::is_same_v<Type, bool>) { |
| 173 | this->SetValue(input == "true"); | 182 | this->SetValue(input == "true"); |
| 174 | } else if constexpr (std::is_same<Type, AudioEngine>()) { | 183 | } else if constexpr (std::is_same_v<Type, AudioEngine>) { |
| 175 | this->SetValue(ToEnum<Type>(input)); | 184 | this->SetValue(ToEnum<Type>(input)); |
| 176 | } else { | 185 | } else { |
| 177 | this->SetValue(static_cast<Type>(std::stoll(input))); | 186 | this->SetValue(static_cast<Type>(std::stoll(input))); |
| @@ -181,8 +190,8 @@ public: | |||
| 181 | } | 190 | } |
| 182 | } | 191 | } |
| 183 | 192 | ||
| 184 | [[nodiscard]] std::string constexpr Canonicalize() const override { | 193 | [[nodiscard]] std::string constexpr Canonicalize() const override final { |
| 185 | if constexpr (std::is_enum<Type>::value) { | 194 | if constexpr (std::is_enum_v<Type>) { |
| 186 | return CanonicalizeEnum(this->GetValue()); | 195 | return CanonicalizeEnum(this->GetValue()); |
| 187 | } else { | 196 | } else { |
| 188 | return ToString(this->GetValue()); | 197 | return ToString(this->GetValue()); |
| @@ -194,26 +203,26 @@ public: | |||
| 194 | * | 203 | * |
| 195 | * @returns the type_index of the setting's type | 204 | * @returns the type_index of the setting's type |
| 196 | */ | 205 | */ |
| 197 | virtual std::type_index TypeId() const override { | 206 | [[nodiscard]] std::type_index TypeId() const override final { |
| 198 | return std::type_index(typeid(Type)); | 207 | return std::type_index(typeid(Type)); |
| 199 | } | 208 | } |
| 200 | 209 | ||
| 201 | constexpr u32 EnumIndex() const override { | 210 | [[nodiscard]] constexpr u32 EnumIndex() const override final { |
| 202 | if constexpr (std::is_enum<Type>()) { | 211 | if constexpr (std::is_enum_v<Type>) { |
| 203 | return EnumMetadata<Type>::Index(); | 212 | return EnumMetadata<Type>::Index(); |
| 204 | } else { | 213 | } else { |
| 205 | return std::numeric_limits<u32>::max(); | 214 | return std::numeric_limits<u32>::max(); |
| 206 | } | 215 | } |
| 207 | } | 216 | } |
| 208 | 217 | ||
| 209 | virtual std::string MinVal() const override { | 218 | [[nodiscard]] std::string MinVal() const override final { |
| 210 | return this->ToString(minimum); | 219 | return this->ToString(minimum); |
| 211 | } | 220 | } |
| 212 | virtual std::string MaxVal() const override { | 221 | [[nodiscard]] std::string MaxVal() const override final { |
| 213 | return this->ToString(maximum); | 222 | return this->ToString(maximum); |
| 214 | } | 223 | } |
| 215 | 224 | ||
| 216 | constexpr bool Ranged() const override { | 225 | [[nodiscard]] constexpr bool Ranged() const override { |
| 217 | return ranged; | 226 | return ranged; |
| 218 | } | 227 | } |
| 219 | 228 | ||
| @@ -242,6 +251,10 @@ public: | |||
| 242 | * @param default_val Initial value of the setting, and default value of the setting | 251 | * @param default_val Initial value of the setting, and default value of the setting |
| 243 | * @param name Label for the setting | 252 | * @param name Label for the setting |
| 244 | * @param category_ Category of the setting AKA INI group | 253 | * @param category_ Category of the setting AKA INI group |
| 254 | * @param specialization_ Suggestion for how frontend implemetations represent this in a config | ||
| 255 | * @param save_ Suggests that this should or should not be saved to a frontend config file | ||
| 256 | * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded | ||
| 257 | * @param other_setting_ A second Setting to associate to this one in metadata | ||
| 245 | */ | 258 | */ |
| 246 | explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, | 259 | explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, |
| 247 | Category category_, u32 specialization_ = Specialization::Default, | 260 | Category category_, u32 specialization_ = Specialization::Default, |
| @@ -264,6 +277,10 @@ public: | |||
| 264 | * @param max_val Sets the maximum allowed value of the setting | 277 | * @param max_val Sets the maximum allowed value of the setting |
| 265 | * @param name Label for the setting | 278 | * @param name Label for the setting |
| 266 | * @param category_ Category of the setting AKA INI group | 279 | * @param category_ Category of the setting AKA INI group |
| 280 | * @param specialization_ Suggestion for how frontend implemetations represent this in a config | ||
| 281 | * @param save_ Suggests that this should or should not be saved to a frontend config file | ||
| 282 | * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded | ||
| 283 | * @param other_setting_ A second Setting to associate to this one in metadata | ||
| 267 | */ | 284 | */ |
| 268 | explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, | 285 | explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, |
| 269 | const Type& max_val, const std::string& name, Category category_, | 286 | const Type& max_val, const std::string& name, Category category_, |
| @@ -284,7 +301,7 @@ public: | |||
| 284 | * | 301 | * |
| 285 | * @param to_global Whether to use the global or custom setting. | 302 | * @param to_global Whether to use the global or custom setting. |
| 286 | */ | 303 | */ |
| 287 | void SetGlobal(bool to_global) override { | 304 | void SetGlobal(bool to_global) override final { |
| 288 | use_global = to_global; | 305 | use_global = to_global; |
| 289 | } | 306 | } |
| 290 | 307 | ||
| @@ -293,7 +310,7 @@ public: | |||
| 293 | * | 310 | * |
| 294 | * @returns The global state | 311 | * @returns The global state |
| 295 | */ | 312 | */ |
| 296 | [[nodiscard]] bool UsingGlobal() const override { | 313 | [[nodiscard]] bool UsingGlobal() const override final { |
| 297 | return use_global; | 314 | return use_global; |
| 298 | } | 315 | } |
| 299 | 316 | ||
| @@ -305,13 +322,13 @@ public: | |||
| 305 | * | 322 | * |
| 306 | * @returns The required value of the setting | 323 | * @returns The required value of the setting |
| 307 | */ | 324 | */ |
| 308 | [[nodiscard]] virtual const Type& GetValue() const override { | 325 | [[nodiscard]] const Type& GetValue() const override final { |
| 309 | if (use_global) { | 326 | if (use_global) { |
| 310 | return this->value; | 327 | return this->value; |
| 311 | } | 328 | } |
| 312 | return custom; | 329 | return custom; |
| 313 | } | 330 | } |
| 314 | [[nodiscard]] virtual const Type& GetValue(bool need_global) const { | 331 | [[nodiscard]] const Type& GetValue(bool need_global) const { |
| 315 | if (use_global || need_global) { | 332 | if (use_global || need_global) { |
| 316 | return this->value; | 333 | return this->value; |
| 317 | } | 334 | } |
| @@ -323,7 +340,7 @@ public: | |||
| 323 | * | 340 | * |
| 324 | * @param val The new value | 341 | * @param val The new value |
| 325 | */ | 342 | */ |
| 326 | void SetValue(const Type& val) override { | 343 | void SetValue(const Type& val) override final { |
| 327 | Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val}; | 344 | Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val}; |
| 328 | if (use_global) { | 345 | if (use_global) { |
| 329 | std::swap(this->value, temp); | 346 | std::swap(this->value, temp); |
| @@ -332,11 +349,11 @@ public: | |||
| 332 | } | 349 | } |
| 333 | } | 350 | } |
| 334 | 351 | ||
| 335 | [[nodiscard]] virtual constexpr bool Switchable() const override { | 352 | [[nodiscard]] constexpr bool Switchable() const override final { |
| 336 | return true; | 353 | return true; |
| 337 | } | 354 | } |
| 338 | 355 | ||
| 339 | [[nodiscard]] virtual std::string ToStringGlobal() const override { | 356 | [[nodiscard]] std::string ToStringGlobal() const override final { |
| 340 | return this->ToString(this->value); | 357 | return this->ToString(this->value); |
| 341 | } | 358 | } |
| 342 | 359 | ||
| @@ -347,7 +364,7 @@ public: | |||
| 347 | * | 364 | * |
| 348 | * @returns A reference to the current setting value | 365 | * @returns A reference to the current setting value |
| 349 | */ | 366 | */ |
| 350 | const Type& operator=(const Type& val) override { | 367 | const Type& operator=(const Type& val) override final { |
| 351 | Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val}; | 368 | Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val}; |
| 352 | if (use_global) { | 369 | if (use_global) { |
| 353 | std::swap(this->value, temp); | 370 | std::swap(this->value, temp); |
| @@ -362,7 +379,7 @@ public: | |||
| 362 | * | 379 | * |
| 363 | * @returns A reference to the current setting value | 380 | * @returns A reference to the current setting value |
| 364 | */ | 381 | */ |
| 365 | virtual explicit operator const Type&() const override { | 382 | explicit operator const Type&() const override final { |
| 366 | if (use_global) { | 383 | if (use_global) { |
| 367 | return this->value; | 384 | return this->value; |
| 368 | } | 385 | } |