More random cleanups
[lsnes.git] / settings.cpp
blob6bb1bea8f27f49ac190eb2f68aba3e72a7be00fb
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 function_ptr_command set_setting("set-setting", "set a setting",
14 "Syntax: set-setting <setting> [<value>]\nSet setting to a new value. Omit <value> to set to ''\n",
15 [](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
16 std::string syntax = "Syntax: set-setting <setting> [<value>]";
17 tokensplitter t(args);
18 std::string settingname = t;
19 std::string settingvalue = t.tail();
20 if(settingname == "")
21 throw std::runtime_error("Setting name required.");
22 setting::set(settingname, settingvalue);
23 messages << "Setting '" << settingname << "' set to '" << settingvalue << "'"
24 << std::endl;
25 });
27 function_ptr_command unset_setting("unset-setting", "unset a setting",
28 "Syntax: unset-setting <setting>\nTry to unset a setting. Note that not all settings can be unset\n",
29 [](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
30 std::string syntax = "Syntax: unset-setting <setting>";
31 tokensplitter t(args);
32 std::string settingname = t;
33 if(settingname == "" || t)
34 throw std::runtime_error("Expected setting name and nothing else");
35 setting::blank(settingname);
36 messages << "Setting '" << settingname << "' unset" << std::endl;
37 });
39 function_ptr_command get_command("get-setting", "get value of a setting",
40 "Syntax: get-setting <setting>\nShow value of setting\n",
41 [](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
42 tokensplitter t(args);
43 std::string settingname = t;
44 if(settingname == "" || t.tail() != "")
45 throw std::runtime_error("Expected setting name and nothing else");
46 if(setting::is_set(settingname))
47 messages << "Setting '" << settingname << "' has value '"
48 << setting::get(settingname) << "'" << std::endl;
49 else
50 messages << "Setting '" << settingname << "' unset" << std::endl;
51 });
53 function_ptr_command show_settings("show-settings", "Show values of all settings",
54 "Syntax: show-settings\nShow value of all settings\n",
55 [](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
56 if(args != "")
57 throw std::runtime_error("This command does not take arguments");
58 setting::print_all();
59 });
62 setting::setting(const std::string& name) throw(std::bad_alloc)
64 if(!settings)
65 settings = new std::map<std::string, setting*>();
66 (*settings)[settingname = name] = this;
69 setting::~setting() throw()
71 if(!settings)
72 return;
73 settings->erase(settingname);
76 void setting::set(const std::string& _setting, const std::string& value) throw(std::bad_alloc, std::runtime_error)
78 if(!settings || !settings->count(_setting))
79 throw std::runtime_error("No such setting '" + _setting + "'");
80 try {
81 (*settings)[_setting]->set(value);
82 } catch(std::bad_alloc& e) {
83 throw;
84 } catch(std::exception& e) {
85 throw std::runtime_error("Can't set setting '" + _setting + "': " + e.what());
89 void setting::blank(const std::string& _setting) throw(std::bad_alloc, std::runtime_error)
91 if(!settings || !settings->count(_setting))
92 throw std::runtime_error("No such setting '" + _setting + "'");
93 try {
94 (*settings)[_setting]->blank();
95 } catch(std::bad_alloc& e) {
96 throw;
97 } catch(std::exception& e) {
98 throw std::runtime_error("Can't blank setting '" + _setting + "': " + e.what());
102 std::string setting::get(const std::string& _setting) throw(std::bad_alloc, std::runtime_error)
104 if(!settings || !settings->count(_setting))
105 throw std::runtime_error("No such setting '" + _setting + "'");
106 return (*settings)[_setting]->get();
109 bool setting::is_set(const std::string& _setting) throw(std::bad_alloc, std::runtime_error)
111 if(!settings || !settings->count(_setting))
112 throw std::runtime_error("No such setting '" + _setting + "'");
113 return (*settings)[_setting]->is_set();
116 void setting::print_all() throw(std::bad_alloc)
118 if(!settings)
119 return;
120 for(auto i = settings->begin(); i != settings->end(); i++) {
121 if(!i->second->is_set())
122 messages << i->first << ": (unset)" << std::endl;
123 else
124 messages << i->first << ": " << i->second->get() << std::endl;
128 numeric_setting::numeric_setting(const std::string& sname, int32_t minv, int32_t maxv, int32_t dflt)
129 throw(std::bad_alloc)
130 : setting(sname)
132 minimum = minv;
133 maximum = maxv;
134 value = dflt;
137 void numeric_setting::blank() throw(std::bad_alloc, std::runtime_error)
139 throw std::runtime_error("This setting can't be blanked");
142 bool numeric_setting::is_set() throw()
144 return true;
147 void numeric_setting::set(const std::string& _value) throw(std::bad_alloc, std::runtime_error)
149 int32_t v = parse_value<int32_t>(_value);
150 if(v < minimum || v > maximum) {
151 std::ostringstream x;
152 x << "Value out of range (" << minimum << " - " << maximum << ")";
153 throw std::runtime_error(x.str());
155 value = v;
158 std::string numeric_setting::get() throw(std::bad_alloc)
160 std::ostringstream x;
161 x << value;
162 return x.str();
165 numeric_setting::operator int32_t() throw()
167 return value;
170 boolean_setting::boolean_setting(const std::string& sname, bool dflt) throw(std::bad_alloc)
171 : setting(sname)
173 value = dflt;
175 void boolean_setting::blank() throw(std::bad_alloc, std::runtime_error)
177 throw std::runtime_error("This setting can't be unset");
180 bool boolean_setting::is_set() throw()
182 return true;
185 void boolean_setting::set(const std::string& v) throw(std::bad_alloc, std::runtime_error)
187 if(v == "true" || v == "yes" || v == "on" || v == "1" || v == "enable" || v == "enabled")
188 value = true;
189 else if(v == "false" || v == "no" || v == "off" || v == "0" || v == "disable" || v == "disabled")
190 value = false;
191 else
192 throw std::runtime_error("Invalid value for boolean setting");
194 std::string boolean_setting::get() throw(std::bad_alloc)
196 if(value)
197 return "true";
198 else
199 return "false";
202 boolean_setting::operator bool() throw()
204 return value;