[Config] Gracefully handle type mismatches in cvars.
Detect cvar type mismatch and reset to default value, as well as show message to the user that the cvar from the config has been updated.
This commit is contained in:
committed by
Radosław Gliński
parent
70e44ab6ec
commit
93adb2bb95
@@ -30,6 +30,7 @@ cxxopts::Options options("xenia", "Xbox 360 Emulator");
|
||||
std::map<std::string, ICommandVar*>* CmdVars;
|
||||
std::map<std::string, IConfigVar*>* ConfigVars;
|
||||
std::multimap<uint32_t, const IConfigVarUpdate*>* IConfigVarUpdate::updates_;
|
||||
std::vector<std::string>* config_type_mismatch_warnings = nullptr;
|
||||
|
||||
void PrintHelpAndExit() {
|
||||
std::cout << options.help({""}) << std::endl;
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace toml_internal {
|
||||
std::string EscapeString(const std::string_view str);
|
||||
}
|
||||
|
||||
// Track config values that had type mismatches during loading
|
||||
extern std::vector<std::string>* config_type_mismatch_warnings;
|
||||
|
||||
class ICommandVar {
|
||||
public:
|
||||
virtual ~ICommandVar() = default;
|
||||
@@ -147,7 +150,16 @@ inline void CommandVar<std::filesystem::path>::LoadFromLaunchOptions(
|
||||
}
|
||||
template <class T>
|
||||
void ConfigVar<T>::LoadConfigValue(const toml::node* result) {
|
||||
SetConfigValue(result->value<T>().value());
|
||||
auto value_opt = result->value<T>();
|
||||
if (value_opt) {
|
||||
SetConfigValue(value_opt.value());
|
||||
} else {
|
||||
// Type mismatch - track for warning
|
||||
if (!config_type_mismatch_warnings) {
|
||||
config_type_mismatch_warnings = new std::vector<std::string>();
|
||||
}
|
||||
config_type_mismatch_warnings->push_back(this->name_);
|
||||
}
|
||||
}
|
||||
template <>
|
||||
inline void ConfigVar<std::filesystem::path>::LoadConfigValue(
|
||||
@@ -157,7 +169,16 @@ inline void ConfigVar<std::filesystem::path>::LoadConfigValue(
|
||||
}
|
||||
template <class T>
|
||||
void ConfigVar<T>::LoadGameConfigValue(const toml::node* result) {
|
||||
SetGameConfigValue(result->value<T>().value());
|
||||
auto value_opt = result->value<T>();
|
||||
if (value_opt) {
|
||||
SetGameConfigValue(value_opt.value());
|
||||
} else {
|
||||
// Type mismatch - track for warning
|
||||
if (!config_type_mismatch_warnings) {
|
||||
config_type_mismatch_warnings = new std::vector<std::string>();
|
||||
}
|
||||
config_type_mismatch_warnings->push_back(this->name_);
|
||||
}
|
||||
}
|
||||
template <>
|
||||
inline void ConfigVar<std::filesystem::path>::LoadGameConfigValue(
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/string.h"
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/base/system.h"
|
||||
|
||||
toml::parse_result ParseFile(const std::filesystem::path& filename) {
|
||||
return toml::parse_file(xe::path_to_utf8(filename));
|
||||
@@ -118,6 +119,26 @@ void ReadConfig(const std::filesystem::path& file_path,
|
||||
cvar::IConfigVarUpdate::ApplyUpdates(config_defaults_date);
|
||||
}
|
||||
|
||||
// Check for type mismatch warnings
|
||||
if (cvar::config_type_mismatch_warnings &&
|
||||
!cvar::config_type_mismatch_warnings->empty()) {
|
||||
std::string warning_message =
|
||||
"The following config values had invalid types and have been reset to "
|
||||
"defaults:\n\n";
|
||||
for (const auto& name : *cvar::config_type_mismatch_warnings) {
|
||||
warning_message += " - " + name + "\n";
|
||||
}
|
||||
warning_message +=
|
||||
"\nPlease check your config file. The config will be saved with the "
|
||||
"correct types.";
|
||||
|
||||
xe::ShowSimpleMessageBox(xe::SimpleMessageBoxType::Warning,
|
||||
warning_message);
|
||||
|
||||
// Clear warnings
|
||||
cvar::config_type_mismatch_warnings->clear();
|
||||
}
|
||||
|
||||
XELOGI("Loaded config: {}", file_path);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user