Inheriting GeneralSettings from SettingsCategory, making generic read/write JSON functions

This commit is contained in:
Dan Paulat 2022-12-17 23:05:00 -06:00
parent 78739cd627
commit c93e776137
7 changed files with 184 additions and 96 deletions

View file

@ -110,12 +110,14 @@ set(SRC_REQUEST source/scwx/qt/request/nexrad_file_request.cpp)
set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp
source/scwx/qt/settings/map_settings.hpp
source/scwx/qt/settings/palette_settings.hpp
source/scwx/qt/settings/settings_category.hpp
source/scwx/qt/settings/settings_container.hpp
source/scwx/qt/settings/settings_variable.hpp
source/scwx/qt/settings/settings_variable_base.hpp)
set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp
source/scwx/qt/settings/map_settings.cpp
source/scwx/qt/settings/palette_settings.cpp
source/scwx/qt/settings/settings_category.cpp
source/scwx/qt/settings/settings_container.cpp
source/scwx/qt/settings/settings_variable.cpp
source/scwx/qt/settings/settings_variable_base.cpp)

View file

@ -98,7 +98,7 @@ static boost::json::value ConvertSettingsToJson()
{
boost::json::object settingsJson;
settingsJson[kGeneralKey] = generalSettings_->ToJson();
generalSettings_->WriteJson(settingsJson);
settingsJson[kMapKey] = mapSettings_->ToJson();
settingsJson[kPaletteKey] = paletteSettings_->ToJson();
@ -109,7 +109,7 @@ static void GenerateDefaultSettings()
{
logger_->info("Generating default settings");
generalSettings_ = settings::GeneralSettings::Create();
generalSettings_ = std::make_shared<settings::GeneralSettings>();
mapSettings_ = settings::MapSettings::Create();
paletteSettings_ = settings::PaletteSettings::Create();
}
@ -120,8 +120,9 @@ static bool LoadSettings(const boost::json::object& settingsJson)
bool jsonDirty = false;
generalSettings_ = settings::GeneralSettings::Load(
settingsJson.if_contains(kGeneralKey), jsonDirty);
generalSettings_ = std::make_shared<settings::GeneralSettings>();
jsonDirty |= !generalSettings_->ReadJson(settingsJson);
mapSettings_ =
settings::MapSettings::Load(settingsJson.if_contains(kMapKey), jsonDirty);
paletteSettings_ = settings::PaletteSettings::Load(

View file

@ -36,42 +36,28 @@ public:
gridHeight_.SetMaximum(2);
mapboxApiKey_.SetValidator([](const std::string& value)
{ return !value.empty(); });
RegisterVariables({&debugEnabled_,
&defaultRadarSite_,
&fontSizes_,
&gridWidth_,
&gridHeight_,
&mapboxApiKey_});
SetDefaults();
}
~GeneralSettingsImpl() {}
void SetDefaults()
{
for (auto& variable : variables_)
{
variable->SetValueToDefault();
}
}
SettingsVariable<bool> debugEnabled_ {"debug_enabled"};
SettingsVariable<std::string> defaultRadarSite_ {"default_radar_site"};
SettingsContainer<std::vector<std::int64_t>> fontSizes_ {"font_sizes"};
SettingsVariable<std::int64_t> gridWidth_ {"grid_width"};
SettingsVariable<std::int64_t> gridHeight_ {"grid_height"};
SettingsVariable<std::string> mapboxApiKey_ {"mapbox_api_key"};
std::vector<SettingsVariableBase*> variables_;
void
RegisterVariables(std::initializer_list<SettingsVariableBase*> variables);
};
GeneralSettings::GeneralSettings() : p(std::make_unique<GeneralSettingsImpl>())
GeneralSettings::GeneralSettings() :
SettingsCategory("general"), p(std::make_unique<GeneralSettingsImpl>())
{
RegisterVariables({&p->debugEnabled_,
&p->defaultRadarSite_,
&p->fontSizes_,
&p->gridWidth_,
&p->gridHeight_,
&p->mapboxApiKey_});
SetDefaults();
}
GeneralSettings::~GeneralSettings() = default;
@ -79,12 +65,6 @@ GeneralSettings::GeneralSettings(GeneralSettings&&) noexcept = default;
GeneralSettings&
GeneralSettings::operator=(GeneralSettings&&) noexcept = default;
void GeneralSettingsImpl::RegisterVariables(
std::initializer_list<SettingsVariableBase*> variables)
{
variables_.insert(variables_.end(), variables);
}
bool GeneralSettings::debug_enabled() const
{
return p->debugEnabled_.GetValue();
@ -115,57 +95,6 @@ std::string GeneralSettings::mapbox_api_key() const
return p->mapboxApiKey_.GetValue();
}
boost::json::value GeneralSettings::ToJson() const
{
boost::json::object json;
for (auto& variable : p->variables_)
{
variable->WriteValue(json);
}
return json;
}
std::shared_ptr<GeneralSettings> GeneralSettings::Create()
{
std::shared_ptr<GeneralSettings> generalSettings =
std::make_shared<GeneralSettings>();
return generalSettings;
}
std::shared_ptr<GeneralSettings>
GeneralSettings::Load(const boost::json::value* json, bool& jsonDirty)
{
std::shared_ptr<GeneralSettings> generalSettings =
std::make_shared<GeneralSettings>();
if (json != nullptr && json->is_object())
{
for (auto& variable : generalSettings->p->variables_)
{
jsonDirty |= !variable->ReadValue(json->as_object());
}
}
else
{
if (json == nullptr)
{
logger_->warn("Key is not present, resetting to defaults");
}
else if (!json->is_object())
{
logger_->warn("Invalid json, resetting to defaults");
}
generalSettings->p->SetDefaults();
jsonDirty = true;
}
return generalSettings;
}
bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs)
{
return (lhs.p->debugEnabled_ == rhs.p->debugEnabled_ &&

View file

@ -1,10 +1,10 @@
#pragma once
#include <scwx/qt/settings/settings_category.hpp>
#include <memory>
#include <string>
#include <boost/json.hpp>
namespace scwx
{
namespace qt
@ -14,7 +14,7 @@ namespace settings
class GeneralSettingsImpl;
class GeneralSettings
class GeneralSettings : public SettingsCategory
{
public:
explicit GeneralSettings();
@ -29,16 +29,10 @@ public:
bool debug_enabled() const;
std::string default_radar_site() const;
std::vector<int64_t> font_sizes() const;
int64_t grid_height() const;
int64_t grid_width() const;
std::int64_t grid_height() const;
std::int64_t grid_width() const;
std::string mapbox_api_key() const;
boost::json::value ToJson() const;
static std::shared_ptr<GeneralSettings> Create();
static std::shared_ptr<GeneralSettings> Load(const boost::json::value* json,
bool& jsonDirty);
friend bool operator==(const GeneralSettings& lhs,
const GeneralSettings& rhs);

View file

@ -0,0 +1,100 @@
#include <scwx/qt/settings/settings_category.hpp>
#include <scwx/qt/util/json.hpp>
#include <scwx/util/logger.hpp>
namespace scwx
{
namespace qt
{
namespace settings
{
static const std::string logPrefix_ = "scwx::qt::settings::settings_category";
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
class SettingsCategory::Impl
{
public:
explicit Impl(const std::string& name) : name_ {name} {}
~Impl() {}
const std::string name_;
std::vector<SettingsVariableBase*> variables_;
};
SettingsCategory::SettingsCategory(const std::string& name) :
p(std::make_unique<Impl>(name))
{
}
SettingsCategory::~SettingsCategory() = default;
SettingsCategory::SettingsCategory(SettingsCategory&&) noexcept = default;
SettingsCategory&
SettingsCategory::operator=(SettingsCategory&&) noexcept = default;
void SettingsCategory::SetDefaults()
{
for (auto& variable : p->variables_)
{
variable->SetValueToDefault();
}
}
bool SettingsCategory::ReadJson(const boost::json::object& json)
{
bool validated = true;
const boost::json::value* value = json.if_contains(p->name_);
if (value != nullptr && value->is_object())
{
const boost::json::object& object = value->as_object();
for (auto& variable : p->variables_)
{
validated &= variable->ReadValue(object);
}
}
else
{
if (value == nullptr)
{
logger_->warn("Key {} is not present, resetting to defaults",
p->name_);
}
else if (!value->is_object())
{
logger_->warn("Invalid json for key {}, resetting to defaults",
p->name_);
}
SetDefaults();
validated = false;
}
return validated;
}
void SettingsCategory::WriteJson(boost::json::object& json) const
{
boost::json::object object;
for (auto& variable : p->variables_)
{
variable->WriteValue(object);
}
json.insert_or_assign(p->name_, object);
}
void SettingsCategory::RegisterVariables(
std::initializer_list<SettingsVariableBase*> variables)
{
p->variables_.insert(p->variables_.end(), variables);
}
} // namespace settings
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,62 @@
#pragma once
#include <scwx/qt/settings/settings_variable_base.hpp>
#include <memory>
#include <string>
#include <boost/json/object.hpp>
namespace scwx
{
namespace qt
{
namespace settings
{
class SettingsCategory
{
public:
explicit SettingsCategory(const std::string& name);
~SettingsCategory();
SettingsCategory(const SettingsCategory&) = delete;
SettingsCategory& operator=(const SettingsCategory&) = delete;
SettingsCategory(SettingsCategory&&) noexcept;
SettingsCategory& operator=(SettingsCategory&&) noexcept;
/**
* Set all variables to their defaults.
*/
virtual void SetDefaults();
/**
* Reads the variables from the JSON object.
*
* @param json JSON object to read
*
* @return true if the values read are valid, false if any values were
* modified.
*/
virtual bool ReadJson(const boost::json::object& json);
/**
* Writes the variables to the JSON object.
*
* @param json JSON object to write
*/
virtual void WriteJson(boost::json::object& json) const;
protected:
void
RegisterVariables(std::initializer_list<SettingsVariableBase*> variables);
private:
class Impl;
std::unique_ptr<Impl> p;
};
} // namespace settings
} // namespace qt
} // namespace scwx