openMSX
SettingsManager.cc
Go to the documentation of this file.
1 #include "SettingsManager.hh"
3 #include "Command.hh"
4 #include "InfoTopic.hh"
5 #include "TclObject.hh"
6 #include "Setting.hh"
7 #include "CommandException.hh"
8 #include "XMLElement.hh"
9 #include "KeyRange.hh"
10 #include "memory.hh"
11 #include <cassert>
12 
13 using std::string;
14 using std::vector;
15 
16 namespace openmsx {
17 
18 // SettingsManager implementation:
19 
20 class SettingInfo : public InfoTopic
21 {
22 public:
23  SettingInfo(InfoCommand& openMSXInfoCommand, SettingsManager& manager);
24  virtual void execute(array_ref<TclObject> tokens,
25  TclObject& result) const;
26  virtual string help(const vector<string>& tokens) const;
27  virtual void tabCompletion(vector<string>& tokens) const;
28 private:
29  SettingsManager& manager;
30 };
31 
33 {
34 public:
36  SettingsManager& manager);
37  virtual string help(const vector<string>& tokens) const;
38  virtual void tabCompletion(vector<string>& tokens) const;
39 private:
40  SettingsManager& manager;
41 };
42 
44 {
45 public:
47  SettingsManager& manager,
48  const string& name);
49  virtual string help(const vector<string>& tokens) const;
50  virtual void tabCompletion(vector<string>& tokens) const;
51 private:
52  SettingsManager& manager;
53 };
54 
55 
57  : settingInfo(make_unique<SettingInfo>(
58  commandController.getOpenMSXInfoCommand(), *this))
59  , setCompleter(make_unique<SetCompleter>(
60  commandController, *this))
61  , incrCompleter(make_unique<SettingCompleter>(
62  commandController, *this, "incr"))
63  , unsetCompleter(make_unique<SettingCompleter>(
64  commandController, *this, "unset"))
65 {
66 }
67 
69 {
70  assert(settingsMap.empty());
71 }
72 
74 {
75  assert(settingsMap.find(name) == end(settingsMap));
76  settingsMap[name] = &setting;
77 }
78 
80 {
81  assert(settingsMap.find(name) != end(settingsMap));
82  settingsMap.erase(name);
83 }
84 
86 {
87  auto it = settingsMap.find(name);
88  return (it != end(settingsMap)) ? it->second : nullptr;
89 }
90 
91 // Helper functions for setting commands
92 
93 BaseSetting& SettingsManager::getByName(string_ref cmd, string_ref name) const
94 {
95  if (auto* setting = findSetting(name)) {
96  return *setting;
97  }
98  throw CommandException(cmd + ": " + name + ": no such setting");
99 }
100 
102 {
103  // restore default values
104  for (auto* s : values(settingsMap)) {
105  if (s->needLoadSave()) {
106  s->setString(s->getRestoreValue());
107  }
108  }
109 
110  // load new values
111  auto* settings = config.findChild("settings");
112  if (!settings) return;
113  for (auto& p : settingsMap) {
114  auto name = p.first();
115  auto& setting = *p.second;
116  if (!setting.needLoadSave()) continue;
117  if (auto* elem = settings->findChildWithAttribute(
118  "setting", "id", name)) {
119  try {
120  setting.setString(elem->getData());
121  } catch (MSXException&) {
122  // ignore, keep default value
123  }
124  }
125  }
126 }
127 
128 
129 // class SettingInfo
130 
132  SettingsManager& manager_)
133  : InfoTopic(openMSXInfoCommand, "setting")
134  , manager(manager_)
135 {
136 }
137 
139 {
140  auto& settingsMap = manager.settingsMap;
141  switch (tokens.size()) {
142  case 2:
143  for (auto& p : settingsMap) {
144  result.addListElement(p.first());
145  }
146  break;
147  case 3: {
148  const auto& name = tokens[2].getString();
149  auto it = settingsMap.find(name);
150  if (it == end(settingsMap)) {
151  throw CommandException("No such setting: " + name);
152  }
153  it->second->info(result);
154  break;
155  }
156  default:
157  throw CommandException("Too many parameters.");
158  }
159 }
160 
161 string SettingInfo::help(const vector<string>& /*tokens*/) const
162 {
163  return "openmsx_info setting : "
164  "returns list of all settings\n"
165  "openmsx_info setting <name> : "
166  "returns info on a specific setting\n";
167 }
168 
169 void SettingInfo::tabCompletion(vector<string>& tokens) const
170 {
171  if (tokens.size() == 3) {
172  // complete setting name
173  completeString(tokens, keys(manager.settingsMap));
174  }
175 }
176 
177 
178 // class SetCompleter
179 
181  SettingsManager& manager_)
182  : CommandCompleter(commandController, "set"), manager(manager_)
183 {
184 }
185 
186 string SetCompleter::help(const vector<string>& tokens) const
187 {
188  if (tokens.size() == 2) {
189  return manager.getByName("set", tokens[1]).getDescription();
190  }
191  return "Set or query the value of a openMSX setting or Tcl variable\n"
192  " set <setting> shows current value\n"
193  " set <setting> <value> set a new value\n"
194  "Use 'help set <setting>' to get more info on a specific\n"
195  "openMSX setting.\n";
196 }
197 
198 void SetCompleter::tabCompletion(vector<string>& tokens) const
199 {
200  switch (tokens.size()) {
201  case 2:
202  // complete setting name
203  completeString(tokens, keys(manager.settingsMap), false); // case insensitive
204  break;
205  case 3: {
206  // complete setting value
207  auto it = manager.settingsMap.find(tokens[1]);
208  if (it != end(manager.settingsMap)) {
209  it->second->tabCompletion(tokens);
210  }
211  break;
212  }
213  }
214 }
215 
216 
217 // class SettingCompleter
218 
221  const string& name)
222  : CommandCompleter(commandController, name)
223  , manager(manager_)
224 {
225 }
226 
227 string SettingCompleter::help(const vector<string>& /*tokens*/) const
228 {
229  return ""; // TODO
230 }
231 
232 void SettingCompleter::tabCompletion(vector<string>& tokens) const
233 {
234  if (tokens.size() == 2) {
235  // complete setting name
236  completeString(tokens, keys(manager.settingsMap));
237  }
238 }
239 
240 } // namespace openmsx
detail::KeyRange< MAP, 1 > values(const MAP &map)
Definition: KeyRange.hh:101
virtual std::string getDescription() const =0
pure virtual methods ///
string_ref::const_iterator end(const string_ref &x)
Definition: string_ref.hh:135
size_type size() const
Definition: array_ref.hh:61
virtual string help(const vector< string > &tokens) const
Print help for this topic.
This class implements a subset of the proposal for std::string_ref (proposed for the next c++ standar...
Definition: string_ref.hh:18
void loadSettings(const XMLElement &config)
void unregisterSetting(BaseSetting &setting, string_ref name)
void registerSetting(BaseSetting &setting, string_ref name)
const XMLElement * findChild(string_ref name) const
Definition: XMLElement.cc:132
virtual string help(const vector< string > &tokens) const
Print help for this command.
virtual string help(const vector< string > &tokens) const
Print help for this command.
Manages all settings.
virtual void tabCompletion(vector< string > &tokens) const
Attempt tab completion for this topic.
SettingCompleter(CommandController &commandController, SettingsManager &manager, const string &name)
This class implements a subset of the proposal for std::array_ref (proposed for the next c++ standard...
Definition: array_ref.hh:19
BaseSetting * findSetting(string_ref name) const
Find the setting with given name.
SettingsManager(GlobalCommandController &commandController)
SetCompleter(CommandController &commandController, SettingsManager &manager)
virtual void tabCompletion(vector< string > &tokens) const
Attempt tab completion for this command.
virtual void tabCompletion(vector< string > &tokens) const
Attempt tab completion for this command.
virtual void execute(array_ref< TclObject > tokens, TclObject &result) const
Show info on this topic.
void addListElement(string_ref element)
Definition: TclObject.cc:110
static void completeString(std::vector< std::string > &tokens, const RANGE &possibleValues, bool caseSensitive=true)
Definition: Completer.hh:88
commandController(commandController_)
SettingInfo(InfoCommand &openMSXInfoCommand, SettingsManager &manager)
std::unique_ptr< T > make_unique()
Definition: memory.hh:27
detail::KeyRange< MAP, 0 > keys(const MAP &map)
Definition: KeyRange.hh:96