You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
AdLike2048/assets/mx/module/gm/GmRegistry.ts

105 lines
2.9 KiB

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 = [];
}
}