mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
make ModSettingsManager manage savedata fully
Some checks are pending
Build Binaries / Build Windows (push) Waiting to run
Build Binaries / Build macOS (push) Waiting to run
Build Binaries / Build Android (64-bit) (push) Waiting to run
Build Binaries / Build Android (32-bit) (push) Waiting to run
Build Binaries / Publish (push) Blocked by required conditions
Check CHANGELOG.md / Check CHANGELOG.md (push) Waiting to run
Some checks are pending
Build Binaries / Build Windows (push) Waiting to run
Build Binaries / Build macOS (push) Waiting to run
Build Binaries / Build Android (64-bit) (push) Waiting to run
Build Binaries / Build Android (32-bit) (push) Waiting to run
Build Binaries / Publish (push) Blocked by required conditions
Check CHANGELOG.md / Check CHANGELOG.md (push) Waiting to run
This commit is contained in:
parent
361c15be70
commit
8f88913815
5 changed files with 35 additions and 29 deletions
|
@ -4,12 +4,16 @@
|
||||||
#include "SettingV3.hpp"
|
#include "SettingV3.hpp"
|
||||||
|
|
||||||
namespace geode {
|
namespace geode {
|
||||||
|
class Mod;
|
||||||
|
class SettingV3;
|
||||||
|
|
||||||
class GEODE_DLL ModSettingsManager final {
|
class GEODE_DLL ModSettingsManager final {
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
std::unique_ptr<Impl> m_impl;
|
std::unique_ptr<Impl> m_impl;
|
||||||
|
|
||||||
friend class ::geode::SettingV3;
|
friend class ::geode::SettingV3;
|
||||||
|
friend class ::geode::Mod;
|
||||||
|
|
||||||
void markRestartRequired();
|
void markRestartRequired();
|
||||||
|
|
||||||
|
@ -36,9 +40,23 @@ namespace geode {
|
||||||
* The format of the savedata will be an object with the keys being
|
* The format of the savedata will be an object with the keys being
|
||||||
* setting IDs and then the values the values of the saved settings
|
* setting IDs and then the values the values of the saved settings
|
||||||
* @note If saving a setting fails, it will log a warning to the console
|
* @note If saving a setting fails, it will log a warning to the console
|
||||||
|
* @warning This will overwrite the whole `json` parameter - be sure to
|
||||||
|
* pass the full settings savedata to `load()` so you can be sure that
|
||||||
|
* unregistered custom settings' saved values don't disappear!
|
||||||
|
* @todo in v4: make this return the value instead lol
|
||||||
*/
|
*/
|
||||||
void save(matjson::Value& json);
|
void save(matjson::Value& json);
|
||||||
|
|
||||||
|
// todo in 3.7.0: add this
|
||||||
|
/**
|
||||||
|
* Get the savedata for settings, aka the JSON object that contains all
|
||||||
|
* the settings' saved states that was loaded up from disk and will be
|
||||||
|
* saved to disk
|
||||||
|
* @warning Modifying this will modify the value of the settings - use
|
||||||
|
* carefully!
|
||||||
|
*/
|
||||||
|
// matjson::Value& getSaveData();
|
||||||
|
|
||||||
Result<> registerCustomSettingType(std::string_view type, SettingGenerator generator);
|
Result<> registerCustomSettingType(std::string_view type, SettingGenerator generator);
|
||||||
// todo in v4: remove this
|
// todo in v4: remove this
|
||||||
Result<> registerLegacyCustomSetting(std::string_view key, std::unique_ptr<SettingValue>&& ptr);
|
Result<> registerLegacyCustomSetting(std::string_view key, std::unique_ptr<SettingValue>&& ptr);
|
||||||
|
|
|
@ -48,9 +48,8 @@ matjson::Value& Mod::getSaveContainer() {
|
||||||
return m_impl->getSaveContainer();
|
return m_impl->getSaveContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
matjson::Value& Mod::getSavedSettingsData() {
|
// todo in 3.7.0: move Mod::getSavedSettingsData() back here from
|
||||||
return m_impl->getSavedSettingsData();
|
// ModSettingsManager.cpp and make it use ModSettingsManager::getSaveData()
|
||||||
}
|
|
||||||
|
|
||||||
bool Mod::isEnabled() const {
|
bool Mod::isEnabled() const {
|
||||||
return m_impl->isEnabled();
|
return m_impl->isEnabled();
|
||||||
|
|
|
@ -138,10 +138,6 @@ matjson::Value& Mod::Impl::getSaveContainer() {
|
||||||
return m_saved;
|
return m_saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
matjson::Value& Mod::Impl::getSavedSettingsData() {
|
|
||||||
return m_savedSettingsData;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Mod::Impl::isEnabled() const {
|
bool Mod::Impl::isEnabled() const {
|
||||||
return m_enabled || this->isInternal();
|
return m_enabled || this->isInternal();
|
||||||
}
|
}
|
||||||
|
@ -182,7 +178,6 @@ Result<> Mod::Impl::loadData() {
|
||||||
auto settingPath = m_saveDirPath / "settings.json";
|
auto settingPath = m_saveDirPath / "settings.json";
|
||||||
if (std::filesystem::exists(settingPath)) {
|
if (std::filesystem::exists(settingPath)) {
|
||||||
GEODE_UNWRAP_INTO(auto json, utils::file::readJson(settingPath));
|
GEODE_UNWRAP_INTO(auto json, utils::file::readJson(settingPath));
|
||||||
m_savedSettingsData = json;
|
|
||||||
auto load = m_settings->load(json);
|
auto load = m_settings->load(json);
|
||||||
if (!load) {
|
if (!load) {
|
||||||
log::warn("Unable to load settings: {}", load.unwrapErr());
|
log::warn("Unable to load settings: {}", load.unwrapErr());
|
||||||
|
@ -214,14 +209,8 @@ Result<> Mod::Impl::saveData() {
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data saving should be fully fail-safe
|
// ModSettingsManager keeps track of the whole savedata
|
||||||
// If some settings weren't provided a custom settings handler (for example,
|
matjson::Value json;
|
||||||
// the mod was not loaded) then make sure to save their previous state in
|
|
||||||
// order to not lose data
|
|
||||||
if (!m_savedSettingsData.is_object()) {
|
|
||||||
m_savedSettingsData = matjson::Object();
|
|
||||||
}
|
|
||||||
matjson::Value json = m_savedSettingsData;
|
|
||||||
m_settings->save(json);
|
m_settings->save(json);
|
||||||
|
|
||||||
// saveData is expected to be synchronous, and always called from GD thread
|
// saveData is expected to be synchronous, and always called from GD thread
|
||||||
|
|
|
@ -52,10 +52,6 @@ namespace geode {
|
||||||
* Setting values. This is behind unique_ptr for interior mutability
|
* Setting values. This is behind unique_ptr for interior mutability
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<ModSettingsManager> m_settings = nullptr;
|
std::unique_ptr<ModSettingsManager> m_settings = nullptr;
|
||||||
/**
|
|
||||||
* Settings save data. Stored for efficient loading of custom settings
|
|
||||||
*/
|
|
||||||
matjson::Value m_savedSettingsData = matjson::Object();
|
|
||||||
/**
|
/**
|
||||||
* Whether the mod resources are loaded or not
|
* Whether the mod resources are loaded or not
|
||||||
*/
|
*/
|
||||||
|
@ -101,7 +97,6 @@ namespace geode {
|
||||||
std::filesystem::path getBinaryPath() const;
|
std::filesystem::path getBinaryPath() const;
|
||||||
|
|
||||||
matjson::Value& getSaveContainer();
|
matjson::Value& getSaveContainer();
|
||||||
matjson::Value& getSavedSettingsData();
|
|
||||||
|
|
||||||
#if defined(GEODE_EXPOSE_SECRET_INTERNALS_IN_HEADERS_DO_NOT_DEFINE_PLEASE)
|
#if defined(GEODE_EXPOSE_SECRET_INTERNALS_IN_HEADERS_DO_NOT_DEFINE_PLEASE)
|
||||||
void setMetadata(ModMetadata const& metadata);
|
void setMetadata(ModMetadata const& metadata);
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
// Stored so custom settings registered after the fact can be loaded
|
// Stored so custom settings registered after the fact can be loaded
|
||||||
// If the ability to unregister custom settings is ever added, remember to
|
// If the ability to unregister custom settings is ever added, remember to
|
||||||
// update this by calling saveSettingValueToSave
|
// update this by calling saveSettingValueToSave
|
||||||
matjson::Object savedata;
|
matjson::Value savedata;
|
||||||
bool restartRequired = false;
|
bool restartRequired = false;
|
||||||
|
|
||||||
void loadSettingValueFromSave(std::string const& key) {
|
void loadSettingValueFromSave(std::string const& key) {
|
||||||
|
@ -232,13 +232,12 @@ void ModSettingsManager::save(matjson::Value& json) {
|
||||||
for (auto& [key, _] : m_impl->settings) {
|
for (auto& [key, _] : m_impl->settings) {
|
||||||
m_impl->saveSettingValueToSave(key);
|
m_impl->saveSettingValueToSave(key);
|
||||||
}
|
}
|
||||||
// Doing this indirection instead of just `json = m_impl->savedata` because
|
// Doing this since `ModSettingsManager` is expected to manage savedata fully
|
||||||
// we do NOT want to accidentally discard keys present in `json` but not in
|
json = m_impl->savedata;
|
||||||
// `m_impl->savedata`
|
|
||||||
for (auto& [key, value] : m_impl->savedata) {
|
|
||||||
json[key] = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// matjson::Value& ModSettingsManager::getSaveData() {
|
||||||
|
// return m_impl->savedata;
|
||||||
|
// }
|
||||||
|
|
||||||
std::shared_ptr<SettingV3> ModSettingsManager::get(std::string_view key) {
|
std::shared_ptr<SettingV3> ModSettingsManager::get(std::string_view key) {
|
||||||
auto id = std::string(key);
|
auto id = std::string(key);
|
||||||
|
@ -275,3 +274,9 @@ std::optional<Setting> ModSettingsManager::getLegacyDefinition(std::string_view
|
||||||
bool ModSettingsManager::restartRequired() const {
|
bool ModSettingsManager::restartRequired() const {
|
||||||
return m_impl->restartRequired;
|
return m_impl->restartRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo in 3.7.0: move Mod::getSavedSettingsData() back to Mod.cpp and make it
|
||||||
|
// use ModSettingsManager::getSaveData()
|
||||||
|
matjson::Value& Mod::getSavedSettingsData() {
|
||||||
|
return m_impl->m_settings->m_impl->savedata;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue