GUI M8f: Event-driven updates, deferred link restoration, routing rules UI

This commit is contained in:
Joey Yakimowich-Payne 2026-01-30 11:52:24 -07:00
commit b819d6fd65
6 changed files with 440 additions and 121 deletions

View file

@ -274,19 +274,20 @@ A Qt6-based node editor GUI for warppipe using the QtNodes (nodeeditor) library.
- [x] Remove meter rows when nodes deleted
- [x] `rebuildNodeMeters()` wired to `nodeCreated`/`nodeDeleted` signals
- [x] Add tests for AudioLevelMeter level clamping, hold/decay logic, METERS tab existence, meter row creation
- [ ] Milestone 8f - Architecture and Routing Rules
- [ ] Event-driven updates: replace 500ms polling with signal/slot if core adds registry callbacks
- [ ] `nodeAdded(NodeInfo)`, `nodeRemoved(uint32_t)`, `nodeChanged(NodeInfo)`
- [ ] `linkAdded(LinkInfo)`, `linkRemoved(uint32_t)`
- [ ] Keep polling as fallback if signals not available
- [ ] Link intent system: remember intended links by stable key, restore when nodes reappear
- [ ] `rememberLinkIntent(LinkInfo)` — store stable_id:port_name pairs
- [ ] `tryRestoreLinks()` — called on node add, resolves stored intents
- [ ] Persist link intents in layout JSON
- [ ] Add routing rule UI (separate panel or dialog)
- [ ] List existing rules from `Client::ListRouteRules()`
- [ ] Add/remove rules with RuleMatch fields
- [ ] Show which nodes are affected by rules
- [x] Milestone 8f - Architecture and Routing Rules
- [x] Event-driven updates: core `SetChangeCallback()` fires on registry changes, GUI debounces via 50ms QTimer + QueuedConnection marshal (2s polling kept as fallback)
- [x] `Client::SetChangeCallback(ChangeCallback)` — fires from PW thread on node/port/link add/remove
- [x] `NotifyChange()` uses dedicated `change_cb_mutex` (not cache_mutex) to avoid lock ordering issues
- [x] GUI marshals to Qt thread via `QMetaObject::invokeMethod(..., Qt::QueuedConnection)`
- [x] Link intent system: implemented via core `saved_links` + deferred `ProcessSavedLinks()`
- [x] `LoadConfig()` parses links into `saved_links` vector (stable node:port name pairs)
- [x] `ProcessSavedLinks()` resolves names → port IDs on each CoreDone, creates via `CreateSavedLinkAsync()`
- [x] Competing links from WirePlumber auto-removed after saved link creation
- [x] Persisted in config.json `links` array (not layout JSON — core owns link state)
- [x] Add routing rule UI (RULES sidebar tab)
- [x] List existing rules from `Client::ListRouteRules()` as styled cards
- [x] Add rules via dialog with Application Name, Process Binary, Media Role, Target Node fields
- [x] Delete rules via per-card ✕ button
---