From fca918c47c54cbcdbeee4f3503f71a7e851d079a Mon Sep 17 00:00:00 2001 From: dgflash Date: Sun, 22 Feb 2026 21:24:44 +0800 Subject: [PATCH] =?UTF-8?q?CCEntity.addUi=E4=B8=8ECCEntity.removeUi?= =?UTF-8?q?=E6=94=AF=E6=8C=81CCView=E4=B8=8EGameComponent=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=E7=95=8C=E9=9D=A2=E6=89=93=E5=BC=80=E4=B8=8E?= =?UTF-8?q?=E7=A7=BB=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/module/common/CCEntity.ts | 43 ++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/assets/module/common/CCEntity.ts b/assets/module/common/CCEntity.ts index 869da9a..3f6cab0 100644 --- a/assets/module/common/CCEntity.ts +++ b/assets/module/common/CCEntity.ts @@ -12,11 +12,21 @@ import type { CCBusiness } from './CCBusiness'; import type { CCView } from './CCView'; import { GameComponent } from './GameComponent'; +/** ECS 组件构造函数类型(用于继承自 ecs.Comp 的组件) */ type ECSCtor = | __private.__types_globals__Constructor | __private.__types_globals__AbstractedConstructor; -type ECSView = CCView; +/** UI 组件构造函数类型(用于继承自 GameComponent 并使用 gui.register 注册的组件) */ +type UICtor = + | __private.__types_globals__Constructor + | __private.__types_globals__AbstractedConstructor; +/** ECS 游戏视图组件类型(继承自 CCView,用于完整的 ECS 组件) */ +export type ECSView = CCView; +/** GUI 视图组件类型(继承自 GameComponent,使用 @gui.register 装饰器注册的组件) */ +export type GUIView = GameComponent; +/** ECS 实体构造函数类型 */ type EntityCtor = new (...args: any[]) => T; +/** ECS 业务逻辑组件构造函数类型 */ type BusinessCtor = CCBusiness> = new (...args: any[]) => T; /** ECS 游戏模块实体 */ @@ -123,11 +133,11 @@ export abstract class CCEntity extends ecs.Entity { /** * 添加视图层组件 - * @param ctor 界面逻辑组件 + * @param ctor 界面逻辑组件(支持 CCView 或使用 gui.register 注册的 GameComponent 子类) * @param params 界面参数 * @returns 界面节点 */ - async addUi(ctor: ECSCtor, params?: UIParam): Promise { + async addUi(ctor: UICtor, params?: UIParam): Promise { const key = gui.internal.getKey(ctor); if (!key) { throw new Error(`${ctor.name} 界面组件未使用 gui.register 注册`); @@ -146,21 +156,18 @@ export abstract class CCEntity extends ecs.Entity { } const node = await oops.gui.open(key, params); - const comp = node.getComponent(ctor) as ecs.Comp; - if (!comp) { - throw new Error(`界面节点上未找到组件 ${ctor.name}`); - } + const comp = node.getComponent(ctor) as unknown as ecs.Comp; + if (comp) this.add(comp); - this.add(comp); oops.gui.show(key); return node; } /** * 移除视图层组件 - * @param ctor 界面逻辑组件 + * @param ctor 界面逻辑组件(支持 CCView 或使用 gui.register 注册的 GameComponent 子类) */ - removeUi(ctor: CompType) { + removeUi(ctor: UICtor) { const key = gui.internal.getKey(ctor); if (key) { @@ -170,12 +177,15 @@ export abstract class CCEntity extends ecs.Entity { return; } - const comp = node.getComponent(LayerUIElement); - if (comp) { + const layer = node.getComponent(LayerUIElement); + if (layer) { // 处理界面关闭动画播放完成后,移除ECS组件,避免使用到组件实体数据还在动画播放时在使用导致的空对象问题 - comp.onClose = () => { + layer.onClose = () => { try { - this.remove(ctor); + const view = node.getComponent(ctor) as unknown as ecs.Comp; + if (view) { + this.remove(ctor as unknown as CompType); + } } catch (error) { console.error(`移除界面组件失败: ${key}`, error); @@ -185,11 +195,12 @@ export abstract class CCEntity extends ecs.Entity { } else { // 没有 LayerUIElement,直接移除 - this.remove(ctor); + this.remove(ctor as unknown as CompType); } } else { - this.remove(ctor); + // 组件未使用 gui.register 注册,尝试直接移除 + this.remove(ctor as unknown as CompType); } } //#endregion