|
Undo and redo landed a couple of days ago. The next item on the plan was the Piece Settings window – the place where a score's global configuration lives. But Piece Settings requires instrument assignments, and instrument assignments require a working Instrument Library. So the sequence revealed itself, as it does: not Piece Settings next, but the thing Piece Settings depends on. This is not an unwelcome discovery. The Instrument Library turns out to be the cleanest possible entity to build at this stage, precisely because it depends on nothing. No piece identity, no piece lifecycle, no window hierarchy. It is global and singleton: one library per backend, shared across all connected clients, persisting across restarts. It holds templates, not instances – when a musician is assigned an instrument, the piece receives a copy of the template and the two are independent from that point. Renaming a template later has no effect on instruments already in scores. That independence from the rest of the system makes it the right place to establish something that will govern every piece of shared state Ooloi ever manages: the invalidate/fetch/replace pattern. The PatternThe pattern is this. When the library changes on the backend, the server broadcasts a notification that any copies 'out there' are now stale. Clients that receive it mark their local cache stale. If the Instrument Library window happens to be open, they fetch immediately and re-render. If the window is closed, nothing happens until it opens – at which point the fetch occurs and the window renders from fresh data. A client that never opens the window pays no cost at all, even if the library is modified repeatedly during the session by other clients. The sending client follows the same path as everyone else. It does not update its local state from the success response; it waits for the event it will receive as a subscriber, then fetches like any other client. There is one code path for state updates regardless of where the change originated. In practiceWorking through the implementation surfaced several problems, each with a clean answer. Two users editing the library simultaneously must not silently overwrite each other's work, so a change is rejected if someone else updated the library first – the conflict is surfaced explicitly, and the second user reapplies their change on top of the current state. Instruments deleted by the user must stay deleted across application updates that ship new default entries, which requires tracking deletions rather than simply omitting items. Display order within a family must survive both user rearrangement and future additions from updates, which requires ordering to be stored explicitly rather than inferred from position.
What the exercise confirmed is the value of the division of concerns itself. The backend stores state, enforces consistency, and broadcasts invalidation events. The frontend gets the data when required, transforms it locally through whatever editing operations the user performs, and submits the result. The backend does not participate in editing decisions; the frontend does not manage persistence concerns. That division – established here on clean, self-contained ground – is the same division that will govern every piece of rendered state going forward. The Instrument Library is the first authoritative backend entity that is not a piece; its clean behaviour under load, concurrency, and updates confirms that the model generalises. Everything built on top of it will follow the same pattern. Read all about it in ADR 0045: Instrument Library.
7 Comments
Magnus Johansson
12/3/2026 18:18:56
Will the Instrument Library contain professional and amateur ranges for each instrument like in Igor Engraver where notes are coloured yellow when outside the amateur range, and red when outside the professional range?
Reply
Peter Bengtson
12/3/2026 20:32:50
Yes – each template carries both :range and :amateur-range fields, producing the red/yellow distinction at render time. The Horn in F entry in ADR-0045 shows both fields as a worked example.
Reply
Magnus Johansson
12/3/2026 21:41:05
What about octave transposing clefs? Will it be possible to have the Instrument Library always use the treble clef ottava alta for the soprano recorder?
Reply
Peter Bengtson
12/3/2026 22:42:46
Yes. The default clef for any instrument is set in the template and can be changed in the Instrument Library. The soprano recorder would simply have its staff spec updated to use the treble ottava alta clef, and that becomes the default for all new scores using that template.
Reply
Magnus Johansson
13/3/2026 08:35:50
Great!
Rune Brynsholmen
19/3/2026 15:12:03
Following this development is on of the most interesting thing I have done. Some goes over my head, but the way you explain things is so clear and it all seems so well thought out. Rey exited to see how well my scores from other apps will transform in ooloi when the time comes.
Reply
Peter Bengtson
19/3/2026 18:14:17
Thank you, Rune. The technical depth is there for those who want it, but you don't need to follow every detail to use the result. I try to make things as understandable as possible, as this blog is a development log _and_ a musician-facing forum. Art served by Technology.
Reply
Leave a Reply. |
AuthorPeter Bengtson – SearchArchives
April 2026
Categories
All
|
|
|
Ooloi is an open-source desktop music notation system for musicians who need stable, precise engraving and the freedom to notate complex music without workarounds. Scores and parts are handled consistently, remain responsive at scale, and support collaborative work without semantic compromise. They are not tied to proprietary formats or licensing.
Ooloi is currently under development. No release date has been announced.
|
RSS Feed