Q-W6: registration table (OCP) in main.cpp; bank verbs -> shell/bank_ops(Session&); persist.h + wav_trim + namespaces.h shims deleted; 61/61
capture.h realtime seam split to capture_realtime_shell.h; GetProjExtState grow-loop rehomed to core/wire/ext_state_read; stale persist.cpp/bank_panel.cpp comment refs fixed; CLAUDE.md persist/bank_book/actions bullets updated. Command-id suffixes, display phrases, and undo labels byte-identical.
This commit is contained in:
@@ -1,13 +1,30 @@
|
||||
#pragma once
|
||||
// action_registry — shared registration plumbing for the bindable action families
|
||||
// (Q-W4 split of actions.cpp). Owns the durable interned-string store both the
|
||||
// Design View and multi-bank families register through, so a composed command id
|
||||
// keeps ONE stable pointer from register to the mirror-unregister, and the
|
||||
// register-a-command_id-then-gaccel sequence has one implementation.
|
||||
// action_registry — shared registration plumbing + the Q-W6 registration TABLE.
|
||||
//
|
||||
// Two layers, one TU:
|
||||
//
|
||||
// * The Q-W4 plumbing (channelIdFor / registerAction): the durable interned-string
|
||||
// store the action families register through, so a composed command id keeps ONE
|
||||
// stable pointer from register to the mirror-unregister, and the
|
||||
// register-a-command_id-then-gaccel sequence has one implementation. The
|
||||
// design_view / bank / ingest families still register row-by-row through this.
|
||||
//
|
||||
// * The Q-W6 registration TABLE (ActionTableRow + registerActionTable /
|
||||
// actionTableHandleCommand / actionTableCommandId / unregisterActionTable): the
|
||||
// data-driven home of main.cpp's own action family (capture scopes, panel toggle,
|
||||
// insert, batch, realtime, recapture, version). One row = one action (FOREVER-
|
||||
// STABLE id suffix, display phrase, flat function-pointer handler); registration
|
||||
// iterates the rows, hookcommand dispatch walks the same rows, and unload
|
||||
// mirror-unregisters from them — adding an action touches the table only (OCP).
|
||||
// Handlers are plain function pointers (a static dispatch walk, no std::function,
|
||||
// no virtual — the §3 performance guardrail); gaccel + interned-id storage is
|
||||
// owned here for the module lifetime, so REAPER's held pointers stay valid and
|
||||
// the '-command_id' unregister re-presents the IDENTICAL pointer registered.
|
||||
//
|
||||
// Includes reaper_plugin.h (gaccel_register_t / reaper_plugin_info_t full defs);
|
||||
// only the action-family TUs include this header. Q-W6's registration table
|
||||
// subsumes this helper when the hand-written blocks become data.
|
||||
// only the action-family TUs and main.cpp include this header.
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "reaper_plugin.h" // reaper_plugin_info_t, gaccel_register_t
|
||||
|
||||
@@ -26,4 +43,41 @@ const char* channelIdFor(const char* suffix);
|
||||
int registerAction(reaper_plugin_info_t* rec, const char* suffix,
|
||||
gaccel_register_t& accel, const char* phrase);
|
||||
|
||||
// --- The registration table (Q-W6) -------------------------------------------
|
||||
|
||||
// One bindable action. `suffix` and `phrase` are the channel-AGNOSTIC pieces (the
|
||||
// registry composes the full id/label via channelCommandId / channelActionName);
|
||||
// both must have static storage duration (string literals, or a pure static table
|
||||
// like captureActionTable()). `run` fires when the minted command does; `arg` is an
|
||||
// opaque per-row value passed through to it (e.g. a captureActionTable row index, or
|
||||
// a bool-like flag), so sibling actions can share one handler without captures.
|
||||
struct ActionTableRow {
|
||||
const char* suffix; // FOREVER-STABLE command-id suffix — never change shipped
|
||||
const char* phrase; // Actions-list display phrase (after the channel prefix)
|
||||
void (*run)(int arg); // handler — a flat function pointer, no state
|
||||
int arg = 0; // opaque per-row handler argument
|
||||
};
|
||||
|
||||
// Registers every row (command_id -> gaccel, via the same interning plumbing as
|
||||
// registerAction) in table order. Rows are COPIED into registry-owned storage whose
|
||||
// element addresses never move (REAPER holds each gaccel pointer until unload).
|
||||
// Call once at load; a failed command_id mint (cmd 0) leaves that row inert but
|
||||
// still mirror-unregistered on unload (harmless, matches the pre-table behavior).
|
||||
void registerActionTable(reaper_plugin_info_t* rec, const ActionTableRow* rows,
|
||||
std::size_t count);
|
||||
|
||||
// Dispatches one fired command: fires the matching row's handler and returns true;
|
||||
// false when the command belongs to no table row (caller's hookcommand keeps
|
||||
// looking, per the claim-only contract). A flat walk over the registered rows.
|
||||
bool actionTableHandleCommand(int command);
|
||||
|
||||
// The minted command id for `suffix` (0 when unregistered / mint failed). For the
|
||||
// callers that need a raw command id outside dispatch — e.g. the toggleaction
|
||||
// checked-state hook resolving TOGGLE_BANK_PANEL once at load.
|
||||
int actionTableCommandId(const char* suffix);
|
||||
|
||||
// Mirror-unregisters every table row (reverse table order): '-gaccel' with the same
|
||||
// held storage, '-command_id' with the SAME interned pointer used at register.
|
||||
void unregisterActionTable(reaper_plugin_info_t* rec);
|
||||
|
||||
} // namespace reasampler
|
||||
|
||||
Reference in New Issue
Block a user