78 return visible_cache_[
index(lane, step)];
81 return last_engine_sequence_;
138 std::size_t
index(std::uint8_t lane, std::uint8_t step)
const {
139 return static_cast<std::size_t
>(lane) * steps_ + step;
142 visible_cache_[
index(lane, step)] =
v;
145 pump_dirty_cells_.push_back(
Cell{lane, step});
160 return next_client_seq_++;
163 needs_initial_resync_ =
true;
172 std::uint8_t lanes_, steps_, patterns_;
174 void subscribe_probe();
175 void unsubscribe_probe();
178 std::vector<CellVisual> visible_cache_;
181 bool needs_initial_resync_ =
true;
184 std::vector<Cell> pump_dirty_cells_;
185 bool pump_full_ =
false;
188 std::uint8_t playhead_step_ = 0;
189 std::uint8_t playhead_pattern_ = 0;
190 bool playhead_visible_ =
false;
193 bool dragging_ =
false;
194 bool drag_sets_enabled_ =
true;
195 std::optional<Cell> last_drag_cell_{};
212 static_assert(
sizeof(Cell) == 0,
213 "Provide a CellPolicy<YourCell> with static visual(const Cell&, "
214 "bool muted) -> StepGridViewBase::CellVisual and static "
215 "make_set_cell(const Cell&, bool enabled) -> Cell.");
222 v.intensity = std::clamp(
c.velocity / 127.0f, 0.0f, 1.0f);
233 c.flags =
static_cast<std::uint8_t
>(
c.flags &
~state::StepCell::kEnabledBit);
240template <
class Config,
class CellPolicy = DefaultCellPolicy<
typename Config::cell_type>>
248 static_cast<
std::uint8_t>(Config::
steps),
256 channel_->debug_release_ui_consumer();
265 channel_->debug_release_ui_consumer();
268 const bool claimed = channel_->debug_claim_ui_consumer();
271 assert(claimed &&
"another StepGridView already consumes this channel");
285 return channel_ !=
nullptr;
289 return channel_->ui_resync_required_epoch();
293 render_ = channel_->ui_read_latest_snapshot();
295 return {render_.epoch, render_.engine_sequence,
n};
299 auto e = channel_->ui_try_pop_applied();
302 if (
e->engine_sequence <= min_exclusive)
311 const auto& sr =
e->payload.step_range;
314 auto& lane = render_.patterns[sr.pattern].lanes[sr.lane];
315 for (std::uint8_t
i = 0;
i < sr.step_count; ++
i) {
316 std::uint8_t step =
static_cast<std::uint8_t
>(sr.first_step +
i);
319 lane[step] = sr.cells[
i];
323 for (std::uint8_t
i = 0;
i < sr.step_count; ++
i) {
324 std::uint8_t step =
static_cast<std::uint8_t
>(sr.first_step +
i);
327 set_visible(sr.lane, step, visual_for(lane[step], step));
334 const auto& pl =
e->payload.pattern_length;
337 render_.patterns[pl.pattern].length = pl.length;
345 render_.active_pattern =
e->payload.active_pattern.pattern;
356 const auto ph = channel_->ui_read_playhead();
357 return {ph.active_pattern, ph.active_step, ph.playing != 0};
363 for (std::uint8_t lane = 0; lane <
lanes(); ++lane)
364 for (std::uint8_t step = 0; step <
steps(); ++step) {
365 set_visible(lane, step, visual_for(pat.lanes[lane][step], step));
373 if (!channel_ || lane >=
lanes() || step >=
steps())
387 channel_->ui_try_submit(cmd);
391 CellVisual visual_for(
const typename Config::cell_type&
c, std::uint8_t step)
const {
393 return CellPolicy::visual(
c, muted);
Definition canvas.hpp:240
Ownership: the engine (audio) thread is the single reader of the command queue and the single writer ...
Definition sequencer_state_channel.hpp:301
StepEditCommandT< Config > Command
Definition sequencer_state_channel.hpp:306
SnapshotT< Config > Snapshot
Definition sequencer_state_channel.hpp:304
SetCellEditT< Config > SetCellEdit
Definition sequencer_state_channel.hpp:309
Definition frame_clock.hpp:14
virtual ResyncPoint resync_from_snapshot()=0
Replace the render copy from the channel's latest snapshot and rebuild the whole visible cache; retur...
void request_initial_resync()
Definition step_grid_view.hpp:162
virtual int rebuild_visible()=0
Rebuild the whole visible cache for the displayed pattern; return the count.
state::EngineSequence last_engine_sequence() const
Definition step_grid_view.hpp:80
Rect playhead_column_rect(std::uint8_t step) const
void on_mouse_down(Point pos) override
void on_mouse_up(Point pos) override
void set_displayed_pattern(std::uint8_t pattern)
Which pattern is shown/edited.
state::ClientSequence next_client_sequence()
Definition step_grid_view.hpp:159
virtual PlayheadProjection read_playhead() const =0
void paint(canvas::Canvas &canvas) override
EchoStatus
Definition step_grid_view.hpp:102
@ Applied
Definition step_grid_view.hpp:102
@ SkippedStale
Definition step_grid_view.hpp:102
@ Drained
Definition step_grid_view.hpp:102
std::uint8_t lanes() const
Definition step_grid_view.hpp:147
std::uint8_t steps() const
Definition step_grid_view.hpp:150
std::size_t index(std::uint8_t lane, std::uint8_t step) const
Definition step_grid_view.hpp:138
std::uint8_t displayed_pattern() const
Definition step_grid_view.hpp:69
Rect cell_rect(std::uint8_t lane, std::uint8_t step) const
virtual void submit_set_cell(std::uint8_t lane, std::uint8_t step, bool enabled, state::GesturePhase)=0
virtual bool channel_bound() const =0
virtual EchoResult apply_next_echo(state::EngineSequence min_exclusive)=0
Pop the next applied echo.
std::uint8_t displayed_pattern_
Definition step_grid_view.hpp:169
void on_frame_clock_changed() override
The FrameClock reachable from this view (via frame_clock()) may have changed — a clock was installed ...
StepGridViewBase(std::uint8_t lanes, std::uint8_t steps, std::uint8_t patterns)
state::EditTransactionId current_txn() const
Definition step_grid_view.hpp:156
virtual state::Epoch channel_resync_required_epoch() const =0
bool wants_mouse_input() const override
True if this widget handles mouse down/drag through virtual methods even when it does not expose JS p...
Definition step_grid_view.hpp:89
~StepGridViewBase() override
PumpResult pump()
Drain the channel and update the render copy + visual cache.
void record_dirty(std::uint8_t lane, std::uint8_t step)
Definition step_grid_view.hpp:144
void set_visible(std::uint8_t lane, std::uint8_t step, const CellVisual &v)
Definition step_grid_view.hpp:141
std::optional< Cell > cell_at(Point pos) const
void detach_probe()
The shim MUST call this in its destructor (before its typed members die) so the FrameClock probe can'...
void on_mouse_drag(Point pos) override
const CellVisual & cell_visual(std::uint8_t lane, std::uint8_t step) const
Definition step_grid_view.hpp:77
std::uint8_t patterns() const
Definition step_grid_view.hpp:153
Definition step_grid_view.hpp:241
int rebuild_visible() override
Rebuild the whole visible cache for the displayed pattern; return the count.
Definition step_grid_view.hpp:360
void set_channel(Channel *channel)
Bind the channel this view reads/writes.
Definition step_grid_view.hpp:261
const Snapshot & render_snapshot() const
Definition step_grid_view.hpp:279
EchoResult apply_next_echo(state::EngineSequence min_exclusive) override
Pop the next applied echo.
Definition step_grid_view.hpp:298
PlayheadProjection read_playhead() const override
Definition step_grid_view.hpp:353
~StepGridViewT() override
Definition step_grid_view.hpp:251
typename Channel::Snapshot Snapshot
Definition step_grid_view.hpp:244
ResyncPoint resync_from_snapshot() override
Replace the render copy from the channel's latest snapshot and rebuild the whole visible cache; retur...
Definition step_grid_view.hpp:292
bool channel_bound() const override
Definition step_grid_view.hpp:284
state::SequencerStateChannelT< Config > Channel
Definition step_grid_view.hpp:243
void submit_set_cell(std::uint8_t lane, std::uint8_t step, bool enabled, state::GesturePhase phase) override
Definition step_grid_view.hpp:371
state::Epoch channel_resync_required_epoch() const override
Definition step_grid_view.hpp:288
Channel * channel() const
Definition step_grid_view.hpp:275
StepGridViewT()
Definition step_grid_view.hpp:246
bool enabled() const
CSS :disabled equivalent — blocks input, reduces opacity.
Definition view.hpp:715
Definition affine_transform.hpp:24
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
std::uint64_t ClientSequence
Definition sequencer_state_channel.hpp:62
std::uint32_t EditTransactionId
Definition sequencer_state_channel.hpp:63
@ CommandRejected
Definition sequencer_state_channel.hpp:265
@ PatternLengthChanged
Definition sequencer_state_channel.hpp:263
@ ActivePatternChanged
Definition sequencer_state_channel.hpp:264
@ StepRangeChanged
Definition sequencer_state_channel.hpp:262
std::uint64_t EngineSequence
Definition sequencer_state_channel.hpp:61
@ SetCell
Definition sequencer_state_channel.hpp:166
std::uint64_t Epoch
Definition sequencer_state_channel.hpp:60
GesturePhase
Host-undo gesture bracketing hint.
Definition sequencer_state_channel.hpp:177
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
StepGridViewT< state::ReferenceSequencerConfig > StepGridView
Definition step_grid_view.hpp:401
@ c
Definition input_events.hpp:39
@ n
Definition input_events.hpp:40
@ i
Definition input_events.hpp:40
@ v
Definition input_events.hpp:41
@ e
Definition input_events.hpp:39
One step in one lane.
Definition sequencer_state_channel.hpp:69
static constexpr std::uint8_t kEnabledBit
Definition sequencer_state_channel.hpp:78
StepEditKind kind
Definition sequencer_state_channel.hpp:215
ClientSequence client_sequence
Definition sequencer_state_channel.hpp:212
EditTransactionId transaction_id
Definition sequencer_state_channel.hpp:213
GesturePhase gesture_phase
Definition sequencer_state_channel.hpp:214
union pulp::state::StepEditCommandT::Payload payload
static StepGridViewBase::CellVisual visual(const state::StepCell &c, bool muted)
Definition step_grid_view.hpp:219
static state::StepCell make_set_cell(const state::StepCell &old, bool enabled)
Definition step_grid_view.hpp:226
Primary template is deliberately undefined-usable: a custom cell type must supply its own CellPolicy ...
Definition step_grid_view.hpp:211
Definition geometry.hpp:20
Axis-aligned rectangle in continuous (float) coordinates.
Definition geometry.hpp:52
Precomputed per-cell visual, recomputed only for dirtied regions.
Definition step_grid_view.hpp:43
bool enabled
Definition step_grid_view.hpp:44
bool muted
Definition step_grid_view.hpp:46
float intensity
Definition step_grid_view.hpp:45
Definition step_grid_view.hpp:59
std::uint8_t lane
Definition step_grid_view.hpp:60
std::uint8_t step
Definition step_grid_view.hpp:61
Definition step_grid_view.hpp:103
int rebuilt_cells
Definition step_grid_view.hpp:107
bool full_rebuild
Definition step_grid_view.hpp:106
EchoStatus status
Definition step_grid_view.hpp:104
state::EngineSequence engine_sequence
Definition step_grid_view.hpp:105
Definition step_grid_view.hpp:114
std::uint8_t active_pattern
Definition step_grid_view.hpp:115
std::uint8_t active_step
Definition step_grid_view.hpp:116
bool playing
Definition step_grid_view.hpp:117
Result of one pump(), surfaced for headless tests (a hostless view cannot observe request_repaint()).
Definition step_grid_view.hpp:51
int echoes_applied
Definition step_grid_view.hpp:55
bool requested_repaint
Definition step_grid_view.hpp:52
bool resynced
Definition step_grid_view.hpp:56
bool full_rebuild
Definition step_grid_view.hpp:53
int rebuilt_cells
Definition step_grid_view.hpp:54
Definition step_grid_view.hpp:109
state::EngineSequence engine_sequence
Definition step_grid_view.hpp:111
state::Epoch epoch
Definition step_grid_view.hpp:110
int rebuilt_cells
Definition step_grid_view.hpp:112
SetCellEditT< Config > set_cell
Definition sequencer_state_channel.hpp:218