#pragma once // action_registry — shared REAPER registration plumbing, plus a data-driven action // table (ActionTableRow) so adding an action means adding one row, not touching // register/dispatch/unregister separately (OCP). Interned command-id/label strings // persist for the module lifetime: REAPER holds those pointers, and an unregister // must re-present the SAME one. Handlers are flat function pointers, never // std::function/virtual (hot-path-adjacent dispatch discipline). #include #include "reaper_plugin.h" // reaper_plugin_info_t, gaccel_register_t namespace reasampler { // Interns the channel-qualified command id for `suffix` once per process, so a // '-command_id' unregister presents the IDENTICAL pointer registered earlier. const char* channelIdFor(const char* suffix); // Mints a command id from `suffix`, registers its gaccel with label `phrase`. // Returns the id (0 on failure); gaccel storage is caller-owned. int registerAction(reaper_plugin_info_t* rec, const char* suffix, gaccel_register_t& accel, const char* phrase); // --- The registration table --------------------------------------------------- // `suffix`/`phrase` are channel-agnostic and must have static storage duration. // `arg` is an opaque per-row value so sibling actions can share one handler. 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 }; // Rows are copied into registry-owned storage whose addresses never move (REAPER // holds each gaccel pointer until unload). void registerActionTable(reaper_plugin_info_t* rec, const ActionTableRow* rows, std::size_t count); bool actionTableHandleCommand(int command); // 0 when unregistered / mint failed — for callers needing a raw id outside dispatch // (e.g. the toggleaction checked-state hook). int actionTableCommandId(const char* suffix); // Mirror-unregisters every table row (reverse order): '-gaccel' with the held // storage, '-command_id' with the SAME interned pointer used at register. void unregisterActionTable(reaper_plugin_info_t* rec); } // namespace reasampler