fix: 收敛战斗内存增长并强化战斗结束清理
This commit is contained in:
@@ -12,6 +12,7 @@ import { FacSet, FightSet } from "../common/config/GameSet";
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { Monster } from "../hero/Mon";
|
||||
import { Skill } from "../skill/Skill";
|
||||
import { Tooltip } from "../skill/Tooltip";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
|
||||
@@ -184,7 +185,10 @@ export class MissionComp extends CCComp {
|
||||
mission_end(){
|
||||
// mLogger.log(this.debugMode, 'MissionComp', " mission_end")
|
||||
// 合并 FightEnd 逻辑:清理组件、停止游戏循环
|
||||
this.unscheduleAllCallbacks();
|
||||
smc.mission.play=false
|
||||
smc.mission.pause = false;
|
||||
smc.mission.in_fight = false;
|
||||
this.cleanComponents()
|
||||
this.clearBattlePools()
|
||||
this.node.active=false
|
||||
@@ -255,13 +259,18 @@ export class MissionComp extends CCComp {
|
||||
}
|
||||
|
||||
private cleanComponents() {
|
||||
// 优化销毁顺序:直接销毁实体,让ECS系统自动处理组件清理
|
||||
// 这样可以避免在组件reset方法中访问已经被销毁的实体引用
|
||||
const heroEntities: ecs.Entity[] = [];
|
||||
ecs.query(this.heroViewMatcher).forEach(entity => {
|
||||
heroEntities.push(entity);
|
||||
});
|
||||
heroEntities.forEach(entity => {
|
||||
entity.destroy();
|
||||
});
|
||||
|
||||
const skillEntities: ecs.Entity[] = [];
|
||||
ecs.query(this.skillViewMatcher).forEach(entity => {
|
||||
skillEntities.push(entity);
|
||||
});
|
||||
skillEntities.forEach(entity => {
|
||||
entity.destroy();
|
||||
});
|
||||
}
|
||||
@@ -269,6 +278,38 @@ export class MissionComp extends CCComp {
|
||||
private clearBattlePools() {
|
||||
Monster.clearPools();
|
||||
Skill.clearPools();
|
||||
Tooltip.clearPool();
|
||||
this.clearBattleSceneNodes();
|
||||
}
|
||||
|
||||
private clearBattleSceneNodes() {
|
||||
const scene = smc.map?.MapView?.scene;
|
||||
const layer = scene?.entityLayer?.node;
|
||||
if (!layer) return;
|
||||
const heroRoot = layer.getChildByName("HERO");
|
||||
const skillRoot = layer.getChildByName("SKILL");
|
||||
if (heroRoot) {
|
||||
for (let i = heroRoot.children.length - 1; i >= 0; i--) {
|
||||
heroRoot.children[i].destroy();
|
||||
}
|
||||
}
|
||||
if (skillRoot) {
|
||||
for (let i = skillRoot.children.length - 1; i >= 0; i--) {
|
||||
skillRoot.children[i].destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getBattleLayerNodeCount() {
|
||||
const scene = smc.map?.MapView?.scene;
|
||||
const layer = scene?.entityLayer?.node;
|
||||
if (!layer) return { heroNodes: 0, skillNodes: 0 };
|
||||
const heroRoot = layer.getChildByName("HERO");
|
||||
const skillRoot = layer.getChildByName("SKILL");
|
||||
return {
|
||||
heroNodes: heroRoot?.children.length || 0,
|
||||
skillNodes: skillRoot?.children.length || 0
|
||||
};
|
||||
}
|
||||
|
||||
/** 性能监控相关代码 */
|
||||
@@ -308,6 +349,8 @@ export class MissionComp extends CCComp {
|
||||
});
|
||||
const monPool = Monster.getPoolStats();
|
||||
const skillPool = Skill.getPoolStats();
|
||||
const tooltipPool = Tooltip.getPoolStats();
|
||||
const layerNodes = this.getBattleLayerNodeCount();
|
||||
const perf = (globalThis as any).performance;
|
||||
const heapBytes = perf && perf.memory ? perf.memory.usedJSHeapSize : 0;
|
||||
let heapMB = heapBytes > 0 ? heapBytes / 1024 / 1024 : -1;
|
||||
@@ -338,8 +381,8 @@ export class MissionComp extends CCComp {
|
||||
`Heap:${heapText}MB Δ:${heapDeltaText} Peak:${heapPeakText}\n` +
|
||||
`Trend:${this.heapTrendPerMinMB.toFixed(2)}MB/min\n` +
|
||||
`Perf dt:${(avgDt * 1000).toFixed(1)}ms fps:${fps.toFixed(1)}\n` +
|
||||
`Ent H:${heroCount} S:${skillCount}\n` +
|
||||
`Pool M:${monPool.total}(${monPool.paths}) K:${skillPool.total}(${skillPool.paths})`;
|
||||
`Ent H:${heroCount} S:${skillCount} N:${layerNodes.heroNodes}/${layerNodes.skillNodes}\n` +
|
||||
`Pool M:${monPool.total}(${monPool.paths}) K:${skillPool.total}(${skillPool.paths}) T:${tooltipPool.total}`;
|
||||
if (text === this.lastMemoryText) return;
|
||||
this.lastMemoryText = text;
|
||||
this.memoryLabel.string = text;
|
||||
|
||||
Reference in New Issue
Block a user