diff --git a/assets/libs/ecs/ECSEntity.ts b/assets/libs/ecs/ECSEntity.ts index 99f1798..3e6171a 100644 --- a/assets/libs/ecs/ECSEntity.ts +++ b/assets/libs/ecs/ECSEntity.ts @@ -269,7 +269,7 @@ export class ECSEntity { remove(ctor: CompType, isRecycle = true): void { const componentTypeId = typeof ctor === 'number' ? ctor : ctor.tid; const compName = typeof ctor === 'number' ? '' : ctor.compName; - + if (!this.mask.has(componentTypeId)) { return; } @@ -280,7 +280,7 @@ export class ECSEntity { } comp.ent = null!; - + if (isRecycle) { comp.reset(); @@ -296,7 +296,8 @@ export class ECSEntity { // 限制缓存组件数量,防止内存泄漏 if (this.compTid2Obj.size < ECSEntity.MAX_CACHE_COMP) { this.compTid2Obj.set(componentTypeId, comp); // 用于缓存显示对象组件 - } else { + } + else { // 超过限制,强制回收 console.warn(`实体 ${this.name} 缓存组件数量超过限制,强制回收组件 ${compName}`); comp.reset(); @@ -338,10 +339,10 @@ export class ECSEntity { // 移除实体上所有组件 this.compTid2Ctor.forEach(this._remove, this); destroyEntity(this); - + // 清理缓存的组件对象,防止内存泄漏 this.compTid2Obj.clear(); - + // 回收 mask 到对象池 this.mask.destroy(); } diff --git a/assets/module/common/CCEntity.ts b/assets/module/common/CCEntity.ts index f3f9bd0..869da9a 100644 --- a/assets/module/common/CCEntity.ts +++ b/assets/module/common/CCEntity.ts @@ -224,6 +224,10 @@ export abstract class CCEntity extends ecs.Entity { //@ts-ignore business.init(); this.businesss.set(cls, business); + + // 将业务逻辑组件直接附加到实体对象身上,方便直接获取 + Reflect.set(this, cls.name, business); + return business as T; } @@ -247,6 +251,9 @@ export abstract class CCEntity extends ecs.Entity { if (business) { business.destroy(); this.businesss.delete(cls); + + // 清理实体上的业务逻辑组件引用 + Reflect.set(this, cls.name, null); } } } diff --git a/assets/module/common/CCView.ts b/assets/module/common/CCView.ts index 19d1703..f8f67ad 100644 --- a/assets/module/common/CCView.ts +++ b/assets/module/common/CCView.ts @@ -43,7 +43,7 @@ export class RoleViewComp extends CCView { @ecs.register('LoadingView', false) export class LoadingViewComp extends CCView { protected mvvm = true; // 启用 MVVM 功能 - + data: LoadingData = { finished: 0, total: 0, @@ -70,15 +70,15 @@ export abstract class CCView extends GameComponent implement //#region MVVM 功能相关(仅在 mvvm = true 时使用) /** 是否启用 MVVM 功能(子类可覆盖为 true) */ - protected mvvm: boolean = false; - - /** + protected mvvm = false; + + /** * MVVM 绑定的标签,延迟初始化以节省内存 * 仅在启用 MVVM 时创建 */ protected tag?: string; - - /** + + /** * 需要绑定的私有数据 * 注意:子类应该显式初始化此属性 */ @@ -109,11 +109,11 @@ export abstract class CCView extends GameComponent implement // 优化:只在必要时替换点号,使用更快的 replaceAll(如果支持) this.tag = `_temp<${uuid.replace('.', '')}>`; VM.add(this.data!, this.tag); - + // 搜寻所有节点:找到 watch path const comps = this.getVMComponents(); const len = comps.length; - + // 优化:避免属性查找,缓存 tag const tag = this.tag; for (let i = 0; i < len; i++) { @@ -143,7 +143,7 @@ export abstract class CCView extends GameComponent implement // @ts-ignore - 优化:使用 any 类型避免多次类型转换 const vmComp: any = comp; const path: string = vmComp.watchPath; - + // 优化:使用严格相等避免类型转换 if (vmComp.templateMode === true) { const pathArr: string[] = vmComp.watchPathArr; @@ -171,20 +171,20 @@ export abstract class CCView extends GameComponent implement */ private getVMComponents(): Component[] { const comps = this.node.getComponentsInChildren(VMBase); - + // 优化:提前返回,避免不必要的计算 if (comps.length === 0) { return comps; } - + // 优化:只在有嵌套 CCView 时才获取 parents const parents = this.node.getComponentsInChildren(CCView); - + // 优化:使用数组长度判断,避免创建新数组 let hasNested = false; const len = parents.length; const myUuid = this.uuid; - + for (let i = 0; i < len; i++) { const p = parents[i]; if (p.uuid !== myUuid && p.mvvm) { @@ -219,7 +219,7 @@ export abstract class CCView extends GameComponent implement result.push(comps[i]); } } - + return result; } @@ -229,20 +229,20 @@ export abstract class CCView extends GameComponent implement console.error(`组件 ${this.name} 移除失败,实体不存在`); return; } - + if (this.tid < 0) { console.error(`组件 ${this.name} 移除失败,组件未注册 (tid=${this.tid})`); return; } - + const cct = ECSModel.compCtors[this.tid]; if (!cct) { console.error(`组件 ${this.name} 移除失败,组件构造函数不存在 (tid=${this.tid})`); return; } - + this.ent.removeUi(cct); - this.ent = null!; // 清空引用,避免内存泄漏 + this.ent = null!; // 清空引用,避免内存泄漏 } /** @@ -260,7 +260,7 @@ export abstract class CCView extends GameComponent implement // @ts-ignore - 优化:显式清空引用,帮助 GC this.tag = undefined; } - + // @ts-ignore - 优化:显式清空引用,帮助 GC this.data = undefined; } @@ -269,4 +269,4 @@ export abstract class CCView extends GameComponent implement } abstract reset(): void; -} \ No newline at end of file +}