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