~ubuntu-branches/ubuntu/utopic/slic3r/utopic

« back to all changes in this revision

Viewing changes to xs/src/Config.cpp

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2014-06-17 01:27:26 UTC
  • Revision ID: package-import@ubuntu.com-20140617012726-2wrs4zdo251nr4vg
Tags: upstream-1.1.4+dfsg
ImportĀ upstreamĀ versionĀ 1.1.4+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "Config.hpp"
 
2
 
 
3
namespace Slic3r {
 
4
 
 
5
bool
 
6
ConfigBase::has(const t_config_option_key opt_key) {
 
7
    return (this->option(opt_key, false) != NULL);
 
8
}
 
9
 
 
10
void
 
11
ConfigBase::apply(const ConfigBase &other, bool ignore_nonexistent) {
 
12
    // get list of option keys to apply
 
13
    t_config_option_keys opt_keys;
 
14
    other.keys(&opt_keys);
 
15
    
 
16
    // loop through options and apply them
 
17
    for (t_config_option_keys::const_iterator it = opt_keys.begin(); it != opt_keys.end(); ++it) {
 
18
        ConfigOption* my_opt = this->option(*it, true);
 
19
        if (my_opt == NULL) {
 
20
            if (ignore_nonexistent == false) throw "Attempt to apply non-existent option";
 
21
            continue;
 
22
        }
 
23
        
 
24
        // not the most efficient way, but easier than casting pointers to subclasses
 
25
        bool res = my_opt->deserialize( other.option(*it)->serialize() );
 
26
        if (!res) CONFESS("Unexpected failure when deserializing serialized value");
 
27
    }
 
28
}
 
29
 
 
30
std::string
 
31
ConfigBase::serialize(const t_config_option_key opt_key) {
 
32
    ConfigOption* opt = this->option(opt_key);
 
33
    assert(opt != NULL);
 
34
    return opt->serialize();
 
35
}
 
36
 
 
37
bool
 
38
ConfigBase::set_deserialize(const t_config_option_key opt_key, std::string str) {
 
39
    if (this->def->count(opt_key) == 0) throw "Calling set_deserialize() on unknown option";
 
40
    ConfigOptionDef* optdef = &(*this->def)[opt_key];
 
41
    if (!optdef->shortcut.empty()) {
 
42
        for (std::vector<t_config_option_key>::iterator it = optdef->shortcut.begin(); it != optdef->shortcut.end(); ++it) {
 
43
            if (!this->set_deserialize(*it, str)) return false;
 
44
        }
 
45
        return true;
 
46
    }
 
47
    
 
48
    ConfigOption* opt = this->option(opt_key, true);
 
49
    assert(opt != NULL);
 
50
    return opt->deserialize(str);
 
51
}
 
52
 
 
53
double
 
54
ConfigBase::get_abs_value(const t_config_option_key opt_key) {
 
55
    ConfigOption* opt = this->option(opt_key, false);
 
56
    if (ConfigOptionFloatOrPercent* optv = dynamic_cast<ConfigOptionFloatOrPercent*>(opt)) {
 
57
        // get option definition
 
58
        assert(this->def->count(opt_key) != 0);
 
59
        ConfigOptionDef* def = &(*this->def)[opt_key];
 
60
        
 
61
        // compute absolute value over the absolute value of the base option
 
62
        return optv->get_abs_value(this->get_abs_value(def->ratio_over));
 
63
    } else if (ConfigOptionFloat* optv = dynamic_cast<ConfigOptionFloat*>(opt)) {
 
64
        return optv->value;
 
65
    } else {
 
66
        throw "Not a valid option type for get_abs_value()";
 
67
    }
 
68
}
 
69
 
 
70
double
 
71
ConfigBase::get_abs_value(const t_config_option_key opt_key, double ratio_over) {
 
72
    // get stored option value
 
73
    ConfigOptionFloatOrPercent* opt = dynamic_cast<ConfigOptionFloatOrPercent*>(this->option(opt_key));
 
74
    assert(opt != NULL);
 
75
    
 
76
    // compute absolute value
 
77
    return opt->get_abs_value(ratio_over);
 
78
}
 
79
 
 
80
#ifdef SLIC3RXS
 
81
SV*
 
82
ConfigBase::as_hash() {
 
83
    HV* hv = newHV();
 
84
    
 
85
    t_config_option_keys opt_keys;
 
86
    this->keys(&opt_keys);
 
87
    
 
88
    for (t_config_option_keys::const_iterator it = opt_keys.begin(); it != opt_keys.end(); ++it)
 
89
        (void)hv_store( hv, it->c_str(), it->length(), this->get(*it), 0 );
 
90
    
 
91
    return newRV_noinc((SV*)hv);
 
92
}
 
93
 
 
94
SV*
 
95
ConfigBase::get(t_config_option_key opt_key) {
 
96
    ConfigOption* opt = this->option(opt_key);
 
97
    if (opt == NULL) return &PL_sv_undef;
 
98
    if (ConfigOptionFloat* optv = dynamic_cast<ConfigOptionFloat*>(opt)) {
 
99
        return newSVnv(optv->value);
 
100
    } else if (ConfigOptionPercent* optv = dynamic_cast<ConfigOptionPercent*>(opt)) {
 
101
        return newSVnv(optv->value);
 
102
    } else if (ConfigOptionFloats* optv = dynamic_cast<ConfigOptionFloats*>(opt)) {
 
103
        AV* av = newAV();
 
104
        av_fill(av, optv->values.size()-1);
 
105
        for (std::vector<double>::iterator it = optv->values.begin(); it != optv->values.end(); ++it)
 
106
            av_store(av, it - optv->values.begin(), newSVnv(*it));
 
107
        return newRV_noinc((SV*)av);
 
108
    } else if (ConfigOptionInt* optv = dynamic_cast<ConfigOptionInt*>(opt)) {
 
109
        return newSViv(optv->value);
 
110
    } else if (ConfigOptionInts* optv = dynamic_cast<ConfigOptionInts*>(opt)) {
 
111
        AV* av = newAV();
 
112
        av_fill(av, optv->values.size()-1);
 
113
        for (std::vector<int>::iterator it = optv->values.begin(); it != optv->values.end(); ++it)
 
114
            av_store(av, it - optv->values.begin(), newSViv(*it));
 
115
        return newRV_noinc((SV*)av);
 
116
    } else if (ConfigOptionString* optv = dynamic_cast<ConfigOptionString*>(opt)) {
 
117
        // we don't serialize() because that would escape newlines
 
118
        return newSVpvn_utf8(optv->value.c_str(), optv->value.length(), true);
 
119
    } else if (ConfigOptionStrings* optv = dynamic_cast<ConfigOptionStrings*>(opt)) {
 
120
        AV* av = newAV();
 
121
        av_fill(av, optv->values.size()-1);
 
122
        for (std::vector<std::string>::iterator it = optv->values.begin(); it != optv->values.end(); ++it)
 
123
            av_store(av, it - optv->values.begin(), newSVpvn_utf8(it->c_str(), it->length(), true));
 
124
        return newRV_noinc((SV*)av);
 
125
    } else if (ConfigOptionPoint* optv = dynamic_cast<ConfigOptionPoint*>(opt)) {
 
126
        return optv->point.to_SV_pureperl();
 
127
    } else if (ConfigOptionPoints* optv = dynamic_cast<ConfigOptionPoints*>(opt)) {
 
128
        AV* av = newAV();
 
129
        av_fill(av, optv->values.size()-1);
 
130
        for (Pointfs::iterator it = optv->values.begin(); it != optv->values.end(); ++it)
 
131
            av_store(av, it - optv->values.begin(), it->to_SV_pureperl());
 
132
        return newRV_noinc((SV*)av);
 
133
    } else if (ConfigOptionBool* optv = dynamic_cast<ConfigOptionBool*>(opt)) {
 
134
        return newSViv(optv->value ? 1 : 0);
 
135
    } else if (ConfigOptionBools* optv = dynamic_cast<ConfigOptionBools*>(opt)) {
 
136
        AV* av = newAV();
 
137
        av_fill(av, optv->values.size()-1);
 
138
        for (std::vector<bool>::iterator it = optv->values.begin(); it != optv->values.end(); ++it)
 
139
            av_store(av, it - optv->values.begin(), newSViv(*it ? 1 : 0));
 
140
        return newRV_noinc((SV*)av);
 
141
    } else {
 
142
        std::string serialized = opt->serialize();
 
143
        return newSVpvn_utf8(serialized.c_str(), serialized.length(), true);
 
144
    }
 
145
}
 
146
 
 
147
SV*
 
148
ConfigBase::get_at(t_config_option_key opt_key, size_t i) {
 
149
    ConfigOption* opt = this->option(opt_key);
 
150
    if (opt == NULL) return &PL_sv_undef;
 
151
    
 
152
    if (ConfigOptionFloats* optv = dynamic_cast<ConfigOptionFloats*>(opt)) {
 
153
        return newSVnv(optv->get_at(i));
 
154
    } else if (ConfigOptionInts* optv = dynamic_cast<ConfigOptionInts*>(opt)) {
 
155
        return newSViv(optv->get_at(i));
 
156
    } else if (ConfigOptionStrings* optv = dynamic_cast<ConfigOptionStrings*>(opt)) {
 
157
        // we don't serialize() because that would escape newlines
 
158
        std::string val = optv->get_at(i);
 
159
        return newSVpvn_utf8(val.c_str(), val.length(), true);
 
160
    } else if (ConfigOptionPoints* optv = dynamic_cast<ConfigOptionPoints*>(opt)) {
 
161
        return optv->get_at(i).to_SV_pureperl();
 
162
    } else if (ConfigOptionBools* optv = dynamic_cast<ConfigOptionBools*>(opt)) {
 
163
        return newSViv(optv->get_at(i) ? 1 : 0);
 
164
    } else {
 
165
        return &PL_sv_undef;
 
166
    }
 
167
}
 
168
 
 
169
bool
 
170
ConfigBase::set(t_config_option_key opt_key, SV* value) {
 
171
    ConfigOption* opt = this->option(opt_key, true);
 
172
    if (opt == NULL) CONFESS("Trying to set non-existing option");
 
173
    
 
174
    if (ConfigOptionFloat* optv = dynamic_cast<ConfigOptionFloat*>(opt)) {
 
175
        if (!looks_like_number(value)) return false;
 
176
        optv->value = SvNV(value);
 
177
    } else if (ConfigOptionFloats* optv = dynamic_cast<ConfigOptionFloats*>(opt)) {
 
178
        std::vector<double> values;
 
179
        AV* av = (AV*)SvRV(value);
 
180
        const size_t len = av_len(av)+1;
 
181
        for (size_t i = 0; i < len; i++) {
 
182
            SV** elem = av_fetch(av, i, 0);
 
183
            if (elem == NULL || !looks_like_number(*elem)) return false;
 
184
            values.push_back(SvNV(*elem));
 
185
        }
 
186
        optv->values = values;
 
187
    } else if (ConfigOptionInt* optv = dynamic_cast<ConfigOptionInt*>(opt)) {
 
188
        if (!looks_like_number(value)) return false;
 
189
        optv->value = SvIV(value);
 
190
    } else if (ConfigOptionInts* optv = dynamic_cast<ConfigOptionInts*>(opt)) {
 
191
        std::vector<int> values;
 
192
        AV* av = (AV*)SvRV(value);
 
193
        const size_t len = av_len(av)+1;
 
194
        for (size_t i = 0; i < len; i++) {
 
195
            SV** elem = av_fetch(av, i, 0);
 
196
            if (elem == NULL || !looks_like_number(*elem)) return false;
 
197
            values.push_back(SvIV(*elem));
 
198
        }
 
199
        optv->values = values;
 
200
    } else if (ConfigOptionString* optv = dynamic_cast<ConfigOptionString*>(opt)) {
 
201
        optv->value = std::string(SvPV_nolen(value), SvCUR(value));
 
202
    } else if (ConfigOptionStrings* optv = dynamic_cast<ConfigOptionStrings*>(opt)) {
 
203
        optv->values.clear();
 
204
        AV* av = (AV*)SvRV(value);
 
205
        const size_t len = av_len(av)+1;
 
206
        for (size_t i = 0; i < len; i++) {
 
207
            SV** elem = av_fetch(av, i, 0);
 
208
            if (elem == NULL) return false;
 
209
            optv->values.push_back(std::string(SvPV_nolen(*elem), SvCUR(*elem)));
 
210
        }
 
211
    } else if (ConfigOptionPoint* optv = dynamic_cast<ConfigOptionPoint*>(opt)) {
 
212
        return optv->point.from_SV(value);
 
213
    } else if (ConfigOptionPoints* optv = dynamic_cast<ConfigOptionPoints*>(opt)) {
 
214
        std::vector<Pointf> values;
 
215
        AV* av = (AV*)SvRV(value);
 
216
        const size_t len = av_len(av)+1;
 
217
        for (size_t i = 0; i < len; i++) {
 
218
            SV** elem = av_fetch(av, i, 0);
 
219
            Pointf point;
 
220
            if (elem == NULL || !point.from_SV(*elem)) return false;
 
221
            values.push_back(point);
 
222
        }
 
223
        optv->values = values;
 
224
    } else if (ConfigOptionBool* optv = dynamic_cast<ConfigOptionBool*>(opt)) {
 
225
        optv->value = SvTRUE(value);
 
226
    } else if (ConfigOptionBools* optv = dynamic_cast<ConfigOptionBools*>(opt)) {
 
227
        optv->values.clear();
 
228
        AV* av = (AV*)SvRV(value);
 
229
        const size_t len = av_len(av)+1;
 
230
        for (size_t i = 0; i < len; i++) {
 
231
            SV** elem = av_fetch(av, i, 0);
 
232
            if (elem == NULL) return false;
 
233
            optv->values.push_back(SvTRUE(*elem));
 
234
        }
 
235
    } else {
 
236
        if (!opt->deserialize( std::string(SvPV_nolen(value)) )) return false;
 
237
    }
 
238
    return true;
 
239
}
 
240
 
 
241
/* This method is implemented as a workaround for this typemap bug:
 
242
   https://rt.cpan.org/Public/Bug/Display.html?id=94110 */
 
243
bool
 
244
ConfigBase::set_deserialize(const t_config_option_key opt_key, SV* str) {
 
245
    size_t len;
 
246
    const char * c = SvPV(str, len);
 
247
    std::string value(c, len);
 
248
    
 
249
    return this->set_deserialize(opt_key, value);
 
250
}
 
251
#endif
 
252
 
 
253
DynamicConfig& DynamicConfig::operator= (DynamicConfig other)
 
254
{
 
255
    this->swap(other);
 
256
    return *this;
 
257
}
 
258
 
 
259
void
 
260
DynamicConfig::swap(DynamicConfig &other)
 
261
{
 
262
    std::swap(this->options, other.options);
 
263
}
 
264
 
 
265
DynamicConfig::~DynamicConfig () {
 
266
    for (t_options_map::iterator it = this->options.begin(); it != this->options.end(); ++it) {
 
267
        ConfigOption* opt = it->second;
 
268
        if (opt != NULL) delete opt;
 
269
    }
 
270
}
 
271
 
 
272
DynamicConfig::DynamicConfig (const DynamicConfig& other) {
 
273
    this->def = other.def;
 
274
    this->apply(other, false);
 
275
}
 
276
 
 
277
ConfigOption*
 
278
DynamicConfig::option(const t_config_option_key opt_key, bool create) {
 
279
    if (this->options.count(opt_key) == 0) {
 
280
        if (create) {
 
281
            ConfigOptionDef* optdef = &(*this->def)[opt_key];
 
282
            ConfigOption* opt;
 
283
            if (optdef->type == coFloat) {
 
284
                opt = new ConfigOptionFloat ();
 
285
            } else if (optdef->type == coFloats) {
 
286
                opt = new ConfigOptionFloats ();
 
287
            } else if (optdef->type == coInt) {
 
288
                opt = new ConfigOptionInt ();
 
289
            } else if (optdef->type == coInts) {
 
290
                opt = new ConfigOptionInts ();
 
291
            } else if (optdef->type == coString) {
 
292
                opt = new ConfigOptionString ();
 
293
            } else if (optdef->type == coStrings) {
 
294
                opt = new ConfigOptionStrings ();
 
295
            } else if (optdef->type == coPercent) {
 
296
                opt = new ConfigOptionPercent ();
 
297
            } else if (optdef->type == coFloatOrPercent) {
 
298
                opt = new ConfigOptionFloatOrPercent ();
 
299
            } else if (optdef->type == coPoint) {
 
300
                opt = new ConfigOptionPoint ();
 
301
            } else if (optdef->type == coPoints) {
 
302
                opt = new ConfigOptionPoints ();
 
303
            } else if (optdef->type == coBool) {
 
304
                opt = new ConfigOptionBool ();
 
305
            } else if (optdef->type == coBools) {
 
306
                opt = new ConfigOptionBools ();
 
307
            } else if (optdef->type == coEnum) {
 
308
                ConfigOptionEnumGeneric* optv = new ConfigOptionEnumGeneric ();
 
309
                optv->keys_map = &optdef->enum_keys_map;
 
310
                opt = static_cast<ConfigOption*>(optv);
 
311
            } else {
 
312
                throw "Unknown option type";
 
313
            }
 
314
            this->options[opt_key] = opt;
 
315
            return opt;
 
316
        } else {
 
317
            return NULL;
 
318
        }
 
319
    }
 
320
    return this->options[opt_key];
 
321
}
 
322
 
 
323
template<class T>
 
324
T*
 
325
DynamicConfig::opt(const t_config_option_key opt_key, bool create) {
 
326
    return dynamic_cast<T*>(this->option(opt_key, create));
 
327
}
 
328
template ConfigOptionInt* DynamicConfig::opt<ConfigOptionInt>(const t_config_option_key opt_key, bool create);
 
329
template ConfigOptionBool* DynamicConfig::opt<ConfigOptionBool>(const t_config_option_key opt_key, bool create);
 
330
template ConfigOptionBools* DynamicConfig::opt<ConfigOptionBools>(const t_config_option_key opt_key, bool create);
 
331
 
 
332
const ConfigOption*
 
333
DynamicConfig::option(const t_config_option_key opt_key) const {
 
334
    return const_cast<DynamicConfig*>(this)->option(opt_key, false);
 
335
}
 
336
 
 
337
void
 
338
DynamicConfig::keys(t_config_option_keys *keys) const {
 
339
    for (t_options_map::const_iterator it = this->options.begin(); it != this->options.end(); ++it)
 
340
        keys->push_back(it->first);
 
341
}
 
342
 
 
343
void
 
344
DynamicConfig::erase(const t_config_option_key opt_key) {
 
345
    this->options.erase(opt_key);
 
346
}
 
347
 
 
348
void
 
349
StaticConfig::keys(t_config_option_keys *keys) const {
 
350
    for (t_optiondef_map::const_iterator it = this->def->begin(); it != this->def->end(); ++it) {
 
351
        const ConfigOption* opt = this->option(it->first);
 
352
        if (opt != NULL) keys->push_back(it->first);
 
353
    }
 
354
}
 
355
 
 
356
const ConfigOption*
 
357
StaticConfig::option(const t_config_option_key opt_key) const
 
358
{
 
359
    return const_cast<StaticConfig*>(this)->option(opt_key, false);
 
360
}
 
361
 
 
362
#ifdef SLIC3RXS
 
363
bool
 
364
StaticConfig::set(t_config_option_key opt_key, SV* value) {
 
365
    ConfigOptionDef* optdef = &(*this->def)[opt_key];
 
366
    if (!optdef->shortcut.empty()) {
 
367
        for (std::vector<t_config_option_key>::iterator it = optdef->shortcut.begin(); it != optdef->shortcut.end(); ++it) {
 
368
            if (!this->set(*it, value)) return false;
 
369
        }
 
370
        return true;
 
371
    }
 
372
    
 
373
    return static_cast<ConfigBase*>(this)->set(opt_key, value);
 
374
}
 
375
#endif
 
376
 
 
377
}