Added gui architecture documentation
This commit is contained in:
parent
a7fab74f58
commit
0616721681
121
gui.md
Normal file
121
gui.md
Normal file
@ -0,0 +1,121 @@
|
||||
# GUI Architecture
|
||||
|
||||
This document defines the high-level architectural decisions for the real-time display system.
|
||||
The display must provide smooth visual feedback for metronome position, column progress, and track states
|
||||
while maintaining responsive updates from OSC messages without blocking the rendering thread.
|
||||
|
||||
## Overview
|
||||
|
||||
The GUI architecture uses two threads to maintain responsive visual updates.
|
||||
The OSC receiver thread handles incoming state messages from the audio engine and updates shared state.
|
||||
The GUI thread runs the egui rendering loop and interpolates time-based animations independently.
|
||||
|
||||
These subsystems communicate through Tokio watch channels for efficient state synchronization.
|
||||
The audio engine acts as an OSC server, with the display connecting as a client and automatically reconnecting on failures.
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
AudioEngine[Audio Engine<br/>OSC Server<br/>Unix Socket]
|
||||
OSCThread[OSC Receiver Thread<br/>tokio + rosc<br/>State Updates]
|
||||
GUIThread[GUI Thread<br/>egui Rendering<br/>Animation Interpolation]
|
||||
|
||||
AudioEngine -->|OSC Messages| OSCThread
|
||||
OSCThread -->|Watch Channel| GUIThread
|
||||
|
||||
subgraph "Display Process"
|
||||
OSCThread
|
||||
GUIThread
|
||||
end
|
||||
```
|
||||
|
||||
The system receives state updates through standardized OSC messages and renders them using a hierarchical state structure.
|
||||
Time-critical animations like metronome movement and progress bars use local interpolation to maintain smooth 60fps updates
|
||||
independent of the OSC message frequency.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
The display uses egui as the immediate mode GUI framework,
|
||||
providing excellent performance for real-time updates and straightforward integration with Rust's async ecosystem.
|
||||
|
||||
**Core Libraries:**
|
||||
- **egui**: Immediate mode GUI framework for rendering
|
||||
- **tokio**: Async runtime for OSC message handling
|
||||
- **rosc**: OSC message parsing and Unix socket communication
|
||||
- **tokio::sync::watch**: Lock-free state sharing between threads
|
||||
|
||||
## Threading Architecture
|
||||
|
||||
### OSC Receiver Thread
|
||||
The OSC receiver thread manages the Unix socket connection to the audio engine and processes incoming state messages.
|
||||
This thread runs a tokio async loop that handles connection establishment, message parsing, and state updates.
|
||||
|
||||
### GUI Thread
|
||||
The GUI thread owns the egui context and handles all rendering operations.
|
||||
This thread polls the watch channel receiver for state changes and triggers repaints when updates arrive.
|
||||
Time interpolation for smooth animations happens during the render loop using stored timestamps and elapsed time calculations.
|
||||
|
||||
## State Management
|
||||
|
||||
### Hierarchical State Structure
|
||||
The display state mirrors the audio engine's organization to maintain consistency and simplify message parsing.
|
||||
|
||||
```
|
||||
DisplayState
|
||||
├── global
|
||||
│ ├── mode: OperationMode (Menu | Performance)
|
||||
│ ├── tempo: f32 (BPM)
|
||||
│ ├── selected_cell: (usize, usize)
|
||||
│ ├── click_enabled: bool
|
||||
│ ├── click_volume: f32
|
||||
│ └── master_volume: f32
|
||||
├── columns: [ColumnState; 5]
|
||||
│ ├── beats: usize (Total beats, 0 = not set)
|
||||
│ ├── current_beat: usize (1-based position)
|
||||
│ └── tracks: [TrackState; 5]
|
||||
│ ├── state: TrackDisplayState (Empty | Ready | Recording | Playing | Solo)
|
||||
│ └── volume: f32
|
||||
└── metronome
|
||||
├── position: f32 (0.0-1.0 within current beat)
|
||||
└── timestamp: Instant (When received)
|
||||
```
|
||||
|
||||
### State Updates
|
||||
The OSC receiver thread modifies the state directly based on incoming messages and sends the complete updated state through the watch channel.
|
||||
This approach ensures atomic updates and eliminates complex synchronization logic.
|
||||
|
||||
## OSC Message Processing
|
||||
|
||||
### Message Parsing Flow
|
||||
Incoming OSC messages map directly to state field updates using a straightforward parsing pipeline.
|
||||
Initial connection triggers a complete state dump from the audio engine using the same message format as regular updates.
|
||||
|
||||
### Time-Sensitive Messages
|
||||
Metronome position messages include timestamp capture to enable smooth interpolation in the GUI thread.
|
||||
This allows the display to show fluid metronome movement despite receiving position updates at MIDI PPQN rate rather than display refresh rate.
|
||||
|
||||
## Time Interpolation Strategy
|
||||
|
||||
### Metronome Animation
|
||||
The metronome requires smooth movement between received position updates to maintain visual continuity.
|
||||
Time interpolation happens during the render loop by calculating elapsed time since the last position update and advancing the visual position accordingly.
|
||||
This maintains frame-rate independence and ensures smooth animations regardless of system load.
|
||||
|
||||
### Column Progress Animation
|
||||
Column progress bars use similar interpolation to show smooth advancement between beat boundaries.
|
||||
The current beat position provides the discrete timing reference, with interpolation filling the gaps for fluid visual feedback.
|
||||
|
||||
## Connection Management
|
||||
|
||||
### Client Connection Pattern
|
||||
The display connects to the audio engine's Unix socket server and handles connection lifecycle automatically.
|
||||
Connection failures trigger retry attempts to avoid overwhelming the system during startup sequences.
|
||||
|
||||
### Error States and Recovery
|
||||
The GUI displays connection status to provide user feedback during system startup or audio engine restarts.
|
||||
Connection recovery happens transparently in the background, with the GUI resuming normal operation once the OSC stream resumes.
|
||||
|
||||
## Process Lifecycle
|
||||
|
||||
The display process operates independently of the audio engine, connecting as needed and handling temporary disconnections gracefully.
|
||||
External process management tools handle startup coordination and service lifecycle,
|
||||
keeping the display implementation focused on its core visualization responsibilities.
|
||||
@ -164,7 +164,7 @@ SPP (F2H): Reset to 0 on Start message
|
||||
```osc
|
||||
/looper/metronome/position <float>
|
||||
Range: 0.0 - 1.0 (position within current beat)
|
||||
Update frequency: 60 FPS
|
||||
Update frequency: same as PPQN midi signal
|
||||
```
|
||||
|
||||
### OSC Implementation Details
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user