openMSX uses settings for both persistent user preferences and non-persistent configuration items. A setting has the following properties:
For some types (such as string) the range is always the full type: any string is possible. For ordered types (int, float) range is a minimum and maximum value. For enumerations, range is the list of possible values.
Both the current value and the range are dynamic. An example of a dynamic range is the "videosource" setting: if a GFX9000 cartridge is inserted, an additional video source becomes available.
Setting existence is also dynamic: for example sound settings such as volume and balance exist for each sound device and sound devices can come and go at runtime. Another example is the firmware setting, which is only available on machines that have indeed switchable firmware.
Much of the functionality of Catapult consists of controlling openMSX settings. Therefore, we want to have a framework that offers an easy way to observe and modify settings.
Here is an overview of how Catapult should handle the different setting properties:
All communication between Catapult and openMSX is asynchronous. This means that reading a setting will not immediately return an answer. The framework should offer a mechanism to deliver the answer when it arrives. Additionally, Catapult can subscribe to updates from openMSX, which arrive in Catapult at arbitrary moments.
Typically there is a widget or set of widgets to control a particular setting. The framework must offer a way to keep the value of a widget synchronized to the value of the setting in openMSX: the widget's value must get updated when the setting's value changes and vice versa. This mechanism must avoid oscillation that can happen because of the latency of the asynchronous communication channel with openMSX.
In addition to synchronizing the current value, there must be a mechanism to synchronize the current range: if openMSX reports a change in range, the widget must be reconfigured accordingly. Also "revert to default value" must be easy to trigger by a widget.
Settings may stop or start to exist when a machine is changed. It must be possible for a widget to be connected to a certain setting in the current machine. When a switch from an old machine to a new machine occurs, the widget must automatically be synchronized (and stay synchronized) to the same setting in the new machine. The cases where a setting exists in the old machine but not in the new machine or vice versa must be supported as well.
Catapult will keep a proxy object for every setting that it is interested in. There will be a central registry of setting proxies, to make sure there is at most one proxy for each openMSX setting.
Setting properties (both static and dynamic) are fetched from openMSX. Catapult's view of a setting can be in one of the following states:
Note that "currently" refers to Catapult's view of the setting. Because of the asynchronous nature of the control connection, openMSX might temporarily have a different view.
It would be possible to query setting properties one at a time, in which case the "known" state would be split into several new states. However, this complicates things without offering an advantage.
Some settings exist per machine. For those settings, the setting proxy will reflect the setting from the current machine. Therefore, on a machine change settings can go in or out of existance, or change value.
We should be able to handle the fact that different widget types have different signals (names and signatures) for 'value changed' and different methods to set a value (e.g. in a ComboBox for EnumSettings, you have to find the proper index and set that as current).
We should take into account that we have to convert types in our setting code. E.g. Slider widgets do not support floats. We have to convert to ints and back to floats for this. Other (small) conversions need to take place for booleans in checkboxes, e.g.
Filename setting: can we use it to do something clever with a file dialog?
$Id$