The config system in pcb-rnd - why
Why, what was wrong with the old one?
The old config system had several limitations that would have been
hard to fix keeping the original design:
- config settings were specified in a flat list - no grouping
- the core had a rather static system - HIDs or plugins couldn't extend it, thus they had to invent their own config files
- ... this led to a variety of configuration formats; using one format not always because it was better suited for the task, but for historical reasons
- ... this also led to a collection of config files - again not always split by boundaries of settings, but often by arbitrary boundaries of code
- the old system didn't support lists or arrays well
- it didn't have a coherent concept of how settings from different sources would override each other
- ... this resulted in the rigid structure that most of the settings could come from only one place (e.g. if it's an user setting, the design won't be able to override it)
What the new system offers
- unified format: lihata ...
- ... more future proof: generic markup language - easier to extend without having to worry about breaking the syntax
- ... the configuration is represented in a tree, grouped by the nature of settings
- ... there are arrays and lists
- ... a config file can overwrite a list or prepend/append to it (e.g. design-level config prepending an extra library path keeping system set paths as well)
- there are different sources of configuration, e.g. system-wise, user-wise, project-wise, etc.
- the user has the power to change default config priority per setting; e.g. normally design config overrides user config, but it's possible to mark a setting from user config so strong that it overrides even the setting read from the board file
- the way settings are stored is flexible and extensible so that a plugin can define their subtree of settings
- ... since the API even makes it easier to access such settings (vs. parsing your own config file), plugins will tend to use the unified config format/system instead of inventing their own
- ... the GUI (preferences dialog) thus can automatically handle the new settings
- ... plugins don't have to implement actions to set/toggle/query their settings for the menu system, there are generic config set/toggle/query actions the menu config can use
- ... plugins also get the multi-source, priority-based config mechanism
- ... which also means plugin settings can be automatically saved as user setting, project setting or even design setting
- all these are true for all kind of settings, be them GUI preferences, paths, layer colors, grid settings; there should be no exception
But isn't this more complicated for the user?
Hopefully not much. There are a few extra features, like
multiple sources with levels that did not
exist in pcb and lists with prepend/append. Some of these
features present in other software so users should be comfortable with the ideas.
The learning curve is probably compensated by the more orthogonal system.
The syntax is also geared for simplicity and easy use with text editors.
Finally, the new preferences dialog and config actions help
the user to explore how settings got used from all the config sources. There's
an intended layering in complexity: simple things can be done easily without
having to understand the whole system.
All in all, the extra features the user needs to learn is comparable with
the old customs that he/she can forget.
And did it make the code more complicated?
The size of the code did not change much after the initial config rewrite.
The new system has new features, some of which brought in a few hundred lines of
code, but a similar amount of old code could be removed. What came in is
infrastructure, what had to go was a bunch of repetitive config parsing,
boolean-setting-accessor-action code. This means on the long run, the more
settings are added, the more the new system pays back.
Read access, which is far the most common way to use the config in the
code (e.g. if (setting == true) { }) is very similar to the old Settings
system. Write access needs to go through a function call API, but this
is usually a single call per setting (instead of directly modifying a
variable).
For plugin programmers, the new system makes life much easier as they can
plug their settings in.