mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:20:06 +00:00
Settings variable abstract base, additional validation, and reading/writing JSON
This commit is contained in:
parent
1ad67de71b
commit
46c4dd3780
7 changed files with 408 additions and 17 deletions
|
|
@ -3,6 +3,11 @@
|
|||
#include <scwx/qt/settings/settings_variable.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <boost/json.hpp>
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
|
|
@ -11,16 +16,16 @@ namespace settings
|
|||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::settings::settings_variable";
|
||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||
|
||||
template<class T>
|
||||
class SettingsVariable<T>::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl(const std::string& name) : name_ {name} {}
|
||||
explicit Impl() {}
|
||||
|
||||
~Impl() {}
|
||||
|
||||
const std::string name_;
|
||||
T value_ {};
|
||||
T default_ {};
|
||||
std::optional<T> staged_ {};
|
||||
|
|
@ -31,7 +36,7 @@ public:
|
|||
|
||||
template<class T>
|
||||
SettingsVariable<T>::SettingsVariable(const std::string& name) :
|
||||
p(std::make_unique<Impl>(name))
|
||||
SettingsVariableBase(name), p(std::make_unique<Impl>())
|
||||
{
|
||||
}
|
||||
template<class T>
|
||||
|
|
@ -44,9 +49,16 @@ SettingsVariable<T>&
|
|||
SettingsVariable<T>::operator=(SettingsVariable&&) noexcept = default;
|
||||
|
||||
template<class T>
|
||||
std::string SettingsVariable<T>::name() const
|
||||
inline auto FormatParameter(const T& value)
|
||||
{
|
||||
return p->name_;
|
||||
if constexpr (std::is_integral_v<T> || std::is_same_v<T, std::string>)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fmt::join(value, ", ");
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
|
@ -81,14 +93,26 @@ bool SettingsVariable<T>::SetValueOrDefault(const T& value)
|
|||
}
|
||||
else if (p->minimum_.has_value() && value < p->minimum_)
|
||||
{
|
||||
logger_->warn("{0} less than minimum ({1} < {2}), setting to: {2}",
|
||||
name(),
|
||||
FormatParameter<T>(value),
|
||||
FormatParameter<T>(*p->minimum_));
|
||||
p->value_ = *p->minimum_;
|
||||
}
|
||||
else if (p->maximum_.has_value() && value > p->maximum_)
|
||||
{
|
||||
logger_->warn("{0} greater than maximum ({1} > {2}), setting to: {2}",
|
||||
name(),
|
||||
FormatParameter<T>(value),
|
||||
FormatParameter<T>(*p->maximum_));
|
||||
p->value_ = *p->maximum_;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->warn("{} validation failed ({}), setting to default: {}",
|
||||
name(),
|
||||
FormatParameter<T>(value),
|
||||
FormatParameter<T>(p->default_));
|
||||
p->value_ = p->default_;
|
||||
}
|
||||
|
||||
|
|
@ -164,6 +188,59 @@ bool SettingsVariable<T>::Validate(const T& value) const
|
|||
(p->validator_ == nullptr || p->validator_(value))); // User-validation
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool SettingsVariable<T>::ReadValue(const boost::json::object& json)
|
||||
{
|
||||
const boost::json::value* jv = json.if_contains(name());
|
||||
bool validated = false;
|
||||
|
||||
if (jv != nullptr)
|
||||
{
|
||||
try
|
||||
{
|
||||
validated = SetValueOrDefault(boost::json::value_to<T>(*jv));
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
logger_->warn("{} is invalid ({}), setting to default: {}",
|
||||
name(),
|
||||
ex.what(),
|
||||
FormatParameter<T>(p->default_));
|
||||
p->value_ = p->default_;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->debug("{} is not present, setting to default: {}",
|
||||
name(),
|
||||
FormatParameter<T>(p->default_));
|
||||
p->value_ = p->default_;
|
||||
}
|
||||
|
||||
return validated;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void SettingsVariable<T>::WriteValue(boost::json::object& json) const
|
||||
{
|
||||
json[name()] = boost::json::value_from<T&>(p->value_);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool SettingsVariable<T>::Equals(const SettingsVariableBase& o) const
|
||||
{
|
||||
// This is only ever called with SettingsVariable<T>, so static_cast is safe
|
||||
const SettingsVariable<T>& v = static_cast<const SettingsVariable<T>&>(o);
|
||||
|
||||
// Don't compare validator
|
||||
return SettingsVariableBase::Equals(o) && //
|
||||
p->value_ == v.p->value_ && //
|
||||
p->default_ == v.p->default_ && //
|
||||
p->staged_ == v.p->staged_ && //
|
||||
p->minimum_ == v.p->minimum_ && //
|
||||
p->maximum_ == v.p->maximum_;
|
||||
}
|
||||
|
||||
} // namespace settings
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue