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 ();
} else if (Options[opt_key].type == coBool) {
opt = new ConfigOptionBool ();
} else if (Options[opt_key].type == coEnumGCodeFlavor) {
opt = new ConfigOptionEnumGCodeFlavor ();
} else {
throw "Unknown option type";
}

View File

@ -6,7 +6,7 @@
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <iostream>;
#include <iostream>
#include <string>
#include <vector>
#include "Point.hpp"
@ -162,33 +162,36 @@ enum GCodeFlavor {
gcfRepRap, gcfTeacup, gcfMakerWare, gcfSailfish, gcfMach3, gcfNoExtrusion,
};
class ConfigOptionGCodeFlavor : public ConfigOption
template <class T>
class ConfigOptionEnum : public ConfigOption
{
public:
GCodeFlavor value;
ConfigOptionGCodeFlavor() : value(gcfRepRap) {};
T value;
operator GCodeFlavor() const { return this->value; };
operator T() const { return this->value; };
std::string serialize() {
if (this->value == gfcRepRap) { return std::string("reprap"); }
else if (this->value == gcfTeacup) { return std::string("teacup"); }
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; }
};
std::string serialize();
void deserialize(std::string str);
static std::map<std::string,T> get_enum_values();
};
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 {
coFloat,
coInt,
@ -196,7 +199,7 @@ enum ConfigOptionType {
coFloatOrPercent,
coPoint,
coBool,
coGCodeFlavor,
coEnumGCodeFlavor,
};
class ConfigOptionDef
@ -253,13 +256,14 @@ class StaticConfig : public ConfigBase
class FullConfig : public StaticConfig
{
public:
ConfigOptionFloat layer_height;
ConfigOptionFloatOrPercent first_layer_height;
ConfigOptionInt perimeters;
ConfigOptionString extrusion_axis;
ConfigOptionPoint print_center;
ConfigOptionString notes;
ConfigOptionBool use_relative_e_distances;
ConfigOptionFloat layer_height;
ConfigOptionFloatOrPercent first_layer_height;
ConfigOptionInt perimeters;
ConfigOptionString extrusion_axis;
ConfigOptionPoint print_center;
ConfigOptionString notes;
ConfigOptionBool use_relative_e_distances;
ConfigOptionEnumGCodeFlavor gcode_flavor;
ConfigOption* option(const t_config_option_key opt_key, bool create = false) {
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 == "notes") return &this->notes;
if (opt_key == "use_relative_e_distances") return &this->use_relative_e_distances;
if (opt_key == "gcode_flavor") return &this->gcode_flavor;
return NULL;
};
};
@ -295,9 +300,24 @@ static t_optiondef_map _build_optiondef_map () {
Options["use_relative_e_distances"].type = coBool;
Options["gcode_flavor"].type = coEnumGCodeFlavor;
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 () {
FullConfig defconf;
@ -309,6 +329,7 @@ static FullConfig _build_default_config () {
defconf.print_center.point = Pointf(100,100);
defconf.notes.value = "";
defconf.use_relative_e_distances.value = false;
defconf.gcode_flavor.value = gcfRepRap;
return defconf;
}

View File

@ -4,7 +4,7 @@ use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 18;
use Test::More tests => 20;
{
my $config = Slic3r::Config->new;
@ -44,6 +44,10 @@ use Test::More tests => 18;
$config->set('use_relative_e_distances', 1);
is $config->get('use_relative_e_distances'), 1, 'set/get 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__