application_properties.h
An application's settings files: one for the user, one for the machine.
#include <sonore/application_properties.h>- 2types
- Guides: Testing your plugin
On this page
Design notes
What it is for
user_settings.h already keeps a plugin's per-user preferences, keyed by plugin id and stored as a StateBag. An APPLICATION -- the standalone, a tool, an editor that owns its process -- wants the reference's arrangement instead: a file named after the application, in the place each OS expects one, a second file shared by every user of the machine, and reads that fall through from the user's file to the shared one. A licence path set by the installer for everyone, overridden per user, is the ordinary case.
Where the files go
Windows- %APPDATA%\<folder>\<app><suffix> (common: %ProgramData%)
macOS- ~/Library/<sub>/<folder>/<app><suffix> (common: /Library/...) <sub> is "Application Support" or "Preferences", as Apple asks
Linux- $XDG_CONFIG_HOME or ~/.config/<folder>/<app><suffix> (common: the first of $XDG_CONFIG_DIRS, or /etc/xdg)
<folder> is the folder name if one is given, else the application name -- except on macOS, where no folder name means directly in <sub>, as the reference does it. The machine-wide file is usually read-only for an ordinary user; getCommonSettings(true) notices and hands back the user's file instead, so a caller never has to.
Two formats
XML in the reference's own shape -- <PROPERTIES> holding <VALUE name val> elements -- so a file an older application wrote is read, and a user can fix one in a text editor. Or binary: the same StateBag encoding every session blob here uses, behind a magic so the reader can tell. Either is read whatever the options say; the option decides what is WRITTEN.
Saving later, and the clock
A change marks the file dirty and saves it millisecondsBeforeSaving after the LAST change -- a slider dragged for two seconds writes once, not sixty times. The wait is driven by advance(elapsedMs), the same rule every timed thing in this SDK follows: no timer thread inside a settings object, and a test of "saves after 3 s" that runs in no time at all. Zero saves on every change; negative only on save()/saveIfNeeded(), and the destructor saves whatever is still dirty.
Two processes, one file
The machine-wide file is written by more than one process -- two users, two copies of the application. With the process lock on (always, for the common file) every read and write holds an OS file lock on "<file>.lock" beside it: LockFileEx on Windows, flock elsewhere. The lock dies with its process, so a crash never leaves the file locked. The write itself goes through a temporary and a rename, like UserSettings.
MAIN THREAD for saving and loading -- they open files. Reading and setting values is safe from any thread (a lock guards the values).
Types 2
class PropertiesFile : public ChangeBroadcaster
One settings file: string values by key, loaded on construction, saved after a delay, on demand, and on destruction.
Values are text, as in the reference, with typed getters and setters on top. A getter for a key this file lacks asks the fallback file, if one is set -- that is how ApplicationProperties makes the user's file read through to the machine's. Every change is also a ChangeBroadcaster change, so a preferences page can redraw on the next tick.
The pair: a user file and a machine-wide one, opened on first use, the user's reading through to the machine's.
setStorageParameters() first; then getUserSettings() for anything a user chooses and getCommonSettings(true) for anything an installer or an administrator sets -- which comes back as the user's file when the shared one cannot be written.