mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 16:30:05 +00:00
Settings container
This commit is contained in:
parent
08b1d6e152
commit
1ad67de71b
7 changed files with 251 additions and 14 deletions
|
|
@ -110,10 +110,12 @@ set(SRC_REQUEST source/scwx/qt/request/nexrad_file_request.cpp)
|
||||||
set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp
|
set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp
|
||||||
source/scwx/qt/settings/map_settings.hpp
|
source/scwx/qt/settings/map_settings.hpp
|
||||||
source/scwx/qt/settings/palette_settings.hpp
|
source/scwx/qt/settings/palette_settings.hpp
|
||||||
|
source/scwx/qt/settings/settings_container.hpp
|
||||||
source/scwx/qt/settings/settings_variable.hpp)
|
source/scwx/qt/settings/settings_variable.hpp)
|
||||||
set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp
|
set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp
|
||||||
source/scwx/qt/settings/map_settings.cpp
|
source/scwx/qt/settings/map_settings.cpp
|
||||||
source/scwx/qt/settings/palette_settings.cpp
|
source/scwx/qt/settings/palette_settings.cpp
|
||||||
|
source/scwx/qt/settings/settings_container.cpp
|
||||||
source/scwx/qt/settings/settings_variable.cpp)
|
source/scwx/qt/settings/settings_variable.cpp)
|
||||||
set(HDR_TYPES source/scwx/qt/types/qt_types.hpp
|
set(HDR_TYPES source/scwx/qt/types/qt_types.hpp
|
||||||
source/scwx/qt/types/radar_product_record.hpp
|
source/scwx/qt/types/radar_product_record.hpp
|
||||||
|
|
|
||||||
148
scwx-qt/source/scwx/qt/settings/settings_container.cpp
Normal file
148
scwx-qt/source/scwx/qt/settings/settings_container.cpp
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
#define SETTINGS_CONTAINER_IMPLEMENTATION
|
||||||
|
|
||||||
|
#include <scwx/qt/settings/settings_container.hpp>
|
||||||
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
|
namespace scwx
|
||||||
|
{
|
||||||
|
namespace qt
|
||||||
|
{
|
||||||
|
namespace settings
|
||||||
|
{
|
||||||
|
|
||||||
|
static const std::string logPrefix_ = "scwx::qt::settings::settings_container";
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
class SettingsContainer<Container>::Impl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Impl() {}
|
||||||
|
|
||||||
|
~Impl() {}
|
||||||
|
|
||||||
|
T elementDefault_ {};
|
||||||
|
std::optional<T> elementMinimum_ {};
|
||||||
|
std::optional<T> elementMaximum_ {};
|
||||||
|
std::function<bool(const T&)> elementValidator_ {nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
SettingsContainer<Container>::SettingsContainer(const std::string& name) :
|
||||||
|
SettingsVariable<Container>(name), p(std::make_unique<Impl>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
template<class Container>
|
||||||
|
SettingsContainer<Container>::~SettingsContainer() = default;
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
SettingsContainer<Container>::SettingsContainer(SettingsContainer&&) noexcept =
|
||||||
|
default;
|
||||||
|
template<class Container>
|
||||||
|
SettingsContainer<Container>&
|
||||||
|
SettingsContainer<Container>::operator=(SettingsContainer&&) noexcept = default;
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
bool SettingsContainer<Container>::SetValueOrDefault(const Container& c)
|
||||||
|
{
|
||||||
|
bool validated = true;
|
||||||
|
|
||||||
|
Container validatedValues;
|
||||||
|
validatedValues.reserve(c.size());
|
||||||
|
|
||||||
|
std::transform(
|
||||||
|
c.cbegin(),
|
||||||
|
c.cend(),
|
||||||
|
std::back_inserter(validatedValues),
|
||||||
|
[&](auto& value)
|
||||||
|
{
|
||||||
|
if (ValidateElement(value))
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else if (p->elementMinimum_.has_value() && value < p->elementMinimum_)
|
||||||
|
{
|
||||||
|
validated = false;
|
||||||
|
return *p->elementMinimum_;
|
||||||
|
}
|
||||||
|
else if (p->elementMaximum_.has_value() && value > p->elementMaximum_)
|
||||||
|
{
|
||||||
|
validated = false;
|
||||||
|
return *p->elementMaximum_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
validated = false;
|
||||||
|
return p->elementDefault_;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return SettingsVariable<Container>::SetValueOrDefault(validatedValues) &&
|
||||||
|
validated;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
SettingsContainer<Container>::T
|
||||||
|
SettingsContainer<Container>::GetElementDefault() const
|
||||||
|
{
|
||||||
|
return p->elementDefault_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
void SettingsContainer<Container>::SetElementDefault(const T& value)
|
||||||
|
{
|
||||||
|
p->elementDefault_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
void SettingsContainer<Container>::SetElementMinimum(const T& value)
|
||||||
|
{
|
||||||
|
p->elementMinimum_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
void SettingsContainer<Container>::SetElementMaximum(const T& value)
|
||||||
|
{
|
||||||
|
p->elementMaximum_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
void SettingsContainer<Container>::SetElementValidator(
|
||||||
|
std::function<bool(const T&)> validator)
|
||||||
|
{
|
||||||
|
p->elementValidator_ = validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
bool SettingsContainer<Container>::Validate(const Container& c) const
|
||||||
|
{
|
||||||
|
if (!SettingsVariable<Container>::Validate(c))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& element : c)
|
||||||
|
{
|
||||||
|
if (!ValidateElement(element))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
bool SettingsContainer<Container>::ValidateElement(const T& value) const
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
// Validate minimum
|
||||||
|
(!p->elementMinimum_.has_value() || value >= p->elementMinimum_) &&
|
||||||
|
// Validate maximum
|
||||||
|
(!p->elementMaximum_.has_value() || value <= p->elementMaximum_) &&
|
||||||
|
// User-validation
|
||||||
|
(p->elementValidator_ == nullptr || p->elementValidator_(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace settings
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace scwx
|
||||||
50
scwx-qt/source/scwx/qt/settings/settings_container.hpp
Normal file
50
scwx-qt/source/scwx/qt/settings/settings_container.hpp
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <scwx/qt/settings/settings_variable.hpp>
|
||||||
|
|
||||||
|
namespace scwx
|
||||||
|
{
|
||||||
|
namespace qt
|
||||||
|
{
|
||||||
|
namespace settings
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
class SettingsContainer : public SettingsVariable<Container>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using T = Container::value_type;
|
||||||
|
|
||||||
|
explicit SettingsContainer(const std::string& name);
|
||||||
|
~SettingsContainer();
|
||||||
|
|
||||||
|
SettingsContainer(const SettingsContainer&) = delete;
|
||||||
|
SettingsContainer& operator=(const SettingsContainer&) = delete;
|
||||||
|
|
||||||
|
SettingsContainer(SettingsContainer&&) noexcept;
|
||||||
|
SettingsContainer& operator=(SettingsContainer&&) noexcept;
|
||||||
|
|
||||||
|
bool SetValueOrDefault(const Container& c) override;
|
||||||
|
|
||||||
|
bool Validate(const Container& c) const override;
|
||||||
|
bool ValidateElement(const T& value) const;
|
||||||
|
|
||||||
|
T GetElementDefault() const;
|
||||||
|
|
||||||
|
void SetElementDefault(const T& value);
|
||||||
|
void SetElementMinimum(const T& value);
|
||||||
|
void SetElementMaximum(const T& value);
|
||||||
|
void SetElementValidator(std::function<bool(const T&)> validator);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> p;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef SETTINGS_CONTAINER_IMPLEMENTATION
|
||||||
|
template class SettingsContainer<std::vector<int64_t>>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace settings
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace scwx
|
||||||
|
|
@ -20,8 +20,6 @@ public:
|
||||||
|
|
||||||
~Impl() {}
|
~Impl() {}
|
||||||
|
|
||||||
bool Validate(const T& value);
|
|
||||||
|
|
||||||
const std::string name_;
|
const std::string name_;
|
||||||
T value_ {};
|
T value_ {};
|
||||||
T default_ {};
|
T default_ {};
|
||||||
|
|
@ -62,7 +60,7 @@ bool SettingsVariable<T>::SetValue(const T& value)
|
||||||
{
|
{
|
||||||
bool validated = false;
|
bool validated = false;
|
||||||
|
|
||||||
if (p->Validate(value))
|
if (Validate(value))
|
||||||
{
|
{
|
||||||
p->value_ = value;
|
p->value_ = value;
|
||||||
validated = true;
|
validated = true;
|
||||||
|
|
@ -76,7 +74,7 @@ bool SettingsVariable<T>::SetValueOrDefault(const T& value)
|
||||||
{
|
{
|
||||||
bool validated = false;
|
bool validated = false;
|
||||||
|
|
||||||
if (p->Validate(value))
|
if (Validate(value))
|
||||||
{
|
{
|
||||||
p->value_ = value;
|
p->value_ = value;
|
||||||
validated = true;
|
validated = true;
|
||||||
|
|
@ -108,7 +106,7 @@ bool SettingsVariable<T>::StageValue(const T& value)
|
||||||
{
|
{
|
||||||
bool validated = false;
|
bool validated = false;
|
||||||
|
|
||||||
if (p->Validate(value))
|
if (Validate(value))
|
||||||
{
|
{
|
||||||
p->staged_ = value;
|
p->staged_ = value;
|
||||||
validated = true;
|
validated = true;
|
||||||
|
|
@ -158,11 +156,12 @@ void SettingsVariable<T>::SetValidator(std::function<bool(const T&)> validator)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
bool SettingsVariable<T>::Impl::Validate(const T& value)
|
bool SettingsVariable<T>::Validate(const T& value) const
|
||||||
{
|
{
|
||||||
return ((!minimum_.has_value() || value >= minimum_) && // Validate minimum
|
return (
|
||||||
(!maximum_.has_value() || value <= maximum_) && // Validate maximum
|
(!p->minimum_.has_value() || value >= p->minimum_) && // Validate minimum
|
||||||
(validator_ == nullptr || validator_(value))); // User-validation
|
(!p->maximum_.has_value() || value <= p->maximum_) && // Validate maximum
|
||||||
|
(p->validator_ == nullptr || p->validator_(value))); // User-validation
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace settings
|
} // namespace settings
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,14 @@ public:
|
||||||
|
|
||||||
T GetValue() const;
|
T GetValue() const;
|
||||||
bool SetValue(const T& value);
|
bool SetValue(const T& value);
|
||||||
bool SetValueOrDefault(const T& value);
|
virtual bool SetValueOrDefault(const T& value);
|
||||||
void SetValueToDefault();
|
void SetValueToDefault();
|
||||||
|
|
||||||
bool StageValue(const T& value);
|
bool StageValue(const T& value);
|
||||||
void Commit();
|
void Commit();
|
||||||
|
|
||||||
|
virtual bool Validate(const T& value) const;
|
||||||
|
|
||||||
T GetDefault() const;
|
T GetDefault() const;
|
||||||
|
|
||||||
void SetDefault(const T& value);
|
void SetDefault(const T& value);
|
||||||
|
|
@ -50,6 +52,9 @@ private:
|
||||||
template class SettingsVariable<bool>;
|
template class SettingsVariable<bool>;
|
||||||
template class SettingsVariable<int64_t>;
|
template class SettingsVariable<int64_t>;
|
||||||
template class SettingsVariable<std::string>;
|
template class SettingsVariable<std::string>;
|
||||||
|
|
||||||
|
// Containers are not to be used directly
|
||||||
|
template class SettingsVariable<std::vector<int64_t>>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace settings
|
} // namespace settings
|
||||||
|
|
|
||||||
32
test/source/scwx/qt/settings/settings_container.test.cpp
Normal file
32
test/source/scwx/qt/settings/settings_container.test.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include <scwx/qt/settings/settings_container.hpp>
|
||||||
|
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace scwx
|
||||||
|
{
|
||||||
|
namespace qt
|
||||||
|
{
|
||||||
|
namespace settings
|
||||||
|
{
|
||||||
|
|
||||||
|
TEST(SettingsContainerTest, Integer)
|
||||||
|
{
|
||||||
|
SettingsContainer<std::vector<int64_t>> intContainer {
|
||||||
|
"std::vector<int64_t>"};
|
||||||
|
intContainer.SetDefault({42, 5, 63});
|
||||||
|
intContainer.SetElementMinimum(4);
|
||||||
|
intContainer.SetElementMaximum(70);
|
||||||
|
intContainer.SetValueToDefault();
|
||||||
|
|
||||||
|
EXPECT_EQ(intContainer.name(), "std::vector<int64_t>");
|
||||||
|
EXPECT_THAT(intContainer.GetValue(), ::testing::ElementsAre(42, 5, 63));
|
||||||
|
EXPECT_EQ(intContainer.SetValueOrDefault({50, 0, 80}), false);
|
||||||
|
EXPECT_THAT(intContainer.GetValue(), ::testing::ElementsAre(50, 4, 70));
|
||||||
|
EXPECT_EQ(intContainer.SetValueOrDefault({10, 20, 30}), true);
|
||||||
|
EXPECT_THAT(intContainer.GetValue(), ::testing::ElementsAre(10, 20, 30));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace settings
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace scwx
|
||||||
|
|
@ -23,7 +23,8 @@ set(SRC_QT_CONFIG_TESTS source/scwx/qt/config/county_database.test.cpp
|
||||||
source/scwx/qt/config/radar_site.test.cpp)
|
source/scwx/qt/config/radar_site.test.cpp)
|
||||||
set(SRC_QT_MANAGER_TESTS source/scwx/qt/manager/settings_manager.test.cpp)
|
set(SRC_QT_MANAGER_TESTS source/scwx/qt/manager/settings_manager.test.cpp)
|
||||||
set(SRC_QT_MODEL_TESTS source/scwx/qt/model/imgui_context_model.test.cpp)
|
set(SRC_QT_MODEL_TESTS source/scwx/qt/model/imgui_context_model.test.cpp)
|
||||||
set(SRC_QT_SETTINGS_TESTS source/scwx/qt/settings/settings_variable.test.cpp)
|
set(SRC_QT_SETTINGS_TESTS source/scwx/qt/settings/settings_container.test.cpp
|
||||||
|
source/scwx/qt/settings/settings_variable.test.cpp)
|
||||||
set(SRC_UTIL_TESTS source/scwx/util/float.test.cpp
|
set(SRC_UTIL_TESTS source/scwx/util/float.test.cpp
|
||||||
source/scwx/util/rangebuf.test.cpp
|
source/scwx/util/rangebuf.test.cpp
|
||||||
source/scwx/util/streams.test.cpp
|
source/scwx/util/streams.test.cpp
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue