Support enum config options

This commit is contained in:
Alessandro Ranellucci 2013-12-21 10:46:43 +01:00
parent f274287b0e
commit bb5bbe191f
3 changed files with 58 additions and 31 deletions

View File

@ -129,6 +129,8 @@ DynamicConfig::option(const t_config_option_key opt_key, bool create) {
opt = new ConfigOptionPoint (); opt = new ConfigOptionPoint ();
} else if (Options[opt_key].type == coBool) { } else if (Options[opt_key].type == coBool) {
opt = new ConfigOptionBool (); opt = new ConfigOptionBool ();
} else if (Options[opt_key].type == coEnumGCodeFlavor) {
opt = new ConfigOptionEnumGCodeFlavor ();
} else { } else {
throw "Unknown option type"; throw "Unknown option type";
} }

View File

@ -6,7 +6,7 @@
#include <sstream> #include <sstream>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <iostream>; #include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
#include "Point.hpp" #include "Point.hpp"
@ -162,33 +162,36 @@ enum GCodeFlavor {
gcfRepRap, gcfTeacup, gcfMakerWare, gcfSailfish, gcfMach3, gcfNoExtrusion, gcfRepRap, gcfTeacup, gcfMakerWare, gcfSailfish, gcfMach3, gcfNoExtrusion,
}; };
class ConfigOptionGCodeFlavor : public ConfigOption template <class T>
class ConfigOptionEnum : public ConfigOption
{ {
public: public:
GCodeFlavor value; T value;
ConfigOptionGCodeFlavor() : value(gcfRepRap) {};
operator GCodeFlavor() const { return this->value; }; operator T() const { return this->value; };
std::string serialize() { std::string serialize();
if (this->value == gfcRepRap) { return std::string("reprap"); } void deserialize(std::string str);
else if (this->value == gcfTeacup) { return std::string("teacup"); } static std::map<std::string,T> get_enum_values();
else if (this->value == gcfMakerWare) { return std::string("makerware"); }
else if (this->value == gcfSailfish) { return std::string("sailfish"); }
else if (this->value == gcfMach3) { return std::string("mach3"); }
else if (this->value == gcfNoExtrusion) { return std::string("no-extrusion"); }
};
void deserialize(std::string str) {
if (str.compare("reprap") == 0) { this->value = gfcRepRap; }
else if (str.compare("teacup") == 0) { this->value = gcfTeacup; }
else if (str.compare("makerware") == 0) { this->value = gcfMakerWare; }
else if (str.compare("sailfish") == 0) { this->value = gcfSailfish; }
else if (str.compare("mach3") == 0) { this->value = gcfMach3; }
else if (str.compare("no-extrusion") == 0) { this->value = gcfNoExtrusion; }
};
}; };
template <class T>
std::string ConfigOptionEnum<T>::serialize() {
typename std::map<std::string,T> enum_keys_map = ConfigOptionEnum<T>::get_enum_values();
for (typename std::map<std::string,T>::iterator it = enum_keys_map.begin(); it != enum_keys_map.end(); ++it) {
if (it->second == this->value) return it->first;
}
return "";
};
template <class T>
void ConfigOptionEnum<T>::deserialize(std::string str) {
typename std::map<std::string,T> enum_keys_map = ConfigOptionEnum<T>::get_enum_values();
assert(enum_keys_map.count(str) > 0);
this->value = enum_keys_map[str];
};
typedef ConfigOptionEnum<GCodeFlavor> ConfigOptionEnumGCodeFlavor;
enum ConfigOptionType { enum ConfigOptionType {
coFloat, coFloat,
coInt, coInt,
@ -196,7 +199,7 @@ enum ConfigOptionType {
coFloatOrPercent, coFloatOrPercent,
coPoint, coPoint,
coBool, coBool,
coGCodeFlavor, coEnumGCodeFlavor,
}; };
class ConfigOptionDef class ConfigOptionDef
@ -260,6 +263,7 @@ class FullConfig : public StaticConfig
ConfigOptionPoint print_center; ConfigOptionPoint print_center;
ConfigOptionString notes; ConfigOptionString notes;
ConfigOptionBool use_relative_e_distances; ConfigOptionBool use_relative_e_distances;
ConfigOptionEnumGCodeFlavor gcode_flavor;
ConfigOption* option(const t_config_option_key opt_key, bool create = false) { ConfigOption* option(const t_config_option_key opt_key, bool create = false) {
assert(!create); // can't create options in StaticConfig assert(!create); // can't create options in StaticConfig
@ -270,6 +274,7 @@ class FullConfig : public StaticConfig
if (opt_key == "print_center") return &this->print_center; if (opt_key == "print_center") return &this->print_center;
if (opt_key == "notes") return &this->notes; if (opt_key == "notes") return &this->notes;
if (opt_key == "use_relative_e_distances") return &this->use_relative_e_distances; if (opt_key == "use_relative_e_distances") return &this->use_relative_e_distances;
if (opt_key == "gcode_flavor") return &this->gcode_flavor;
return NULL; return NULL;
}; };
}; };
@ -295,9 +300,24 @@ static t_optiondef_map _build_optiondef_map () {
Options["use_relative_e_distances"].type = coBool; Options["use_relative_e_distances"].type = coBool;
Options["gcode_flavor"].type = coEnumGCodeFlavor;
return Options; return Options;
} }
// we declare this as inline to keep it in this file along with all other option definitions
template<> inline std::map<std::string,GCodeFlavor> ConfigOptionEnum<GCodeFlavor>::get_enum_values() {
std::map<std::string,GCodeFlavor> keys_map;
keys_map["reprap"] = gcfRepRap;
keys_map["teacup"] = gcfTeacup;
keys_map["makerware"] = gcfMakerWare;
keys_map["sailfish"] = gcfSailfish;
keys_map["mach3"] = gcfMach3;
keys_map["no-extrusion"] = gcfNoExtrusion;
return keys_map;
}
static FullConfig _build_default_config () { static FullConfig _build_default_config () {
FullConfig defconf; FullConfig defconf;
@ -309,6 +329,7 @@ static FullConfig _build_default_config () {
defconf.print_center.point = Pointf(100,100); defconf.print_center.point = Pointf(100,100);
defconf.notes.value = ""; defconf.notes.value = "";
defconf.use_relative_e_distances.value = false; defconf.use_relative_e_distances.value = false;
defconf.gcode_flavor.value = gcfRepRap;
return defconf; return defconf;
} }

View File

@ -4,7 +4,7 @@ use strict;
use warnings; use warnings;
use Slic3r::XS; use Slic3r::XS;
use Test::More tests => 18; use Test::More tests => 20;
{ {
my $config = Slic3r::Config->new; my $config = Slic3r::Config->new;
@ -44,6 +44,10 @@ use Test::More tests => 18;
$config->set('use_relative_e_distances', 1); $config->set('use_relative_e_distances', 1);
is $config->get('use_relative_e_distances'), 1, 'set/get bool'; is $config->get('use_relative_e_distances'), 1, 'set/get bool';
is $config->serialize('use_relative_e_distances'), '1', 'serialize bool'; is $config->serialize('use_relative_e_distances'), '1', 'serialize bool';
$config->set('gcode_flavor', 'teacup');
is $config->get('gcode_flavor'), 'teacup', 'set/get enum';
is $config->serialize('gcode_flavor'), 'teacup', 'serialize enum';
} }
__END__ __END__