mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-12 04:49:00 +08:00
Refactoring: make Slic3r::Config a thin wrapper around Slic3r::DynamicPrintConfig by moving its accessors to Slic3r::ConfigBase
This commit is contained in:
parent
21eb603cc1
commit
79d0677db2
@ -14,16 +14,22 @@ SCENARIO("Generic config validation performs as expected.") {
|
||||
WHEN( "perimeter_extrusion_width is set to 250%, a valid value") {
|
||||
config->set("perimeter_extrusion_width", "250%");
|
||||
THEN( "The config is read as valid.") {
|
||||
REQUIRE(config->validate() == true);
|
||||
auto except_thrown {false};
|
||||
try {
|
||||
config->validate();
|
||||
} catch (const InvalidOptionException& e) {
|
||||
except_thrown = true;
|
||||
}
|
||||
REQUIRE(except_thrown == false);
|
||||
}
|
||||
}
|
||||
WHEN( "perimeter_extrusion_width is set to -10, an invalid value") {
|
||||
config->set("perimeter_extrusion_width", -10);
|
||||
THEN( "An InvalidOptionValue exception is thrown.") {
|
||||
THEN( "An InvalidOptionException exception is thrown.") {
|
||||
auto except_thrown {false};
|
||||
try {
|
||||
config->validate();
|
||||
} catch (const InvalidOptionValue& e) {
|
||||
} catch (const InvalidOptionException& e) {
|
||||
except_thrown = true;
|
||||
}
|
||||
REQUIRE(except_thrown == true);
|
||||
@ -32,11 +38,11 @@ SCENARIO("Generic config validation performs as expected.") {
|
||||
|
||||
WHEN( "perimeters is set to -10, an invalid value") {
|
||||
config->set("perimeters", -10);
|
||||
THEN( "An InvalidOptionValue exception is thrown.") {
|
||||
THEN( "An InvalidOptionException exception is thrown.") {
|
||||
auto except_thrown {false};
|
||||
try {
|
||||
config->validate();
|
||||
} catch (const InvalidOptionValue& e) {
|
||||
} catch (const InvalidOptionException& e) {
|
||||
except_thrown = true;
|
||||
}
|
||||
REQUIRE(except_thrown == true);
|
||||
@ -48,25 +54,23 @@ SCENARIO("Generic config validation performs as expected.") {
|
||||
SCENARIO("Config accessor functions perform as expected.") {
|
||||
GIVEN("A config generated from default options") {
|
||||
auto config {Slic3r::Config::new_from_defaults()};
|
||||
WHEN("A boolean option is set through the bool interface") {
|
||||
config->set("gcode_comments", true);
|
||||
THEN("The underlying value is set correctly.") {
|
||||
REQUIRE(config->get<ConfigOptionBool>("gcode_comments").getBool() == true);
|
||||
WHEN("A boolean option is set to a boolean value") {
|
||||
THEN("A BadOptionTypeException exception is thrown.") {
|
||||
REQUIRE_THROWS_AS(config->set("gcode_comments", true), BadOptionTypeException);
|
||||
}
|
||||
}
|
||||
WHEN("A boolean option is set through the string interface") {
|
||||
WHEN("A boolean option is set to a string value") {
|
||||
config->set("gcode_comments", "1");
|
||||
THEN("The underlying value is set correctly.") {
|
||||
REQUIRE(config->get<ConfigOptionBool>("gcode_comments").getBool() == true);
|
||||
}
|
||||
}
|
||||
WHEN("A boolean option is set through the int interface") {
|
||||
config->set("gcode_comments", 1);
|
||||
THEN("The underlying value is set correctly.") {
|
||||
REQUIRE(config->get<ConfigOptionBool>("gcode_comments").getBool() == true);
|
||||
WHEN("A string option is set to an int value") {
|
||||
THEN("A BadOptionTypeException exception is thrown.") {
|
||||
REQUIRE_THROWS_AS(config->set("gcode_comments", 1), BadOptionTypeException);
|
||||
}
|
||||
}
|
||||
WHEN("A numeric option is set through the string interface") {
|
||||
WHEN("A numeric option is set from serialized string") {
|
||||
config->set("bed_temperature", "100");
|
||||
THEN("The underlying value is set correctly.") {
|
||||
REQUIRE(config->get<ConfigOptionInt>("bed_temperature").getInt() == 100);
|
||||
@ -92,14 +96,13 @@ SCENARIO("Config accessor functions perform as expected.") {
|
||||
}
|
||||
}
|
||||
WHEN("An integer-based option is set through the double interface") {
|
||||
config->set("bed_temperature", 5.5);
|
||||
THEN("The underlying value is set, rounded to the nearest integer.") {
|
||||
REQUIRE(config->get<ConfigOptionInt>("bed_temperature").getInt() == 6);
|
||||
THEN("A BadOptionTypeException exception is thrown.") {
|
||||
REQUIRE_THROWS_AS(config->set("bed_temperature", 5.5), BadOptionTypeException);
|
||||
}
|
||||
}
|
||||
WHEN("A numeric option is set to a non-numeric value.") {
|
||||
THEN("An InvalidOptionValue exception is thown.") {
|
||||
REQUIRE_THROWS_AS(config->set("perimeter_speed", "zzzz"), InvalidOptionValue);
|
||||
THEN("A BadOptionTypeException exception is thown.") {
|
||||
REQUIRE_THROWS_AS(config->set("perimeter_speed", "zzzz"), BadOptionTypeException);
|
||||
}
|
||||
THEN("The value does not change.") {
|
||||
REQUIRE(config->get<ConfigOptionFloat>("perimeter_speed").getFloat() == 60.0);
|
||||
@ -156,36 +159,34 @@ SCENARIO("Config accessor functions perform as expected.") {
|
||||
}
|
||||
}
|
||||
WHEN("An invalid option is requested during set.") {
|
||||
THEN("An InvalidOptionType exception is thrown.") {
|
||||
REQUIRE_THROWS_AS(config->set("deadbeef_invalid_option", 1), InvalidOptionType);
|
||||
REQUIRE_THROWS_AS(config->set("deadbeef_invalid_option", 1.0), InvalidOptionType);
|
||||
REQUIRE_THROWS_AS(config->set("deadbeef_invalid_option", "1"), InvalidOptionType);
|
||||
REQUIRE_THROWS_AS(config->set("deadbeef_invalid_option", true), InvalidOptionType);
|
||||
THEN("A BadOptionTypeException exception is thrown.") {
|
||||
REQUIRE_THROWS_AS(config->set("deadbeef_invalid_option", 1), UnknownOptionException);
|
||||
REQUIRE_THROWS_AS(config->set("deadbeef_invalid_option", 1.0), UnknownOptionException);
|
||||
REQUIRE_THROWS_AS(config->set("deadbeef_invalid_option", "1"), UnknownOptionException);
|
||||
REQUIRE_THROWS_AS(config->set("deadbeef_invalid_option", true), UnknownOptionException);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("An invalid option is requested during get.") {
|
||||
THEN("An InvalidOptionType exception is thrown.") {
|
||||
REQUIRE_THROWS_AS(config->get<ConfigOptionString>("deadbeef_invalid_option", false), InvalidOptionType);
|
||||
REQUIRE_THROWS_AS(config->get<ConfigOptionFloat>("deadbeef_invalid_option", false), InvalidOptionType);
|
||||
REQUIRE_THROWS_AS(config->get<ConfigOptionInt>("deadbeef_invalid_option", false), InvalidOptionType);
|
||||
REQUIRE_THROWS_AS(config->get<ConfigOptionBool>("deadbeef_invalid_option", false), InvalidOptionType);
|
||||
THEN("A BadOptionTypeException exception is thrown.") {
|
||||
REQUIRE_THROWS_AS(config->get<ConfigOptionString>("deadbeef_invalid_option", false), UnknownOptionException);
|
||||
REQUIRE_THROWS_AS(config->get<ConfigOptionFloat>("deadbeef_invalid_option", false), UnknownOptionException);
|
||||
REQUIRE_THROWS_AS(config->get<ConfigOptionInt>("deadbeef_invalid_option", false), UnknownOptionException);
|
||||
REQUIRE_THROWS_AS(config->get<ConfigOptionBool>("deadbeef_invalid_option", false), UnknownOptionException);
|
||||
}
|
||||
}
|
||||
WHEN("An invalid option is requested during get_ptr.") {
|
||||
THEN("An InvalidOptionType exception is thrown.") {
|
||||
REQUIRE_THROWS_AS(config->get_ptr<ConfigOptionString>("deadbeef_invalid_option", false), InvalidOptionType);
|
||||
REQUIRE_THROWS_AS(config->get_ptr<ConfigOptionFloat>("deadbeef_invalid_option", false), InvalidOptionType);
|
||||
REQUIRE_THROWS_AS(config->get_ptr<ConfigOptionInt>("deadbeef_invalid_option", false), InvalidOptionType);
|
||||
REQUIRE_THROWS_AS(config->get_ptr<ConfigOptionBool>("deadbeef_invalid_option", false), InvalidOptionType);
|
||||
THEN("A BadOptionTypeException exception is thrown.") {
|
||||
REQUIRE_THROWS_AS(config->get_ptr<ConfigOptionString>("deadbeef_invalid_option", false), UnknownOptionException);
|
||||
REQUIRE_THROWS_AS(config->get_ptr<ConfigOptionFloat>("deadbeef_invalid_option", false), UnknownOptionException);
|
||||
REQUIRE_THROWS_AS(config->get_ptr<ConfigOptionInt>("deadbeef_invalid_option", false), UnknownOptionException);
|
||||
REQUIRE_THROWS_AS(config->get_ptr<ConfigOptionBool>("deadbeef_invalid_option", false), UnknownOptionException);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("getX called on an unset option.") {
|
||||
THEN("The default is returned.") {
|
||||
REQUIRE(config->getFloat("layer_height") == 0.3);
|
||||
REQUIRE(config->getString("layer_height") == "0.3");
|
||||
REQUIRE(config->getString("layer_height") == "0.3");
|
||||
REQUIRE(config->getInt("raft_layers") == 0);
|
||||
REQUIRE(config->getBool("support_material") == false);
|
||||
}
|
||||
@ -195,7 +196,6 @@ SCENARIO("Config accessor functions perform as expected.") {
|
||||
config->set("layer_height", 0.5);
|
||||
THEN("The set value is returned.") {
|
||||
REQUIRE(config->getFloat("layer_height") == 0.5);
|
||||
REQUIRE(config->getString("layer_height") == "0.5");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,13 @@
|
||||
#include "Config.hpp"
|
||||
#include "Log.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
extern const PrintConfigDef print_config_def;
|
||||
|
||||
std::shared_ptr<Config>
|
||||
Config::new_from_defaults()
|
||||
{
|
||||
return std::make_shared<Config>();
|
||||
std::shared_ptr<Config> my_config(std::make_shared<Config>());
|
||||
my_config->_config.apply(FullPrintConfig());
|
||||
return my_config;
|
||||
}
|
||||
std::shared_ptr<Config>
|
||||
Config::new_from_defaults(std::initializer_list<std::string> init)
|
||||
@ -22,330 +19,16 @@ std::shared_ptr<Config>
|
||||
Config::new_from_defaults(t_config_option_keys init)
|
||||
{
|
||||
std::shared_ptr<Config> my_config(std::make_shared<Config>());
|
||||
for (auto& opt_key : init) {
|
||||
if (print_config_def.has(opt_key)) {
|
||||
const std::string value { print_config_def.get(opt_key).default_value->serialize() };
|
||||
my_config->_config.set_deserialize(opt_key, value);
|
||||
}
|
||||
}
|
||||
|
||||
my_config->_config.set_defaults(init);
|
||||
return my_config;
|
||||
}
|
||||
|
||||
std::shared_ptr<Config>
|
||||
Config::new_from_ini(const std::string& inifile)
|
||||
{
|
||||
|
||||
std::shared_ptr<Config> my_config(std::make_shared<Config>());
|
||||
my_config->read_ini(inifile);
|
||||
my_config->_config.load(inifile);
|
||||
return my_config;
|
||||
}
|
||||
|
||||
// TODO: this should be merged into ConfigBase::validate()
|
||||
bool
|
||||
Config::validate()
|
||||
{
|
||||
// general validation
|
||||
for (auto k : this->_config.keys()) {
|
||||
if (print_config_def.options.count(k) == 0) continue; // skip over keys that aren't in the master list
|
||||
const ConfigOptionDef& opt { print_config_def.options.at(k) };
|
||||
if (opt.cli == "" || std::regex_search(opt.cli, _match_info, _cli_pattern) == false) continue;
|
||||
std::string type { _match_info.str(1) };
|
||||
std::vector<std::string> values;
|
||||
if (std::regex_search(type, _match_info, std::regex("@$"))) {
|
||||
type = std::regex_replace(type, std::regex("@$"), std::string("")); // strip off the @ for later;
|
||||
ConfigOptionVectorBase* tmp_opt;
|
||||
try {
|
||||
tmp_opt = get_ptr<ConfigOptionVectorBase>(k);
|
||||
} catch (std::bad_cast& e) {
|
||||
throw InvalidOptionType((std::string("(cast failure) Invalid value for ") + std::string(k)).c_str());
|
||||
}
|
||||
const std::vector<std::string> tmp_str { tmp_opt->vserialize() };
|
||||
values.insert(values.end(), tmp_str.begin(), tmp_str.end());
|
||||
} else {
|
||||
Slic3r::Log::debug("Config::validate", std::string("Not an array"));
|
||||
Slic3r::Log::debug("Config::validate", type);
|
||||
values.emplace_back(get_ptr<ConfigOption>(k)->serialize());
|
||||
}
|
||||
// Verify each value
|
||||
for (auto v : values) {
|
||||
if (type == "i" || type == "f" || opt.type == coPercent || opt.type == coFloatOrPercent) {
|
||||
if (opt.type == coPercent || opt.type == coFloatOrPercent)
|
||||
v = std::regex_replace(v, std::regex("%$"), std::string(""));
|
||||
if ((type == "i" && !is_valid_int(type, opt, v)) || !is_valid_float(type, opt, v)) {
|
||||
throw InvalidOptionValue((std::string("Invalid value for ") + std::string(k)).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Config::set(const t_config_option_key& opt_key, const std::string& value)
|
||||
{
|
||||
try {
|
||||
const auto& def = print_config_def.options.at(opt_key);
|
||||
switch (def.type) {
|
||||
case coInt:
|
||||
{
|
||||
ConfigOptionInt* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->value = std::stoi(value);
|
||||
} break;
|
||||
case coInts:
|
||||
{
|
||||
ConfigOptionInts* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
|
||||
if (!ptr->deserialize(value, true) ) {
|
||||
throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
|
||||
}
|
||||
} break;
|
||||
case coFloat:
|
||||
{
|
||||
ConfigOptionFloat* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setFloat(std::stod(value));
|
||||
} break;
|
||||
case coFloatOrPercent:
|
||||
{
|
||||
ConfigOptionFloatOrPercent* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
|
||||
const size_t perc = value.find("%");
|
||||
ptr->percent = (perc != std::string::npos);
|
||||
if (ptr->percent) {
|
||||
ptr->setFloat(std::stod(std::string(value).replace(value.find("%"), std::string("%").length(), "")));
|
||||
ptr->percent = true;
|
||||
} else {
|
||||
ptr->setFloat(std::stod(value));
|
||||
ptr->percent = false;
|
||||
}
|
||||
} break;
|
||||
case coFloats:
|
||||
{
|
||||
ConfigOptionFloats* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
|
||||
if (!ptr->deserialize(value, true) ) {
|
||||
throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
|
||||
}
|
||||
} break;
|
||||
case coString:
|
||||
{
|
||||
ConfigOptionString* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
|
||||
if (!ptr->deserialize(value) ) {
|
||||
throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
|
||||
}
|
||||
} break;
|
||||
case coBool:
|
||||
{
|
||||
ConfigOptionBool* ptr {dynamic_cast<ConfigOptionBool*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->deserialize(value);
|
||||
} break;
|
||||
default:
|
||||
Slic3r::Log::warn("Config::set", "Unknown set type.");
|
||||
}
|
||||
} catch (std::invalid_argument& e) {
|
||||
throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
|
||||
} catch (std::out_of_range& e) {
|
||||
throw InvalidOptionType(std::string(opt_key) + std::string(" is an invalid Slic3r option."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Config::set(const t_config_option_key& opt_key, const bool value)
|
||||
{
|
||||
try {
|
||||
const auto& def = print_config_def.options.at(opt_key);
|
||||
switch (def.type) {
|
||||
case coBool:
|
||||
{
|
||||
ConfigOptionBool* ptr {dynamic_cast<ConfigOptionBool*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->value = value;
|
||||
} break;
|
||||
case coInt:
|
||||
{
|
||||
ConfigOptionInt* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setInt(value);
|
||||
} break;
|
||||
case coInts:
|
||||
{
|
||||
ConfigOptionInts* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->deserialize(std::to_string(value), true);
|
||||
} break;
|
||||
case coFloat:
|
||||
{
|
||||
ConfigOptionFloat* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setFloat(value);
|
||||
} break;
|
||||
case coFloatOrPercent:
|
||||
{
|
||||
ConfigOptionFloatOrPercent* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setFloat(value);
|
||||
ptr->percent = false;
|
||||
} break;
|
||||
case coFloats:
|
||||
{
|
||||
ConfigOptionFloats* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->deserialize(std::to_string(value), true);
|
||||
} break;
|
||||
case coString:
|
||||
{
|
||||
ConfigOptionString* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
|
||||
if (!ptr->deserialize(std::to_string(value)) ) {
|
||||
throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
Slic3r::Log::warn("Config::set", "Unknown set type.");
|
||||
}
|
||||
|
||||
} catch (std::out_of_range &e) {
|
||||
throw InvalidOptionType(std::string(opt_key) + std::string(" is an invalid Slic3r option."));
|
||||
}
|
||||
|
||||
}
|
||||
void
|
||||
Config::set(const t_config_option_key& opt_key, const int value)
|
||||
{
|
||||
try {
|
||||
const auto& def = print_config_def.options.at(opt_key);
|
||||
switch (def.type) {
|
||||
case coBool:
|
||||
{
|
||||
ConfigOptionBool* ptr {dynamic_cast<ConfigOptionBool*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->value = (value != 0);
|
||||
} break;
|
||||
case coInt:
|
||||
{
|
||||
ConfigOptionInt* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setInt(value);
|
||||
} break;
|
||||
case coInts:
|
||||
{
|
||||
ConfigOptionInts* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->deserialize(std::to_string(value), true);
|
||||
} break;
|
||||
case coFloat:
|
||||
{
|
||||
ConfigOptionFloat* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setFloat(value);
|
||||
} break;
|
||||
case coFloatOrPercent:
|
||||
{
|
||||
ConfigOptionFloatOrPercent* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setFloat(value);
|
||||
ptr->percent = false;
|
||||
} break;
|
||||
case coFloats:
|
||||
{
|
||||
ConfigOptionFloats* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->deserialize(std::to_string(value), true);
|
||||
} break;
|
||||
case coString:
|
||||
{
|
||||
ConfigOptionString* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
|
||||
if (!ptr->deserialize(std::to_string(value)) ) {
|
||||
throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
Slic3r::Log::warn("Config::set", "Unknown set type.");
|
||||
}
|
||||
|
||||
} catch (std::out_of_range &e) {
|
||||
throw InvalidOptionType(std::string(opt_key) + std::string(" is an invalid Slic3r option."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Config::set(const t_config_option_key& opt_key, const double value)
|
||||
{
|
||||
try {
|
||||
const auto& def = print_config_def.options.at(opt_key);
|
||||
switch (def.type) {
|
||||
case coInt:
|
||||
{
|
||||
ConfigOptionInt* ptr {dynamic_cast<ConfigOptionInt*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setInt(std::round(value));
|
||||
} break;
|
||||
case coInts:
|
||||
{
|
||||
ConfigOptionInts* ptr {dynamic_cast<ConfigOptionInts*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->deserialize(std::to_string(std::round(value)), true);
|
||||
} break;
|
||||
case coFloat:
|
||||
{
|
||||
ConfigOptionFloat* ptr {dynamic_cast<ConfigOptionFloat*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setFloat(value);
|
||||
} break;
|
||||
case coFloatOrPercent:
|
||||
{
|
||||
ConfigOptionFloatOrPercent* ptr {dynamic_cast<ConfigOptionFloatOrPercent*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->setFloat(value);
|
||||
ptr->percent = false;
|
||||
} break;
|
||||
case coFloats:
|
||||
{
|
||||
ConfigOptionFloats* ptr {dynamic_cast<ConfigOptionFloats*>(this->_config.optptr(opt_key, true))};
|
||||
ptr->deserialize(std::to_string(value), true);
|
||||
} break;
|
||||
case coString:
|
||||
{
|
||||
ConfigOptionString* ptr {dynamic_cast<ConfigOptionString*>(this->_config.optptr(opt_key, true))};
|
||||
if (!ptr->deserialize(std::to_string(value)) ) {
|
||||
throw InvalidOptionValue(std::string(opt_key) + std::string(" set with invalid value."));
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
Slic3r::Log::warn("Config::set", "Unknown set type.");
|
||||
}
|
||||
} catch (std::out_of_range &e) {
|
||||
throw InvalidOptionType(std::string(opt_key) + std::string(" is an invalid Slic3r option."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Config::read_ini(const std::string& file)
|
||||
{
|
||||
this->_config.load(file);
|
||||
}
|
||||
|
||||
void
|
||||
Config::write_ini(const std::string& file) const
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
is_valid_int(const std::string& type, const ConfigOptionDef& opt, const std::string& ser_value)
|
||||
{
|
||||
std::regex _valid_int {"^-?\\d+$"};
|
||||
std::smatch match;
|
||||
ConfigOptionInt tmp;
|
||||
|
||||
bool result {type == "i"};
|
||||
if (result)
|
||||
result = result && std::regex_search(ser_value, match, _valid_int);
|
||||
if (result) {
|
||||
tmp.deserialize(ser_value);
|
||||
result = result & (tmp.getInt() <= opt.max && tmp.getInt() >= opt.min);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
is_valid_float(const std::string& type, const ConfigOptionDef& opt, const std::string& ser_value)
|
||||
{
|
||||
std::regex _valid_float {"^-?(?:\\d+|\\d*\\.\\d+)$"};
|
||||
std::smatch match;
|
||||
ConfigOptionFloat tmp;
|
||||
Slic3r::Log::debug("is_valid_float", ser_value);
|
||||
|
||||
bool result {type == "f" || opt.type == coPercent || opt.type == coFloatOrPercent};
|
||||
if (result)
|
||||
result = result && std::regex_search(ser_value, match, _valid_float);
|
||||
if (result) {
|
||||
tmp.deserialize(ser_value);
|
||||
result = result & (tmp.getFloat() <= opt.max && tmp.getFloat() >= opt.min);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Config::Config() : _config(DynamicPrintConfig()) {};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -5,30 +5,13 @@
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#include "PrintConfig.hpp"
|
||||
#include "ConfigBase.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
/// Exception class for invalid (but correct type) option values.
|
||||
/// Thrown by validate()
|
||||
class InvalidOptionValue : public std::runtime_error {
|
||||
public:
|
||||
InvalidOptionValue(const char* v) : runtime_error(v) {}
|
||||
InvalidOptionValue(const std::string v) : runtime_error(v.c_str()) {}
|
||||
};
|
||||
|
||||
/// Exception class to handle config options that don't exist.
|
||||
class InvalidConfigOption : public std::runtime_error {};
|
||||
|
||||
/// Exception class for type mismatches
|
||||
class InvalidOptionType : public std::runtime_error {
|
||||
public:
|
||||
InvalidOptionType(const char* v) : runtime_error(v) {}
|
||||
InvalidOptionType(const std::string v) : runtime_error(v.c_str()) {}
|
||||
};
|
||||
|
||||
class Config;
|
||||
using config_ptr = std::shared_ptr<Config>;
|
||||
using config_ref = std::weak_ptr<Config>;
|
||||
@ -48,69 +31,66 @@ public:
|
||||
/// Factory method to construct a Config from an ini file.
|
||||
static std::shared_ptr<Config> new_from_ini(const std::string& inifile);
|
||||
|
||||
/// Write a windows-style opt=value ini file with categories from the configuration store.
|
||||
void write_ini(const std::string& file) const;
|
||||
|
||||
/// Parse a windows-style opt=value ini file with categories and load the configuration store.
|
||||
void read_ini(const std::string& file);
|
||||
|
||||
|
||||
double getFloat(const t_config_option_key& opt_key, bool create=true) {
|
||||
if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option."));
|
||||
return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getFloat();
|
||||
double getFloat(const t_config_option_key& opt_key) const {
|
||||
return this->_config.getFloat(opt_key);
|
||||
}
|
||||
int getInt(const t_config_option_key& opt_key, bool create=true) {
|
||||
if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option."));
|
||||
return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getInt();
|
||||
int getInt(const t_config_option_key& opt_key) const {
|
||||
return this->_config.getInt(opt_key);
|
||||
}
|
||||
bool getBool(const t_config_option_key& opt_key, bool create=true) {
|
||||
if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option."));
|
||||
return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getBool();
|
||||
bool getBool(const t_config_option_key& opt_key) const {
|
||||
return this->_config.getBool(opt_key);
|
||||
}
|
||||
std::string getString(const t_config_option_key& opt_key, bool create=true) {
|
||||
if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option."));
|
||||
return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getString();
|
||||
std::string getString(const t_config_option_key& opt_key) const {
|
||||
return this->_config.getString(opt_key);
|
||||
}
|
||||
|
||||
|
||||
/// Template function to dynamic cast and leave it in pointer form.
|
||||
template <class T>
|
||||
T* get_ptr(const t_config_option_key& opt_key, bool create=true) {
|
||||
if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option."));
|
||||
return dynamic_cast<T*>(this->_config.optptr(opt_key, create));
|
||||
return this->_config.opt_throw<T>(opt_key, create);
|
||||
}
|
||||
|
||||
/// Template function to retrieve and cast in hopefully a slightly nicer
|
||||
/// format than longwinded dynamic_cast<>
|
||||
template <class T>
|
||||
T& get(const t_config_option_key& opt_key, bool create=true) {
|
||||
if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option."));
|
||||
return *(dynamic_cast<T*>(this->_config.optptr(opt_key, create)));
|
||||
return *this->_config.opt_throw<T>(opt_key, create);
|
||||
}
|
||||
|
||||
/// Function to parse value from a string to whatever opt_key is.
|
||||
void set(const t_config_option_key& opt_key, const std::string& value);
|
||||
void set(const t_config_option_key& opt_key, const std::string& value) {
|
||||
this->_config.set_deserialize_throw(opt_key, value);
|
||||
};
|
||||
|
||||
void set(const t_config_option_key& opt_key, const char* value) { this->set(opt_key, std::string(value));}
|
||||
void set(const t_config_option_key& opt_key, const char* value) {
|
||||
this->set(opt_key, std::string(value));
|
||||
};
|
||||
|
||||
/// Function to parse value from an integer to whatever opt_key is, if
|
||||
/// opt_key is a numeric type. This will throw an exception and do
|
||||
/// nothing if called with an incorrect type.
|
||||
void set(const t_config_option_key& opt_key, const int value);
|
||||
void set(const t_config_option_key& opt_key, const int value) {
|
||||
this->_config.setInt(opt_key, value);
|
||||
};
|
||||
|
||||
/// Function to parse value from an boolean to whatever opt_key is, if
|
||||
/// opt_key is a numeric type. This will throw an exception and do
|
||||
/// nothing if called with an incorrect type.
|
||||
void set(const t_config_option_key& opt_key, const bool value);
|
||||
void set(const t_config_option_key& opt_key, const bool value) {
|
||||
this->_config.setBool(opt_key, value);
|
||||
};
|
||||
|
||||
/// Function to parse value from an integer to whatever opt_key is, if
|
||||
/// opt_key is a numeric type. This will throw an exception and do
|
||||
/// nothing if called with an incorrect type.
|
||||
void set(const t_config_option_key& opt_key, const double value);
|
||||
void set(const t_config_option_key& opt_key, const double value) {
|
||||
this->_config.setFloat(opt_key, value);
|
||||
};
|
||||
|
||||
/// Method to validate the different configuration options.
|
||||
/// It will throw InvalidConfigOption exceptions on failure.
|
||||
bool validate();
|
||||
/// It will throw InvalidOptionException exceptions on failure.
|
||||
void validate() { this->_config.validate(); };
|
||||
|
||||
const DynamicPrintConfig& config() const { return _config; }
|
||||
bool empty() const { return _config.empty(); }
|
||||
@ -134,20 +114,13 @@ public:
|
||||
bool has(const t_config_option_key& k) const { return _config.has(k); };
|
||||
|
||||
/// Do not use; prefer static factory methods instead.
|
||||
Config();
|
||||
Config() : _config(DynamicPrintConfig()) {};
|
||||
|
||||
private:
|
||||
std::regex _cli_pattern {"=(.+)$"};
|
||||
std::smatch _match_info {};
|
||||
|
||||
|
||||
/// Underlying configuration store.
|
||||
DynamicPrintConfig _config {};
|
||||
};
|
||||
|
||||
bool is_valid_int(const std::string& type, const ConfigOptionDef& opt, const std::string& ser_value);
|
||||
bool is_valid_float(const std::string& type, const ConfigOptionDef& opt, const std::string& ser_value);
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // CONFIG_HPP
|
||||
|
@ -397,6 +397,16 @@ ConfigBase::apply_only(const ConfigBase &other, const t_config_option_keys &opt_
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::set_defaults(const t_config_option_keys &opt_keys)
|
||||
{
|
||||
// use defaults from definition
|
||||
if (this->def == NULL) return;
|
||||
for (auto opt_key : opt_keys)
|
||||
if (this->def->has(opt_key))
|
||||
this->option(opt_key, true)->set(*this->def->options.at(opt_key).default_value);
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigBase::equals(const ConfigBase &other) const {
|
||||
return this->diff(other).empty();
|
||||
@ -451,6 +461,12 @@ ConfigBase::set_deserialize(t_config_option_key opt_key, std::string str, bool a
|
||||
return opt->deserialize(str, append);
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::set_deserialize_throw(t_config_option_key opt_key, std::string str, bool append) {
|
||||
bool res = this->set_deserialize(opt_key, str, append);
|
||||
if (!res) throw BadOptionTypeException();
|
||||
}
|
||||
|
||||
// Return an absolute value of a possibly relative config variable.
|
||||
// For example, return absolute infill extrusion width, either from an absolute value, or relative to the layer height.
|
||||
double
|
||||
@ -482,34 +498,84 @@ ConfigBase::get_abs_value(const t_config_option_key &opt_key, double ratio_over)
|
||||
return opt->get_abs_value(ratio_over);
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigBase::getBool(const t_config_option_key &opt_key) const {
|
||||
return this->option_throw(opt_key)->getBool();
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigBase::getBool(const t_config_option_key &opt_key, bool default_value) const {
|
||||
auto opt = this->opt<ConfigOptionBool>(opt_key);
|
||||
return opt == nullptr ? default_value : opt->value;
|
||||
const ConfigOption* opt = this->option(opt_key);
|
||||
return opt == nullptr ? default_value : opt->getBool();
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::setBool(const t_config_option_key &opt_key, bool value) {
|
||||
this->option(opt_key, true)->setBool(value);
|
||||
}
|
||||
|
||||
double
|
||||
ConfigBase::getFloat(const t_config_option_key &opt_key) const {
|
||||
return this->option_throw(opt_key)->getFloat();
|
||||
}
|
||||
|
||||
double
|
||||
ConfigBase::getFloat(const t_config_option_key &opt_key, double default_value) const {
|
||||
auto opt = this->opt<ConfigOptionFloat>(opt_key);
|
||||
return opt == nullptr ? default_value : opt->value;
|
||||
const ConfigOption* opt = this->option(opt_key);
|
||||
return opt == nullptr ? default_value : opt->getFloat();
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::setFloat(const t_config_option_key &opt_key, double value) {
|
||||
this->option(opt_key, true)->setFloat(value);
|
||||
}
|
||||
|
||||
int
|
||||
ConfigBase::getInt(const t_config_option_key &opt_key, double default_value) const {
|
||||
auto opt = this->opt<ConfigOptionInt>(opt_key);
|
||||
return opt == nullptr ? default_value : opt->value;
|
||||
ConfigBase::getInt(const t_config_option_key &opt_key) const {
|
||||
return this->option_throw(opt_key)->getInt();
|
||||
}
|
||||
|
||||
int
|
||||
ConfigBase::getInt(const t_config_option_key &opt_key, int default_value) const {
|
||||
const ConfigOption* opt = this->option(opt_key);
|
||||
return opt == nullptr ? default_value : opt->getInt();
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::setInt(const t_config_option_key &opt_key, int value) {
|
||||
this->option(opt_key, true)->setInt(value);
|
||||
}
|
||||
|
||||
std::string
|
||||
ConfigBase::getString(const t_config_option_key &opt_key) const {
|
||||
return this->option_throw(opt_key)->getString();
|
||||
}
|
||||
|
||||
std::string
|
||||
ConfigBase::getString(const t_config_option_key &opt_key, std::string default_value) const {
|
||||
auto opt = this->opt<ConfigOptionString>(opt_key);
|
||||
return opt == nullptr ? default_value : opt->value;
|
||||
const ConfigOption* opt = this->option(opt_key);
|
||||
return opt == nullptr ? default_value : opt->getString();
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::setString(const t_config_option_key &opt_key, std::string value) {
|
||||
this->option(opt_key, true)->setString(value);
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
ConfigBase::getStrings(const t_config_option_key &opt_key) const {
|
||||
return this->option_throw(opt_key)->getStrings();
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
ConfigBase::getStrings(const t_config_option_key &opt_key, std::vector<std::string> default_value) const {
|
||||
auto opt = this->opt<ConfigOptionStrings>(opt_key);
|
||||
return opt == nullptr ? default_value : opt->values;
|
||||
const ConfigOption* opt = this->option(opt_key);
|
||||
return opt == nullptr ? default_value : opt->getStrings();
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::setStrings(const t_config_option_key &opt_key, std::vector<std::string> value) {
|
||||
this->option(opt_key, true)->setStrings(value);
|
||||
}
|
||||
|
||||
void
|
||||
@ -527,11 +593,25 @@ ConfigBase::option(const t_config_option_key &opt_key) const {
|
||||
return const_cast<ConfigBase*>(this)->option(opt_key, false);
|
||||
}
|
||||
|
||||
const ConfigOption*
|
||||
ConfigBase::option_throw(const t_config_option_key &opt_key) const {
|
||||
const auto opt = this->option(opt_key);
|
||||
if (opt == nullptr) throw UnknownOptionException(opt_key);
|
||||
return opt;
|
||||
}
|
||||
|
||||
ConfigOption*
|
||||
ConfigBase::option(const t_config_option_key &opt_key, bool create) {
|
||||
return this->optptr(opt_key, create);
|
||||
}
|
||||
|
||||
ConfigOption*
|
||||
ConfigBase::option_throw(const t_config_option_key &opt_key, bool create) {
|
||||
auto opt = this->optptr(opt_key, create);
|
||||
if (opt == nullptr) throw UnknownOptionException(opt_key);
|
||||
return opt;
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::load(const std::string &file)
|
||||
{
|
||||
@ -587,6 +667,11 @@ ConfigBase::validate() const
|
||||
auto &value = this->opt<ConfigOptionFloat>(opt_key)->value;
|
||||
if (value < def.min || value > def.max)
|
||||
throw InvalidOptionException(opt_key);
|
||||
} else if (def.type == coFloatOrPercent) {
|
||||
const auto* opt = this->opt<ConfigOptionFloatOrPercent>(opt_key);
|
||||
auto &value = opt->value;
|
||||
if (!opt->percent && (value < def.min || value > def.max))
|
||||
throw InvalidOptionException(opt_key);
|
||||
} else if (def.type == coInts) {
|
||||
for (auto &value : this->opt<ConfigOptionInts>(opt_key)->values)
|
||||
if (value < def.min || value > def.max)
|
||||
@ -596,7 +681,6 @@ ConfigBase::validate() const
|
||||
if (value < def.min || value > def.max)
|
||||
throw InvalidOptionException(opt_key);
|
||||
}
|
||||
// TODO: validate coFloatOrPercent (semantics of min/max are ambiguous for it)
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,7 +713,7 @@ ConfigOption*
|
||||
DynamicConfig::optptr(const t_config_option_key &opt_key, bool create) {
|
||||
if (this->options.count(opt_key) == 0) {
|
||||
if (create) {
|
||||
if (!this->def->has(opt_key)) return nullptr;
|
||||
if (!this->def->has(opt_key)) throw UnknownOptionException(opt_key);
|
||||
const ConfigOptionDef& optdef = this->def->options.at(opt_key);
|
||||
ConfigOption* opt;
|
||||
if (optdef.default_value != nullptr) {
|
||||
@ -811,11 +895,7 @@ DynamicConfig::read_cli(int argc, char** argv, t_config_option_keys* extra, t_co
|
||||
void
|
||||
StaticConfig::set_defaults()
|
||||
{
|
||||
// use defaults from definition
|
||||
if (this->def == NULL) return;
|
||||
for (auto opt_key : this->keys())
|
||||
if (this->def->has(opt_key))
|
||||
this->option(opt_key)->set(*this->def->options.at(opt_key).default_value);
|
||||
ConfigBase::set_defaults(this->keys());
|
||||
}
|
||||
|
||||
t_config_option_keys
|
||||
|
@ -26,6 +26,31 @@ extern std::string escape_strings_cstyle(const std::vector<std::string> &strs);
|
||||
extern bool unescape_string_cstyle(const std::string &str, std::string &out);
|
||||
extern bool unescape_strings_cstyle(const std::string &str, std::vector<std::string> &out);
|
||||
|
||||
/// Specialization of std::exception to indicate that an unknown config option has been encountered.
|
||||
class ConfigOptionException : public std::exception {
|
||||
public:
|
||||
t_config_option_key opt_key;
|
||||
ConfigOptionException(t_config_option_key _opt_key)
|
||||
: opt_key(_opt_key) {};
|
||||
};
|
||||
class UnknownOptionException : public ConfigOptionException {
|
||||
using ConfigOptionException::ConfigOptionException;
|
||||
};
|
||||
class InvalidOptionException : public ConfigOptionException {
|
||||
using ConfigOptionException::ConfigOptionException;
|
||||
|
||||
public:
|
||||
virtual const char* what() const noexcept {
|
||||
std::string s("Invalid value for option: ");
|
||||
s += this->opt_key;
|
||||
return s.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
/// Specialization of std::exception to indicate that an unsupported accessor was called on a config option.
|
||||
class BadOptionTypeException : public std::exception {};
|
||||
|
||||
|
||||
/// \brief Public interface for configuration options.
|
||||
///
|
||||
/// Defines get/set for all supported data types.
|
||||
@ -38,14 +63,22 @@ class ConfigOption {
|
||||
virtual std::string serialize() const = 0;
|
||||
virtual bool deserialize(std::string str, bool append = false) = 0;
|
||||
virtual void set(const ConfigOption &option) = 0;
|
||||
virtual int getInt() const { return 0; };
|
||||
virtual double getFloat() const { return 0; };
|
||||
virtual bool getBool() const { return false; };
|
||||
virtual void setInt(int val) {};
|
||||
virtual void setFloat(double val) {};
|
||||
virtual void setString(std::string val) {};
|
||||
virtual std::string getString() const { return ""; };
|
||||
virtual std::vector<std::string> getStrings() const { return std::vector<std::string>(); };
|
||||
|
||||
virtual bool getBool() const { throw BadOptionTypeException(); };
|
||||
virtual void setBool(bool val) { throw BadOptionTypeException(); };
|
||||
|
||||
virtual int getInt() const { throw BadOptionTypeException(); };
|
||||
virtual void setInt(int val) { throw BadOptionTypeException(); };
|
||||
|
||||
virtual double getFloat() const { throw BadOptionTypeException(); };
|
||||
virtual void setFloat(double val) { throw BadOptionTypeException(); };
|
||||
|
||||
virtual std::string getString() const { throw BadOptionTypeException(); };
|
||||
virtual void setString(std::string val) { throw BadOptionTypeException(); };
|
||||
|
||||
virtual std::vector<std::string> getStrings() const { throw BadOptionTypeException(); };
|
||||
virtual void setStrings(std::vector<std::string> val) { throw BadOptionTypeException(); };
|
||||
|
||||
friend bool operator== (const ConfigOption &a, const ConfigOption &b);
|
||||
friend bool operator!= (const ConfigOption &a, const ConfigOption &b);
|
||||
};
|
||||
@ -108,7 +141,6 @@ class ConfigOptionFloat : public ConfigOptionSingle<double>
|
||||
double getFloat() const override { return this->value; };
|
||||
void setFloat(double val) override { this->value = val; }
|
||||
void setInt(int val) override { this->value = val; }
|
||||
std::string getString() const override { return trim_zeroes(std::to_string(this->value)); }
|
||||
|
||||
std::string serialize() const override {
|
||||
std::ostringstream ss;
|
||||
@ -178,7 +210,6 @@ class ConfigOptionInt : public ConfigOptionSingle<int>
|
||||
|
||||
int getInt() const override { return this->value; };
|
||||
void setInt(int val) override { this->value = val; };
|
||||
std::string getString() const override { return std::to_string(this->value); }
|
||||
|
||||
std::string serialize() const override {
|
||||
std::ostringstream ss;
|
||||
@ -239,15 +270,18 @@ class ConfigOptionString : public ConfigOptionSingle<std::string>
|
||||
public:
|
||||
ConfigOptionString() : ConfigOptionSingle<std::string>("") {};
|
||||
ConfigOptionString(std::string _value) : ConfigOptionSingle<std::string>(_value) {};
|
||||
ConfigOptionString* clone() const { return new ConfigOptionString(this->value); };
|
||||
ConfigOptionString* clone() const override { return new ConfigOptionString(this->value); };
|
||||
|
||||
std::string getString() const { return this->value; };
|
||||
std::string getString() const override { return this->value; };
|
||||
void setString(std::string val) override { this->value = val; };
|
||||
void setInt(int val) override { this->value = std::to_string(val); };
|
||||
void setFloat(double val) override { this->value = std::to_string(val); };
|
||||
|
||||
std::string serialize() const {
|
||||
std::string serialize() const override {
|
||||
return escape_string_cstyle(this->value);
|
||||
};
|
||||
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
bool deserialize(std::string str, bool append = false) override {
|
||||
return unescape_string_cstyle(str, this->value);
|
||||
};
|
||||
};
|
||||
@ -317,9 +351,19 @@ class ConfigOptionFloatOrPercent : public ConfigOptionPercent
|
||||
ConfigOptionFloatOrPercent() : ConfigOptionPercent(0), percent(false) {};
|
||||
ConfigOptionFloatOrPercent(double _value, bool _percent)
|
||||
: ConfigOptionPercent(_value), percent(_percent) {};
|
||||
ConfigOptionFloatOrPercent* clone() const { return new ConfigOptionFloatOrPercent(this->value, this->percent); };
|
||||
ConfigOptionFloatOrPercent* clone() const override { return new ConfigOptionFloatOrPercent(this->value, this->percent); };
|
||||
|
||||
void set(const ConfigOption &option) {
|
||||
double getFloat() const override { throw BadOptionTypeException(); };
|
||||
void setFloat(double val) override {
|
||||
this->value = val;
|
||||
this->percent = false;
|
||||
}
|
||||
void setInt(int val) override {
|
||||
this->value = val;
|
||||
this->percent = false;
|
||||
}
|
||||
|
||||
void set(const ConfigOption &option) override {
|
||||
const ConfigOptionFloatOrPercent* other = dynamic_cast< const ConfigOptionFloatOrPercent* >(&option);
|
||||
if (other != NULL) {
|
||||
this->value = other->value;
|
||||
@ -335,7 +379,7 @@ class ConfigOptionFloatOrPercent : public ConfigOptionPercent
|
||||
}
|
||||
};
|
||||
|
||||
std::string serialize() const {
|
||||
std::string serialize() const override {
|
||||
std::ostringstream ss;
|
||||
ss << this->value;
|
||||
std::string s(ss.str());
|
||||
@ -343,7 +387,7 @@ class ConfigOptionFloatOrPercent : public ConfigOptionPercent
|
||||
return s;
|
||||
};
|
||||
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
bool deserialize(std::string str, bool append = false) override {
|
||||
this->percent = str.find_first_of("%") != std::string::npos;
|
||||
std::istringstream iss(str);
|
||||
iss >> this->value;
|
||||
@ -706,18 +750,29 @@ class ConfigBase
|
||||
virtual ~ConfigBase() {};
|
||||
bool has(const t_config_option_key &opt_key) const;
|
||||
const ConfigOption* option(const t_config_option_key &opt_key) const;
|
||||
const ConfigOption* option_throw(const t_config_option_key &opt_key) const;
|
||||
ConfigOption* option(const t_config_option_key &opt_key, bool create = false);
|
||||
ConfigOption* option_throw(const t_config_option_key &opt_key, bool create = false);
|
||||
template<class T> T* opt(const t_config_option_key &opt_key, bool create = false) {
|
||||
return dynamic_cast<T*>(this->option(opt_key, create));
|
||||
};
|
||||
template<class T> T* opt_throw(const t_config_option_key &opt_key, bool create = false) {
|
||||
return dynamic_cast<T*>(this->option_throw(opt_key, create));
|
||||
};
|
||||
template<class T> const T* opt(const t_config_option_key &opt_key) const {
|
||||
return dynamic_cast<const T*>(this->option(opt_key));
|
||||
};
|
||||
template<class T> const T* opt_throw(const t_config_option_key &opt_key) const {
|
||||
return dynamic_cast<const T*>(this->option_throw(opt_key));
|
||||
};
|
||||
virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) = 0;
|
||||
virtual t_config_option_keys keys() const = 0;
|
||||
void apply(const ConfigBase &other, bool ignore_nonexistent = false);
|
||||
void apply_only(const ConfigBase &other, const t_config_option_keys &opt_keys, bool ignore_nonexistent = false);
|
||||
|
||||
/// Set the given config options to their defaults defined by PrintConfigDef.
|
||||
void set_defaults(const t_config_option_keys &opt_keys);
|
||||
|
||||
/// Apply one configuration store to another.
|
||||
/// @param other configuration store to apply from
|
||||
/// @param opt_keys Vector of string keys to apply one to the other
|
||||
@ -727,14 +782,31 @@ class ConfigBase
|
||||
bool equals(const ConfigBase &other) const;
|
||||
t_config_option_keys diff(const ConfigBase &other) const;
|
||||
std::string serialize(const t_config_option_key &opt_key) const;
|
||||
virtual bool set_deserialize(t_config_option_key opt_key, std::string str, bool append = false);
|
||||
bool set_deserialize(t_config_option_key opt_key, std::string str, bool append = false);
|
||||
void set_deserialize_throw(t_config_option_key opt_key, std::string str, bool append = false);
|
||||
double get_abs_value(const t_config_option_key &opt_key) const;
|
||||
double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const;
|
||||
bool getBool(const t_config_option_key &opt_key, bool default_value = false) const;
|
||||
double getFloat(const t_config_option_key &opt_key, double default_value = 0.0) const;
|
||||
int getInt(const t_config_option_key &opt_key, double default_value = 0) const;
|
||||
std::string getString(const t_config_option_key &opt_key, std::string default_value = "") const;
|
||||
std::vector<std::string> getStrings(const t_config_option_key &opt_key, std::vector<std::string> default_value = std::vector<std::string>()) const;
|
||||
|
||||
bool getBool(const t_config_option_key &opt_key) const;
|
||||
bool getBool(const t_config_option_key &opt_key, bool default_value) const;
|
||||
void setBool(const t_config_option_key &opt_key, bool value);
|
||||
|
||||
double getFloat(const t_config_option_key &opt_key) const;
|
||||
double getFloat(const t_config_option_key &opt_key, double default_value) const;
|
||||
void setFloat(const t_config_option_key &opt_key, double value);
|
||||
|
||||
int getInt(const t_config_option_key &opt_key) const;
|
||||
int getInt(const t_config_option_key &opt_key, int default_value) const;
|
||||
void setInt(const t_config_option_key &opt_key, int value);
|
||||
|
||||
std::string getString(const t_config_option_key &opt_key) const;
|
||||
std::string getString(const t_config_option_key &opt_key, std::string default_value) const;
|
||||
void setString(const t_config_option_key &opt_key, std::string value);
|
||||
|
||||
std::vector<std::string> getStrings(const t_config_option_key &opt_key) const;
|
||||
std::vector<std::string> getStrings(const t_config_option_key &opt_key, std::vector<std::string> default_value) const;
|
||||
void setStrings(const t_config_option_key &opt_key, std::vector<std::string> value);
|
||||
|
||||
void setenv_();
|
||||
void load(const std::string &file);
|
||||
void save(const std::string &file) const;
|
||||
@ -781,27 +853,6 @@ class StaticConfig : public virtual ConfigBase
|
||||
/// virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) = 0;
|
||||
};
|
||||
|
||||
/// Specialization of std::exception to indicate that an unknown config option has been encountered.
|
||||
class ConfigOptionException : public std::exception {
|
||||
public:
|
||||
t_config_option_key opt_key;
|
||||
ConfigOptionException(t_config_option_key _opt_key)
|
||||
: opt_key(_opt_key) {};
|
||||
};
|
||||
class UnknownOptionException : public ConfigOptionException {
|
||||
using ConfigOptionException::ConfigOptionException;
|
||||
};
|
||||
class InvalidOptionException : public ConfigOptionException {
|
||||
using ConfigOptionException::ConfigOptionException;
|
||||
|
||||
public:
|
||||
virtual const char* what() const noexcept {
|
||||
std::string s("Invalid value for option: ");
|
||||
s += this->opt_key;
|
||||
return s.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user