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:
2026-07-29 13:40:09 -04:00
parent 4831e0e172
commit f3be4d8cce
81 changed files with 970 additions and 1085 deletions
+51 -3
View File
@@ -1,9 +1,10 @@
// action_registry.cpp — shared registration plumbing (Q-W4 split of actions.cpp).
// See action_registry.h. Needs no REAPER API pointers: rec->Register is a member
// call on the dispatch struct REAPER hands the entry point.
// action_registry.cpp — shared registration plumbing (Q-W4) + the registration
// table (Q-W6). See action_registry.h. Needs no REAPER API pointers: rec->Register
// is a member call on the dispatch struct REAPER hands the entry point.
#include "shell/actions/action_registry.h"
#include <cstring>
#include <deque>
#include <string>
@@ -23,6 +24,18 @@ using version::channelCommandId;
// pointer for a given action.
std::deque<std::string> g_strStore;
// One registered table row: the row data plus the registry-owned registration
// artifacts (interned id, minted cmd, gaccel storage REAPER holds a pointer to).
// A std::deque so element addresses never move after push_back — REAPER keeps each
// &accel until the mirror-unregister.
struct TableEntry {
ActionTableRow row;
const char* id = nullptr; // interned channel-qualified command id
int cmd = 0; // minted command id (0 = mint failed / inert row)
gaccel_register_t accel{}; // Actions-list entry; address handed to REAPER
};
std::deque<TableEntry> g_table;
} // namespace
const char* channelIdFor(const char* suffix) {
@@ -46,4 +59,39 @@ int registerAction(reaper_plugin_info_t* rec, const char* suffix,
return cmd;
}
void registerActionTable(reaper_plugin_info_t* rec, const ActionTableRow* rows,
std::size_t count) {
for (std::size_t i = 0; i < count; ++i) {
g_table.push_back(TableEntry{rows[i]});
TableEntry& e = g_table.back();
e.id = channelIdFor(e.row.suffix);
e.cmd = registerAction(rec, e.row.suffix, e.accel, e.row.phrase);
}
}
bool actionTableHandleCommand(int command) {
if (command == 0) return false;
for (const TableEntry& e : g_table)
if (e.cmd != 0 && command == e.cmd) {
e.row.run(e.row.arg);
return true;
}
return false;
}
int actionTableCommandId(const char* suffix) {
for (const TableEntry& e : g_table)
if (std::strcmp(e.row.suffix, suffix) == 0) return e.cmd;
return 0;
}
void unregisterActionTable(reaper_plugin_info_t* rec) {
// Reverse table order, mirroring the register loop. Each '-command_id'
// re-presents the SAME interned pointer channelIdFor handed out at register.
for (auto it = g_table.rbegin(); it != g_table.rend(); ++it) {
rec->Register("-gaccel", (void*)&it->accel);
rec->Register("-command_id", (void*)it->id);
}
}
} // namespace reasampler