优化EntitySystem初始化逻辑/防止多次初始化

增加matcher和entitysystem的测试
This commit is contained in:
YHH
2025-07-30 15:42:19 +08:00
parent 01fa33e122
commit 65386ff731
13 changed files with 2685 additions and 5 deletions

View File

@@ -0,0 +1,129 @@
import { Scene } from '../../../src/ECS/Scene';
import { Entity } from '../../../src/ECS/Entity';
import { Component } from '../../../src/ECS/Component';
import { EntitySystem } from '../../../src/ECS/Systems/EntitySystem';
import { ComponentTypeManager } from '../../../src/ECS/Utils/ComponentTypeManager';
class TestComponent extends Component {
constructor(public value: number = 0) {
super();
}
}
class TrackingSystem extends EntitySystem {
public initializeCallCount = 0;
public onChangedCallCount = 0;
public trackedEntities: Entity[] = [];
public override initialize(): void {
// 必须先调用父类的initialize来检查防重复逻辑
const wasInitialized = (this as any)._initialized;
super.initialize();
// 只有在真正执行初始化时才增加计数
if (!wasInitialized) {
this.initializeCallCount++;
}
}
public override onChanged(entity: Entity): void {
this.onChangedCallCount++;
if (this.isInterestedEntity(entity)) {
if (!this.trackedEntities.includes(entity)) {
this.trackedEntities.push(entity);
}
} else {
const index = this.trackedEntities.indexOf(entity);
if (index !== -1) {
this.trackedEntities.splice(index, 1);
}
}
}
public isInterestedEntity(entity: Entity): boolean {
return entity.hasComponent(TestComponent);
}
}
describe('系统多次初始化问题测试', () => {
let scene: Scene;
let system: TrackingSystem;
beforeEach(() => {
ComponentTypeManager.instance.reset();
scene = new Scene();
system = new TrackingSystem();
});
test('系统被多次添加到场景 - 应该防止重复初始化', () => {
const entity = scene.createEntity('TestEntity');
entity.addComponent(new TestComponent(10));
// 第一次添加系统
scene.addEntityProcessor(system);
expect(system.initializeCallCount).toBe(1);
expect(system.trackedEntities.length).toBe(1);
expect(system.onChangedCallCount).toBe(1);
// 再次添加同一个系统 - 应该被忽略
scene.addEntityProcessor(system);
expect(system.initializeCallCount).toBe(1); // 不应该增加
expect(system.trackedEntities.length).toBe(1); // 实体不应该重复
expect(system.onChangedCallCount).toBe(1); // onChanged不应该重复调用
});
test('手动多次调用initialize - 应该防止重复处理', () => {
const entity = scene.createEntity('TestEntity');
entity.addComponent(new TestComponent(10));
scene.addEntityProcessor(system);
expect(system.initializeCallCount).toBe(1);
expect(system.trackedEntities.length).toBe(1);
expect(system.onChangedCallCount).toBe(1);
// 手动再次调用initialize - 应该被防止
system.initialize();
expect(system.initializeCallCount).toBe(1); // 不应该增加
expect(system.onChangedCallCount).toBe(1); // onChanged不应该重复调用
expect(system.trackedEntities.length).toBe(1);
});
test('系统被移除后重新添加 - 应该重新初始化', () => {
const entity = scene.createEntity('TestEntity');
entity.addComponent(new TestComponent(10));
// 添加系统
scene.addEntityProcessor(system);
expect(system.initializeCallCount).toBe(1);
expect(system.trackedEntities.length).toBe(1);
// 移除系统
scene.removeEntityProcessor(system);
// 重新添加系统 - 应该重新初始化
scene.addEntityProcessor(system);
expect(system.initializeCallCount).toBe(2); // 应该重新初始化
expect(system.trackedEntities.length).toBe(1);
});
test('多个实体的重复初始化应该被防止', () => {
// 创建多个实体
const entities = [];
for (let i = 0; i < 5; i++) {
const entity = scene.createEntity(`Entity${i}`);
entity.addComponent(new TestComponent(i));
entities.push(entity);
}
scene.addEntityProcessor(system);
expect(system.initializeCallCount).toBe(1);
expect(system.trackedEntities.length).toBe(5);
expect(system.onChangedCallCount).toBe(5);
// 手动再次初始化 - 应该被防止
system.initialize();
expect(system.initializeCallCount).toBe(1); // 不应该增加
expect(system.onChangedCallCount).toBe(5); // 不应该重复处理
expect(system.trackedEntities.length).toBe(5);
});
});