import type { GmPanelFactory, IGmCommand } from './GmTypes'; /** * GM 命令与内容面板注册表(普通对象,避免 Map)。 */ export class GmRegistry { private static _cmds: { [id: string]: IGmCommand } = {}; private static _panels: { [id: string]: GmPanelFactory } = {}; private static _order: string[] = []; /** * 批量注册命令;同 id 覆盖并告警。 */ static register(cmds: IGmCommand[]): void { for (let i = 0; i < cmds.length; i++) { const c = cmds[i]; if (!c?.id) { console.warn('[GmRegistry] 跳过无 id 命令'); continue; } if (this._cmds[c.id]) { console.warn('[GmRegistry] 覆盖命令', c.id); } else { this._order.push(c.id); } this._cmds[c.id] = c; } } /** * 注销单条命令。 */ static unregister(id: string): void { if (!this._cmds[id]) { console.warn('[GmRegistry] 注销不存在的命令', id); return; } delete this._cmds[id]; const idx = this._order.indexOf(id); if (idx >= 0) this._order.splice(idx, 1); } /** * 注册内容面板工厂。 */ static registerPanel(panelId: string, factory: GmPanelFactory): void { if (!panelId || !factory) { console.warn('[GmRegistry] registerPanel 参数无效'); return; } if (this._panels[panelId]) { console.warn('[GmRegistry] 覆盖面板', panelId); } this._panels[panelId] = factory; } /** * 取面板工厂。 */ static getPanelFactory(panelId: string): GmPanelFactory | null { return this._panels[panelId] ?? null; } /** * 按分组取出命令(已排序)。 */ static listByGroup(group: string): IGmCommand[] { const out: IGmCommand[] = []; for (let i = 0; i < this._order.length; i++) { const c = this._cmds[this._order[i]]; if (c && c.group === group) out.push(c); } out.sort((a, b) => (a.order ?? 0) - (b.order ?? 0)); return out; } /** * 所有出现过的分组名(保持首次注册顺序)。 */ static listGroups(): string[] { const groups: string[] = []; for (let i = 0; i < this._order.length; i++) { const c = this._cmds[this._order[i]]; if (!c) continue; if (groups.indexOf(c.group) < 0) groups.push(c.group); } return groups; } /** * 是否已有命令。 */ static hasCommands(): boolean { return this._order.length > 0; } /** * 清空(测试 / 热重载)。 */ static clear(): void { this._cmds = {}; this._panels = {}; this._order = []; } }