Clean up some header files
[lsnes.git] / settings.cpp
blobb4509097be3f719248eeb7649fd463e33ddd524a
1 #include "settings.hpp"
2 #include "misc.hpp"
3 #include <map>
4 #include <sstream>
5 #include "misc.hpp"
6 #include "command.hpp"
7 #include <iostream>
9 namespace
11 std::map<std::string, setting*>* settings;
13 class set_command : public command
15 public:
16 set_command() throw(std::bad_alloc) : command("set-setting") {}
17 void invoke(const std::string& args, window* win) throw(std::bad_alloc, std::runtime_error)
19 std::string syntax = "Syntax: set-setting <setting> [<value>]";
20 tokensplitter t(args);
21 std::string settingname = t;
22 std::string settingvalue = t.tail();
23 if(settingname == "")
24 throw std::runtime_error("Setting name required.");
25 setting::set(settingname, settingvalue);
26 out(win) << "Setting '" << settingname << "' set to '" << settingvalue << "'" << std::endl;
28 std::string get_short_help() throw(std::bad_alloc) { return "set a setting"; }
29 std::string get_long_help() throw(std::bad_alloc)
31 return "Syntax: set-setting <setting> [<value>]\n"
32 "Set setting to a new value. Omit <value> to set to ''\n";
34 } set_setting;
36 class unset_command : public command
38 public:
39 unset_command() throw(std::bad_alloc) : command("unset-setting") {}
40 void invoke(const std::string& args, window* win) throw(std::bad_alloc, std::runtime_error)
42 std::string syntax = "Syntax: unset-setting <setting>";
43 tokensplitter t(args);
44 std::string settingname = t;
45 if(settingname == "" || t)
46 throw std::runtime_error("Expected setting name and nothing else");
47 setting::blank(settingname);
48 out(win) << "Setting '" << settingname << "' unset" << std::endl;
50 std::string get_short_help() throw(std::bad_alloc) { return "unset a setting"; }
51 std::string get_long_help() throw(std::bad_alloc)
53 return "Syntax: unset-setting <setting>\n"
54 "Try to unset a setting. Note that not all settings can be unset\n";
56 } unset_setting;
58 class get_command : public command
60 public:
61 get_command() throw(std::bad_alloc) : command("get-setting") {}
62 void invoke(const std::string& args, window* win) throw(std::bad_alloc, std::runtime_error)
64 tokensplitter t(args);
65 std::string settingname = t;
66 if(settingname == "" || t.tail() != "")
67 throw std::runtime_error("Expected setting name and nothing else");
68 if(setting::is_set(settingname))
69 out(win) << "Setting '" << settingname << "' has value '" << setting::get(settingname)
70 << "'" << std::endl;
71 else
72 out(win) << "Setting '" << settingname << "' unset" << std::endl;
74 std::string get_short_help() throw(std::bad_alloc) { return "get value of a setting"; }
75 std::string get_long_help() throw(std::bad_alloc)
77 return "Syntax: get-setting <setting>\n"
78 "Show value of setting\n";
80 } get_setting;
82 class shsettings_command : public command
84 public:
85 shsettings_command() throw(std::bad_alloc) : command("show-settings") {}
86 void invoke(const std::string& args, window* win) throw(std::bad_alloc, std::runtime_error)
88 if(args != "")
89 throw std::runtime_error("This command does not take arguments");
90 setting::print_all(win);
92 std::string get_short_help() throw(std::bad_alloc) { return "Show value of all settings"; }
93 std::string get_long_help() throw(std::bad_alloc)
95 return "Syntax: show-settings\n"
96 "Show value of all settings\n";
98 } sh_setting;
101 setting::setting(const std::string& name) throw(std::bad_alloc)
103 if(!settings)
104 settings = new std::map<std::string, setting*>();
105 (*settings)[settingname = name] = this;
108 setting::~setting() throw()
110 if(!settings)
111 return;
112 settings->erase(settingname);
115 void setting::set(const std::string& _setting, const std::string& value) throw(std::bad_alloc, std::runtime_error)
117 if(!settings || !settings->count(_setting))
118 throw std::runtime_error("No such setting '" + _setting + "'");
119 try {
120 (*settings)[_setting]->set(value);
121 } catch(std::bad_alloc& e) {
122 throw;
123 } catch(std::exception& e) {
124 throw std::runtime_error("Can't set setting '" + _setting + "': " + e.what());
128 void setting::blank(const std::string& _setting) throw(std::bad_alloc, std::runtime_error)
130 if(!settings || !settings->count(_setting))
131 throw std::runtime_error("No such setting '" + _setting + "'");
132 try {
133 (*settings)[_setting]->blank();
134 } catch(std::bad_alloc& e) {
135 throw;
136 } catch(std::exception& e) {
137 throw std::runtime_error("Can't blank setting '" + _setting + "': " + e.what());
141 std::string setting::get(const std::string& _setting) throw(std::bad_alloc, std::runtime_error)
143 if(!settings || !settings->count(_setting))
144 throw std::runtime_error("No such setting '" + _setting + "'");
145 return (*settings)[_setting]->get();
148 bool setting::is_set(const std::string& _setting) throw(std::bad_alloc, std::runtime_error)
150 if(!settings || !settings->count(_setting))
151 throw std::runtime_error("No such setting '" + _setting + "'");
152 return (*settings)[_setting]->is_set();
155 void setting::print_all(window* win) throw(std::bad_alloc)
157 if(!settings)
158 return;
159 for(auto i = settings->begin(); i != settings->end(); i++) {
160 if(!i->second->is_set())
161 out(win) << i->first << ": (unset)" << std::endl;
162 else
163 out(win) << i->first << ": " << i->second->get() << std::endl;
167 numeric_setting::numeric_setting(const std::string& sname, int32_t minv, int32_t maxv, int32_t dflt)
168 throw(std::bad_alloc)
169 : setting(sname)
171 minimum = minv;
172 maximum = maxv;
173 value = dflt;
176 void numeric_setting::blank() throw(std::bad_alloc, std::runtime_error)
178 throw std::runtime_error("This setting can't be blanked");
181 bool numeric_setting::is_set() throw()
183 return true;
186 void numeric_setting::set(const std::string& _value) throw(std::bad_alloc, std::runtime_error)
188 int32_t v = parse_value<int32_t>(_value);
189 if(v < minimum || v > maximum) {
190 std::ostringstream x;
191 x << "Value out of range (" << minimum << " - " << maximum << ")";
192 throw std::runtime_error(x.str());
194 value = v;
197 std::string numeric_setting::get() throw(std::bad_alloc)
199 std::ostringstream x;
200 x << value;
201 return x.str();
204 numeric_setting::operator int32_t() throw()
206 return value;
209 boolean_setting::boolean_setting(const std::string& sname, bool dflt) throw(std::bad_alloc)
210 : setting(sname)
212 value = dflt;
214 void boolean_setting::blank() throw(std::bad_alloc, std::runtime_error)
216 throw std::runtime_error("This setting can't be unset");
219 bool boolean_setting::is_set() throw()
221 return true;
224 void boolean_setting::set(const std::string& v) throw(std::bad_alloc, std::runtime_error)
226 if(v == "true" || v == "yes" || v == "on" || v == "1" || v == "enable" || v == "enabled")
227 value = true;
228 else if(v == "false" || v == "no" || v == "off" || v == "0" || v == "disable" || v == "disabled")
229 value = false;
230 else
231 throw std::runtime_error("Invalid value for boolean setting");
233 std::string boolean_setting::get() throw(std::bad_alloc)
235 if(value)
236 return "true";
237 else
238 return "false";
241 boolean_setting::operator bool() throw()
243 return value;