Reference for how Fixo resources are stored, discovered, and exposed to the UI.
One sentence summary
FixoLibraryis a coordinator that scans two directories — built-in (read-only, ships with the app) and custom (per-personality, user-editable) — forfixo.jsonfiles, and exposes seven Books for the typed CRUD interface the manager UIs use.
| Book | Stores | fixoType it consumes |
|---|---|---|
FixoPresetBook |
Presets — board + actuators + sensors + stanzas | "preset" |
FixoBoardTypeBook |
Board definitions | "board-type" |
FixoActuatorTypeBook |
Actuator type definitions | "actuator-type" |
FixoSensorTypeBook |
Sensor type definitions | "sensor-type" |
FixoLobeTypeBook |
Lobe type definitions | "lobe-type" |
FixoStanzaTemplateBook |
Reusable stanza patterns | "stanza-template" |
FixoPresetTemplateBook |
Parameterised preset templates | "preset-template" |
All Books share the same abstract interface (FixoBook):
QStringList list(); // names of items in this book
T get(const QString&); // item by name (T is book-specific)
T create(const QString&);
bool rename(const QString& oldName, const QString& newName);
T duplicate(const QString& name);
bool remove(const QString& name);
bool importFile(const QString& path);
bool exportFile(const QString& name, const QString& path);
bool isBuiltin(const QString& name);
So once you know the pattern from one Book, the others work the same way.
Items with "builtin": true in their fixo.json are read-only at the UI layer:
FixoBook::isBuiltin(name) returns trueremove() on a built-in returns false and leaves the book unchangedrename() on a built-in is rejectedTo customise a built-in, duplicate it — duplicate() produces a writable copy with "builtin": false that you can then edit and rename.
FixoLibrary configurationFixoLibrary lib;
lib.configure(builtinDir, customDir); // both directories
lib.scan(); // recursive walk + route by fixoType
After scan(), the Books are populated. rescan() re-walks the trees if files have changed on disk (the manager UIs call this when import succeeds).
The two directories are convention:
| Directory | Source | Purpose |
|---|---|---|
builtinDir |
typically a Qt resource path (:/fixo/...) — content shipped in libfixo's qrc |
Stable, ships with releases |
customDir |
<personality>/fixo/ on disk |
User-editable, lives with the personality |
Custom items can override built-ins by name; the override is preferred when both exist.
Every Book exposes file-shaped I/O:
book->importFile("/path/to/something.fixo.json");
book->exportFile("hexy-explorer", "/tmp/share.fixo.json");
The format is the same fixo.json schema described here. Round-trip preserves all fields except the builtin flag, which is forced to false on import (you can't import a built-in into your custom set — it would be redundant).
The Studio's manager activities expose Import / Export buttons that wire to these methods automatically. See Share a preset between nodes for the user-facing workflow.
Each personality on each node has its own <personality>/fixo/ tree, so Hub, Agent, and Remote can independently author and tweak presets. Sharing happens via Import / Export today; an automatic Book-transfer courier is on the roadmap (it'll wrap the same import/export in a courier-driven blob transfer).
| Class | Header |
|---|---|
FixoLibrary |
libfixo/fixo/library/FixoLibrary.hpp |
FixoBook (interface) |
libfixo/fixo/library/FixoBook.hpp |
FixoPresetBook |
libfixo/fixo/library/FixoPresetBook.hpp |
FixoBoardTypeBook |
libfixo/fixo/library/FixoBoardTypeBook.hpp |
FixoActuatorTypeBook |
libfixo/fixo/library/FixoActuatorTypeBook.hpp |
FixoSensorTypeBook |
libfixo/fixo/library/FixoSensorTypeBook.hpp |
FixoLobeTypeBook |
libfixo/fixo/library/FixoLobeTypeBook.hpp |
FixoStanzaTemplateBook |
libfixo/fixo/library/FixoStanzaTemplateBook.hpp |
FixoPresetTemplateBook |
libfixo/fixo/library/FixoPresetTemplateBook.hpp |
fixo.json schema — the file format