fix custom setting values not being loaded

This commit is contained in:
HJfod 2024-09-14 23:54:29 +03:00
parent f9a6333c94
commit 2999fb242a

View file

@ -86,8 +86,47 @@ public:
};
std::string modID;
std::unordered_map<std::string, SettingInfo> settings;
// Stored so custom settings registered after the fact can be loaded
// If the ability to unregister custom settings is ever added, remember to
// update this by calling saveSettingValueToSave
matjson::Object savedata;
bool restartRequired = false;
void loadSettingValueFromSave(std::string_view key) {
if (this->savedata.contains(key) && this->settings.contains(key)) {
auto& sett = this->settings.at(key);
if (!sett.v3) return;
try {
if (!sett.v3->load(this->savedata[key])) {
log::error("Unable to load setting '{}' for mod {}", key, this->modID);
}
}
// matjson::JsonException doesn't catch all possible json errors
catch(std::exception const& e) {
log::error("Unable to load setting '{}' for mod {} (JSON exception): {}", key, this->modID, e.what());
}
}
}
void saveSettingValueToSave(std::string_view key) {
if (this->settings.contains(key)) {
auto& sett = this->settings.at(key);
// Store the value in an intermediary so if `save` fails the existing
// value loaded from disk isn't overwritten
matjson::Value value;
try {
if (sett.v3->save(value)) {
this->savedata[key] = value;
}
else {
log::error("Unable to save setting '{}' for mod {}", key, m_impl->modID);
}
}
catch(matjson::JsonException const& e) {
log::error("Unable to save setting '{}' for mod {} (JSON exception): {}", key, m_impl->modID, e.what());
}
}
}
void createSettings() {
for (auto& [key, setting] : settings) {
if (setting.v3) {
@ -100,6 +139,7 @@ public:
}
if (auto v3 = (*gen)(key, modID, setting.json)) {
setting.v3 = *v3;
this->loadSettingValueFromSave(key);
}
else {
log::error(
@ -177,43 +217,25 @@ Result<> ModSettingsManager::registerLegacyCustomSetting(std::string_view key, s
}
Result<> ModSettingsManager::load(matjson::Value const& json) {
auto root = checkJson(json, "Settings");
for (auto const& [key, value] : root.properties()) {
if (m_impl->settings.contains(key)) {
auto& sett = m_impl->settings.at(key);
if (!sett.v3) continue;
try {
if (!sett.v3->load(value.json())) {
log::error("Unable to load setting '{}' for mod {}", key, m_impl->modID);
}
}
// matjson::JsonException doesn't catch all possible json errors
catch(std::exception const& e) {
log::error("Unable to load setting '{}' for mod {} (JSON exception): {}", key, m_impl->modID, e.what());
}
if (json.is_object()) {
// Save this so when custom settings are registered they can load their
// values properly
m_impl->savedata = json.as_object();
for (auto const& [key, _] : json.as_object()) {
m_impl->loadSettingValueFromSave(key);
}
}
return Ok();
}
void ModSettingsManager::save(matjson::Value& json) {
for (auto& [key, sett] : m_impl->settings) {
if (!sett.v3) {
continue;
}
// Store the value in an intermediary so if `save` fails the existing
// value loaded from disk isn't overwritten
matjson::Value value;
try {
if (sett.v3->save(value)) {
json[key] = value;
}
else {
log::error("Unable to save setting '{}' for mod {}", key, m_impl->modID);
}
}
catch(matjson::JsonException const& e) {
log::error("Unable to save setting '{}' for mod {} (JSON exception): {}", key, m_impl->modID, e.what());
}
for (auto& [key, _] : m_impl->settings) {
m_impl->saveSettingValueToSave(key);
}
// Doing this indirection instead of just `json = m_impl->savedata` because
// we do NOT want to accidentally discard keys present in `json` but not in
// `m_impl->savedata`
for (auto& [key, value] : m_impl->savedata) {
json[key] = value;
}
}