Ownership: the engine (audio) thread is the single reader of the command queue and the single writer of the applied queue / snapshot / playhead. More...
#include <sequencer_state_channel.hpp>
Public Types | |
| using | ConfigType = Config |
| using | Snapshot = SnapshotT<Config> |
| using | PatternState = PatternStateT<Config> |
| using | Command = StepEditCommandT<Config> |
| using | AppliedEdit = AppliedEditT<Config> |
| using | StepRangeApplied = StepRangeAppliedT<Config> |
| using | SetCellEdit = SetCellEditT<Config> |
| using | Playhead = typename Config::playhead_type |
Public Member Functions | |
| SequencerStateChannelT ()=default | |
| bool | ui_try_submit (const Command &command) noexcept |
| Submit an edit command. | |
| std::optional< AppliedEdit > | ui_try_pop_applied () noexcept |
| Pop the next applied echo to replay onto the UI render copy, or nullopt. | |
| Playhead | ui_read_playhead () const noexcept |
| Coherent read of the latest playhead. Lock-free, allocation-free. | |
| const Snapshot & | ui_read_latest_snapshot () noexcept |
| The latest full snapshot. | |
| Epoch | ui_resync_required_epoch () const noexcept |
| The snapshot epoch the UI must reach before trusting incremental echoes again. | |
| runtime::SpscQueueTelemetry | ui_applied_telemetry () const noexcept |
| runtime::SpscQueueTelemetry | ui_command_telemetry () const noexcept |
| bool | debug_claim_ui_consumer () noexcept |
| Debug-only single-UI-consumer guard. | |
| void | debug_release_ui_consumer () noexcept |
| std::optional< Command > | audio_try_pop_command () noexcept |
| Pop the next pending edit command to apply. Lock-free, allocation-free. | |
| bool | audio_try_publish_applied (const AppliedEdit &edit) noexcept |
| Publish an applied echo. | |
| void | audio_publish_snapshot (const Snapshot &snapshot) noexcept |
| Publish the full authoritative snapshot (initial load / preset / bulk / resync). | |
| void | audio_publish_playhead (const Playhead &playhead) noexcept |
| Publish the latest playhead. Lock-free, allocation-free; call per block. | |
| void | audio_mark_resync_required (Epoch epoch) noexcept |
Signal that incremental echoes were lost and the UI must resync to at least epoch. | |
Ownership: the engine (audio) thread is the single reader of the command queue and the single writer of the applied queue / snapshot / playhead.
The UI/message thread is the single writer of the command queue and the single reader of the applied queue / snapshot / playhead. Do not call the UI-side methods from the audio thread or vice versa — each FIFO is strictly single-reader/single-writer.
EXACTLY ONE UI-side consumer per channel: the applied-echo FIFO is destructively consumed, so two views bound to one channel would each see a random interleaving of echoes and corrupt each other. For a multi-view UI put one owner (a render model) between the channel and the views. Debug builds enforce this via a consumer-claim token (see debug_claim_ui_consumer).
| using pulp::state::SequencerStateChannelT< Config >::AppliedEdit = AppliedEditT<Config> |
| using pulp::state::SequencerStateChannelT< Config >::Command = StepEditCommandT<Config> |
| using pulp::state::SequencerStateChannelT< Config >::ConfigType = Config |
| using pulp::state::SequencerStateChannelT< Config >::PatternState = PatternStateT<Config> |
| using pulp::state::SequencerStateChannelT< Config >::Playhead = typename Config::playhead_type |
| using pulp::state::SequencerStateChannelT< Config >::SetCellEdit = SetCellEditT<Config> |
| using pulp::state::SequencerStateChannelT< Config >::Snapshot = SnapshotT<Config> |
| using pulp::state::SequencerStateChannelT< Config >::StepRangeApplied = StepRangeAppliedT<Config> |
|
default |
|
inlinenoexcept |
|
inlinenoexcept |
Publish the latest playhead. Lock-free, allocation-free; call per block.
|
inlinenoexcept |
Publish the full authoritative snapshot (initial load / preset / bulk / resync).
Lock-free but O(snapshot size) — never call per cell edit.
|
inlinenoexcept |
Pop the next pending edit command to apply. Lock-free, allocation-free.
|
inlinenoexcept |
Publish an applied echo.
Lock-free, allocation-free. Returns false if the applied FIFO is full — the engine must then publish a fresh Snapshot and call audio_mark_resync_required(snapshot.epoch) so the UI recovers instead of missing the lost echoes. (step_edit_reducer.hpp's drain_and_apply owns this recovery so producers never hand-roll it wrong.)
|
inlinenoexcept |
Debug-only single-UI-consumer guard.
The UI side claims the channel on bind and releases on unbind; a second concurrent claim trips an assert in the caller. No-op (always succeeds) in release builds.
|
inlinenoexcept |
|
inlinenoexcept |
|
inlinenoexcept |
|
inlinenoexcept |
The latest full snapshot.
Lock-free but O(snapshot size); call only when resyncing (see ui_resync_required_epoch), not every frame.
LIFETIME: the reference is valid only until the next ui_read_latest_snapshot call on this channel (TripleBuffer front-slot stability). Copy out anything you need to retain across reads.
|
inlinenoexcept |
Coherent read of the latest playhead. Lock-free, allocation-free.
|
inlinenoexcept |
|
inlinenoexcept |
Pop the next applied echo to replay onto the UI render copy, or nullopt.
Lock-free, allocation-free.
|
inlinenoexcept |
Submit an edit command.
Lock-free, allocation-free. Returns false if the command FIFO is full (the UI should coalesce / retry, never block).