import { Director, director, isValid } from 'cc'; import type { IGmHost } from './GmTypes'; import { GmBuiltinPanels } from './GmBuiltinPanels'; import { GmView } from './GmView'; /** * GM 壳入口:show/hide,挂 Debug 层。 */ export class GmShell { private static _host: IGmHost | null = null; private static _view: GmView | null = null; private static _visible = false; /** * 注入宿主并注册内置面板。 */ static bindHost(host: IGmHost): void { if (!host) { console.warn('[GmShell] bindHost 收到空 host'); return; } this._host = host; GmBuiltinPanels.ensureRegistered(); } /** * 当前是否可见。 */ static get visible(): boolean { return this._visible; } /** * 切换显示。 */ static show(): void { if (!this._host) { console.warn('[GmShell] 未 bindHost,无法打开'); return; } if (!this._host.isEnabled()) { console.warn('[GmShell] Host 禁用 GM'); return; } this._visible = !this._visible; if (!this._visible) { this._hideView(); return; } if (this._view && isValid(this._view.root)) { this._view.root.active = true; this._layoutView(); this._view.refresh(); return; } this._view = new GmView(this._host, () => { this._visible = false; this._hideView(); }); this._host.attachOverlay(this._view.root); this._layoutView(); } /** 当帧 + 下一帧各铺一次,确保吃到父节点真实尺寸 */ private static _layoutView(): void { this._view?.layoutFullscreen(); director.once(Director.EVENT_AFTER_UPDATE, () => { if (this._view && isValid(this._view.root) && this._visible) { this._view.layoutFullscreen(); } }); } /** * 强制关闭。 */ static hide(): void { this._visible = false; this._hideView(); } /** * 刷新列表(命令变更后)。 */ static refresh(): void { if (this._view && isValid(this._view.root) && this._visible) { this._view.refresh(); } } private static _hideView(): void { if (this._view && isValid(this._view.root)) { this._view.root.active = false; } } /** * 销毁壳(切场景等)。 */ static destroy(): void { this._visible = false; if (this._view) { this._view.destroy(); this._view = null; } } }