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/GmShell.ts

111 lines
2.7 KiB

1 day ago
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;
}
}
}