openMSX
Setting.cc
Go to the documentation of this file.
1 #include "Setting.hh"
2 #include "CommandController.hh"
5 #include "SettingsConfig.hh"
6 #include "TclObject.hh"
7 #include "CliComm.hh"
8 #include "XMLElement.hh"
9 #include "MSXException.hh"
10 #include "checked_cast.hh"
11 
12 using std::string;
13 using std::string_view;
14 
15 namespace openmsx {
16 
17 // class BaseSetting
18 
19 BaseSetting::BaseSetting(string_view name)
20  : fullName(name)
21  , baseName(fullName)
22 {
23 }
24 
26  : fullName(name)
27  , baseName(fullName)
28 {
29 }
30 
31 void BaseSetting::info(TclObject& result) const
32 {
34  additionalInfo(result);
35 }
36 
37 
38 // class Setting
39 
40 Setting::Setting(CommandController& commandController_,
41  string_view name, string_view description_,
42  const TclObject& initialValue, SaveSetting save_)
43  : BaseSetting(name)
44  , commandController(commandController_)
45  , description(description_)
46  , value(initialValue)
47  , defaultValue(initialValue)
48  , restoreValue(initialValue)
49  , save(save_)
50 {
51  checkFunc = [](TclObject&) { /* nothing */ };
52 }
53 
55 {
56  if (needLoadSave()) {
57  auto& settingsConfig = getGlobalCommandController()
59  if (auto* config = settingsConfig.findChild("settings")) {
60  if (auto* elem = config->findChildWithAttribute(
61  "setting", "id", getBaseName())) {
62  try {
63  setValueDirect(TclObject(elem->getData()));
64  } catch (MSXException&) {
65  // saved value no longer valid, just keep default
66  }
67  }
68  }
69  }
71 
72  // This is needed to for example inform catapult of the new setting
73  // value when a setting was destroyed/recreated (by a machine switch
74  // for example).
75  notify();
76 }
77 
79 {
81 }
82 
83 
84 string_view Setting::getDescription() const
85 {
86  return description;
87 }
88 
89 void Setting::setValue(const TclObject& newValue)
90 {
92 }
93 
94 void Setting::notify() const
95 {
96  // Notify all subsystems of a change in the setting value. There
97  // are actually quite a few subsystems involved with the settings:
98  // - the setting classes themselves
99  // - the Tcl variables (and possibly traces on those variables)
100  // - Subject/Observers
101  // - CliComm setting-change events (for external GUIs)
102  // - SettingsConfig (keeps values, also of not yet created settings)
103  // This method takes care of the last 3 in this list.
105  TclObject val = getValue();
106  commandController.getCliComm().update(
108 
109  // Always keep SettingsConfig in sync.
110  auto& config = getGlobalCommandController().getSettingsConfig().getXMLElement();
111  auto& settings = config.getCreateChild("settings");
112  if (!needLoadSave() || (val == getDefaultValue())) {
113  // remove setting
114  if (auto* elem = settings.findChildWithAttribute(
115  "setting", "id", getBaseName())) {
116  settings.removeChild(*elem);
117  }
118  } else {
119  // add (or overwrite) setting
120  auto& elem = settings.getCreateChildWithAttribute(
121  "setting", "id", getBaseName());
122  // check for non-saveable value
123  // (mechanism can be generalize later when needed)
124  if (val == dontSaveValue) val = getRestoreValue();
125  elem.setData(string(val.getString()));
126  }
127 }
128 
130 {
131  TclObject result;
132  info(result);
133  commandController.getCliComm().update(
135 }
136 
138 {
139  return save == SAVE;
140 }
142 {
143  return save != DONT_TRANSFER;
144 }
145 
146 void Setting::setDontSaveValue(const TclObject& dontSaveValue_)
147 {
148  dontSaveValue = dontSaveValue_;
149 }
150 
151 GlobalCommandController& Setting::getGlobalCommandController() const
152 {
153  if (auto* globalCommandController =
154  dynamic_cast<GlobalCommandController*>(&commandController)) {
155  return *globalCommandController;
156  } else {
157  return checked_cast<MSXCommandController*>(&commandController)
158  ->getGlobalCommandController();
159  }
160 }
161 
163 {
164  return commandController.getInterpreter();
165 }
166 
167 void Setting::tabCompletion(std::vector<string>& /*tokens*/) const
168 {
169  // nothing
170 }
171 
172 void Setting::additionalInfo(TclObject& /*result*/) const
173 {
174  // nothing
175 }
176 
177 
178 void Setting::setValueDirect(const TclObject& newValue_)
179 {
180  TclObject newValue = newValue_;
181  checkFunc(newValue);
182  if (newValue != value) {
183  value = newValue;
184  notify();
185  }
186 
187  // synchronize proxy
188  auto* controller = dynamic_cast<MSXCommandController*>(
190  if (!controller) {
191  // This is not a machine specific setting.
192  return;
193  }
194  if (!controller->isActive()) {
195  // This setting does not belong to the active machine.
196  return;
197  }
198 
199  // Tcl already makes sure this doesn't result in an endless loop.
200  try {
202  } catch (MSXException&) {
203  // ignore
204  }
205 }
206 
207 } // namespace openmsx
openmsx::Setting::getInterpreter
Interpreter & getInterpreter() const
Definition: Setting.cc:162
openmsx::CommandController::getInterpreter
virtual Interpreter & getInterpreter()=0
openmsx::Setting::getDefaultValue
TclObject getDefaultValue() const final override
Get the default value of this setting.
Definition: Setting.hh:159
openmsx::CommandController
Definition: CommandController.hh:18
openmsx::BaseSetting::getTypeString
virtual std::string_view getTypeString() const =0
Returns a string describing the setting type (integer, string, ..) Could be used in a GUI to pick an ...
Setting.hh
TclObject.hh
openmsx::BaseSetting::getBaseName
std::string_view getBaseName() const
Definition: Setting.hh:36
openmsx::Setting::getValue
const TclObject & getValue() const final override
Gets the current value of this setting as a TclObject.
Definition: Setting.hh:135
openmsx::Interpreter::setVariable
void setVariable(const TclObject &name, const TclObject &value)
Definition: Interpreter.cc:239
openmsx::Setting::tabCompletion
void tabCompletion(std::vector< std::string > &tokens) const override
Complete a partly typed value.
Definition: Setting.cc:167
openmsx::Setting::needTransfer
bool needTransfer() const final override
Does this setting need to be transfered on reverse.
Definition: Setting.cc:141
openmsx::Setting::setValue
void setValue(const TclObject &newValue) final override
Change the value of this setting to the given value.
Definition: Setting.cc:89
openmsx::Setting::needLoadSave
bool needLoadSave() const final override
Does this setting need to be loaded or saved (settings.xml).
Definition: Setting.cc:137
openmsx::Setting::getCommandController
CommandController & getCommandController() const
Definition: Setting.hh:169
openmsx::CliComm::update
virtual void update(UpdateType type, std::string_view name, std::string_view value)=0
openmsx::BaseSetting::info
void info(TclObject &result) const
For SettingInfo.
Definition: Setting.cc:31
openmsx::Setting::Setting
Setting(const Setting &)=delete
MSXException.hh
openmsx::MSXException
Definition: MSXException.hh:10
openmsx::XMLElement::removeChild
void removeChild(const XMLElement &child)
Definition: XMLElement.cc:29
openmsx::Setting::setDontSaveValue
void setDontSaveValue(const TclObject &dontSaveValue) final override
This value will never end up in the settings.xml file.
Definition: Setting.cc:146
XMLElement.hh
openmsx::CliComm::SETTINGINFO
@ SETTINGINFO
Definition: CliComm.hh:23
openmsx::BaseSetting::additionalInfo
virtual void additionalInfo(TclObject &result) const =0
Helper method for info().
CommandController.hh
openmsx::TclObject::addListElement
void addListElement(T t)
Definition: TclObject.hh:121
openmsx::Setting::getDescription
std::string_view getDescription() const final override
pure virtual methods ///
Definition: Setting.cc:84
openmsx::CommandController::getCliComm
virtual CliComm & getCliComm()=0
SettingsConfig.hh
openmsx::BaseSetting::getFullNameObj
const TclObject & getFullNameObj() const
Get the name of this setting.
Definition: Setting.hh:33
openmsx::BaseSetting::BaseSetting
BaseSetting(std::string_view name)
Definition: Setting.cc:19
openmsx::BaseSetting
Definition: Setting.hh:19
openmsx::Setting::additionalInfo
void additionalInfo(TclObject &result) const override
Helper method for info().
Definition: Setting.cc:172
openmsx::Setting::init
void init()
Definition: Setting.cc:54
openmsx::Setting::DONT_TRANSFER
@ DONT_TRANSFER
Definition: Setting.hh:128
openmsx::SettingsConfig::getXMLElement
XMLElement & getXMLElement()
Definition: SettingsConfig.hh:30
openmsx::Setting::~Setting
virtual ~Setting()
Definition: Setting.cc:78
openmsx::Setting::setValueDirect
void setValueDirect(const TclObject &newValue) final override
Similar to setValue(), but doesn't trigger Tcl traces.
Definition: Setting.cc:178
openmsx::XMLElement::getCreateChild
XMLElement & getCreateChild(std::string_view childName, std::string_view defaultValue={})
Definition: XMLElement.cc:146
checked_cast.hh
openmsx::Setting::SaveSetting
SaveSetting
Definition: Setting.hh:125
openmsx::Setting::getRestoreValue
TclObject getRestoreValue() const final override
Get the value that will be set after a Tcl 'unset' command.
Definition: Setting.hh:160
openmsx::Setting::SAVE
@ SAVE
Definition: Setting.hh:126
GlobalCommandController.hh
openmsx::TclObject::getString
std::string_view getString() const
Definition: TclObject.cc:102
MSXCommandController.hh
openmsx::Setting::notifyPropertyChange
void notifyPropertyChange() const
Definition: Setting.cc:129
openmsx::TclObject
Definition: TclObject.hh:22
openmsx::MSXCommandController
Definition: MSXCommandController.hh:22
openmsx::CommandController::registerSetting
virtual void registerSetting(Setting &setting)=0
TODO.
openmsx::BaseSetting::getBaseNameObj
const TclObject & getBaseNameObj() const
Definition: Setting.hh:34
openmsx::Subject::notify
void notify() const
Definition: Subject.hh:67
CliComm.hh
openmsx::CliComm::SETTING
@ SETTING
Definition: CliComm.hh:22
openmsx::Interpreter
Definition: Interpreter.hh:17
openmsx::GlobalCommandController
Definition: GlobalCommandController.hh:37
openmsx::CommandController::unregisterSetting
virtual void unregisterSetting(Setting &setting)=0
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
openmsx::BaseSetting::getDefaultValue
virtual TclObject getDefaultValue() const =0
Get the default value of this setting.
openmsx::GlobalCommandController::getSettingsConfig
SettingsConfig & getSettingsConfig()
Definition: GlobalCommandController.hh:88