[App] Implement loading MultiChoiceSettingsItem from embedded xml

This commit is contained in:
Satori 2021-08-25 13:28:25 +01:00
parent b2aa9c83b0
commit 8182a10919
3 changed files with 78 additions and 66 deletions

View File

@ -203,7 +203,7 @@ class IMultiChoiceSettingsItem : public ISettingsItem {
: ISettingsItem(SettingsType::MultiChoice, title, description) {}
virtual bool UpdateIndex(int index) = 0;
virtual const std::vector<std::string>& option_names() const = 0;
virtual std::vector<std::string> option_names() const = 0;
};
template <typename T>
@ -241,6 +241,14 @@ class MultiChoiceSettingsItem : public IMultiChoiceSettingsItem {
return false;
}
std::vector<std::string> option_names() const override {
std::vector<std::string> names;
std::transform(options_.begin(), options_.end(),
std::back_inserter(names),
[](const Option& opt) { return opt.title; });
return names;
}
private:
ConfigVar<T>* cvar_;
std::vector<Option> options_;

View File

@ -27,62 +27,6 @@ static std::string_view valid_node_types[] = {
static std::string_view valid_multi_choice_types[] = {
"int", "int32", "int64", "uint", "uint32", "uint64", "double", "string"};
template <>
SettingsLoader::Option<int32_t> SettingsLoader::LoadMultiChoiceOption<int32_t>(
const pugi::xml_node& node) {
std::string title = node.child("title").text().as_string();
int32_t value = node.child("value").text().as_int();
return Option<int32_t>{title, value};
}
template <>
SettingsLoader::Option<int64_t> SettingsLoader::LoadMultiChoiceOption<int64_t>(
const pugi::xml_node& node) {
std::string title = node.child("title").text().as_string();
int64_t value = node.child("value").text().as_llong();
return Option<int64_t>{title, value};
}
template <>
SettingsLoader::Option<uint32_t>
SettingsLoader::LoadMultiChoiceOption<uint32_t>(const pugi::xml_node& node) {
std::string title = node.child("title").text().as_string();
uint32_t value = node.child("value").text().as_uint();
return Option<uint32_t>{title, value};
}
template <>
SettingsLoader::Option<uint64_t>
SettingsLoader::LoadMultiChoiceOption<uint64_t>(const pugi::xml_node& node) {
std::string title = node.child("title").text().as_string();
uint64_t value = node.child("value").text().as_ullong();
return Option<uint64_t>{title, value};
}
template <>
SettingsLoader::Option<double> SettingsLoader::LoadMultiChoiceOption<double>(
const pugi::xml_node& node) {
std::string title = node.child("title").text().as_string();
double value = node.child("value").text().as_double();
return Option<double>{title, value};
}
template <>
SettingsLoader::Option<std::string>
SettingsLoader::LoadMultiChoiceOption<std::string>(const pugi::xml_node& node) {
std::string title = node.child("title").text().as_string();
std::string value = node.child("value").text().as_string();
return Option<std::string>{title, value};
}
void SettingsLoader::AddSetting(std::unique_ptr<ISettingsItem>&& item,
const std::string& group,
const std::string& set) {
auto& settings_set = settings_.FindOrCreateSettingsSet(set);
auto& settings_group = settings_set.FindOrCreateSettingsGroup(group);
settings_group.AddItem(std::move(item));
}
bool SettingsLoader::LoadSettingsFromEmbeddedXml() {
constexpr size_t size = sizeof(xe::embedded::settings_data);
std::array<uint8_t, size> settings_buf;
@ -174,16 +118,23 @@ std::unique_ptr<ISettingsItem> SettingsLoader::LoadSettingsItemFromXmlNode(
std::string_view multi_choice_type = *node_found;
if (multi_choice_type == "int" || multi_choice_type == "int32") {
std::vector<Option<int32_t>> values;
for (const auto& option_node : node.child("options").children()) {
values.push_back(LoadMultiChoiceOption<int32_t>(option_node));
}
return LoadMultiChoiceSetting<int32_t>(title, description, cvar, node);
}
if (multi_choice_type == "int64") {
std::vector<Option<int64_t>> values;
for (const auto& option_node : node.child("options").children()) {
values.push_back(LoadMultiChoiceOption<int64_t>(option_node));
}
return LoadMultiChoiceSetting<int64_t>(title, description, cvar, node);
}
if (multi_choice_type == "uint" || multi_choice_type == "uint64") {
return LoadMultiChoiceSetting<uint32_t>(title, description, cvar, node);
}
if (multi_choice_type == "uint64") {
return LoadMultiChoiceSetting<uint64_t>(title, description, cvar, node);
}
if (multi_choice_type == "double") {
return LoadMultiChoiceSetting<double>(title, description, cvar, node);
}
if (multi_choice_type == "string") {
return LoadMultiChoiceSetting<std::string>(title, description, cvar,
node);
}
}
} else {
@ -193,6 +144,14 @@ std::unique_ptr<ISettingsItem> SettingsLoader::LoadSettingsItemFromXmlNode(
return nullptr;
}
void SettingsLoader::AddSetting(std::unique_ptr<ISettingsItem>&& item,
const std::string& group,
const std::string& set) {
settings_.FindOrCreateSettingsSet(set)
.FindOrCreateSettingsGroup(group)
.AddItem(std::move(item));
}
void SettingsLoader::AddBooleanInputSetting(std::string title,
std::string description,
cvar::ConfigVar<bool>* cvar,

View File

@ -87,7 +87,12 @@ class SettingsLoader {
const pugi::xml_node& node);
template <typename T>
Option<T> LoadMultiChoiceOption(const pugi::xml_node& option_node);
std::unique_ptr<MultiChoiceSettingsItem<T>> LoadMultiChoiceSetting(
const std::string& title, const std::string& description,
IConfigVar* cvar, const pugi::xml_node& node);
template <typename T>
std::vector<Option<T>> LoadMultiChoiceOptions(const pugi::xml_node& node);
Settings& settings_;
};
@ -118,6 +123,46 @@ void SettingsLoader::AddMultiChoiceInputSetting(
}
}
template <typename T>
std::unique_ptr<MultiChoiceSettingsItem<T>>
SettingsLoader::LoadMultiChoiceSetting(const std::string& title,
const std::string& description,
IConfigVar* cvar,
const pugi::xml_node& node) {
std::vector<Option<T>> options =
SettingsLoader::LoadMultiChoiceOptions<T>(node);
return std::make_unique<MultiChoiceSettingsItem<T>>(
title, description, options, dynamic_cast<ConfigVar<T>*>(cvar));
}
template <typename T>
std::vector<SettingsLoader::Option<T>> SettingsLoader::LoadMultiChoiceOptions(
const pugi::xml_node& node) {
std::vector<SettingsLoader::Option<T>> vector;
for (const auto& option_node : node.child("options").children()) {
std::string title = option_node.child("title").text().as_string();
T value;
if constexpr (std::is_same_v<T, int32_t>) {
value = option_node.child("value").text().as_int();
} else if constexpr (std::is_same_v<T, uint32_t>) {
value = option_node.child("value").text().as_uint();
} else if constexpr (std::is_same_v<T, int64_t>) {
value = option_node.child("value").text().as_llong();
} else if constexpr (std::is_same_v<T, uint64_t>) {
value = option_node.child("value").text().as_ullong();
} else if constexpr (std::is_same_v<T, double>) {
value = option_node.child("value").text().as_double();
} else if constexpr (std::is_same_v<T, std::string>) {
value = option_node.child("value").text().as_string();
} else {
static_assert(false, "Type for multi choice option not valid")
}
vector.push_back(Option<T>{title, value});
}
return vector;
}
} // namespace settings
} // namespace app
} // namespace xe