Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::state::SequencerStateChannelT< Config > Class Template Reference

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.

Detailed Description

template<class Config>
class pulp::state::SequencerStateChannelT< Config >

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).

Member Typedef Documentation

◆ AppliedEdit

template<class Config>
using pulp::state::SequencerStateChannelT< Config >::AppliedEdit = AppliedEditT<Config>

◆ Command

template<class Config>
using pulp::state::SequencerStateChannelT< Config >::Command = StepEditCommandT<Config>

◆ ConfigType

template<class Config>
using pulp::state::SequencerStateChannelT< Config >::ConfigType = Config

◆ PatternState

template<class Config>
using pulp::state::SequencerStateChannelT< Config >::PatternState = PatternStateT<Config>

◆ Playhead

template<class Config>
using pulp::state::SequencerStateChannelT< Config >::Playhead = typename Config::playhead_type

◆ SetCellEdit

template<class Config>
using pulp::state::SequencerStateChannelT< Config >::SetCellEdit = SetCellEditT<Config>

◆ Snapshot

template<class Config>
using pulp::state::SequencerStateChannelT< Config >::Snapshot = SnapshotT<Config>

◆ StepRangeApplied

template<class Config>
using pulp::state::SequencerStateChannelT< Config >::StepRangeApplied = StepRangeAppliedT<Config>

Constructor & Destructor Documentation

◆ SequencerStateChannelT()

template<class Config>
pulp::state::SequencerStateChannelT< Config >::SequencerStateChannelT ( )
default

Member Function Documentation

◆ audio_mark_resync_required()

template<class Config>
void pulp::state::SequencerStateChannelT< Config >::audio_mark_resync_required ( Epoch epoch)
inlinenoexcept

Signal that incremental echoes were lost and the UI must resync to at least epoch.

Monotonic: a later resync request never lowers the bar. Publish the snapshot BEFORE calling this (reversing the order live-locks the UI into repeated resyncs until the matching-epoch snapshot lands).

◆ audio_publish_playhead()

template<class Config>
void pulp::state::SequencerStateChannelT< Config >::audio_publish_playhead ( const Playhead & playhead)
inlinenoexcept

Publish the latest playhead. Lock-free, allocation-free; call per block.

◆ audio_publish_snapshot()

template<class Config>
void pulp::state::SequencerStateChannelT< Config >::audio_publish_snapshot ( const Snapshot & snapshot)
inlinenoexcept

Publish the full authoritative snapshot (initial load / preset / bulk / resync).

Lock-free but O(snapshot size) — never call per cell edit.

◆ audio_try_pop_command()

template<class Config>
std::optional< Command > pulp::state::SequencerStateChannelT< Config >::audio_try_pop_command ( )
inlinenoexcept

Pop the next pending edit command to apply. Lock-free, allocation-free.

◆ audio_try_publish_applied()

template<class Config>
bool pulp::state::SequencerStateChannelT< Config >::audio_try_publish_applied ( const AppliedEdit & edit)
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.)

◆ debug_claim_ui_consumer()

template<class Config>
bool pulp::state::SequencerStateChannelT< Config >::debug_claim_ui_consumer ( )
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.

◆ debug_release_ui_consumer()

template<class Config>
void pulp::state::SequencerStateChannelT< Config >::debug_release_ui_consumer ( )
inlinenoexcept

◆ ui_applied_telemetry()

template<class Config>
runtime::SpscQueueTelemetry pulp::state::SequencerStateChannelT< Config >::ui_applied_telemetry ( ) const
inlinenoexcept

◆ ui_command_telemetry()

template<class Config>
runtime::SpscQueueTelemetry pulp::state::SequencerStateChannelT< Config >::ui_command_telemetry ( ) const
inlinenoexcept

◆ ui_read_latest_snapshot()

template<class Config>
const Snapshot & pulp::state::SequencerStateChannelT< Config >::ui_read_latest_snapshot ( )
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.

◆ ui_read_playhead()

template<class Config>
Playhead pulp::state::SequencerStateChannelT< Config >::ui_read_playhead ( ) const
inlinenoexcept

Coherent read of the latest playhead. Lock-free, allocation-free.

◆ ui_resync_required_epoch()

template<class Config>
Epoch pulp::state::SequencerStateChannelT< Config >::ui_resync_required_epoch ( ) const
inlinenoexcept

The snapshot epoch the UI must reach before trusting incremental echoes again.

When this exceeds the UI's local snapshot epoch (or the applied FIFO overflow count moved), the UI must resync from ui_read_latest_snapshot and drop echoes with engine_sequence <= the snapshot's engine_sequence.

◆ ui_try_pop_applied()

template<class Config>
std::optional< AppliedEdit > pulp::state::SequencerStateChannelT< Config >::ui_try_pop_applied ( )
inlinenoexcept

Pop the next applied echo to replay onto the UI render copy, or nullopt.

Lock-free, allocation-free.

◆ ui_try_submit()

template<class Config>
bool pulp::state::SequencerStateChannelT< Config >::ui_try_submit ( const Command & command)
inlinenoexcept

Submit an edit command.

Lock-free, allocation-free. Returns false if the command FIFO is full (the UI should coalesce / retry, never block).


The documentation for this class was generated from the following file: