整合组件类型至统一的componentregistry中
This commit is contained in:
@@ -1,333 +0,0 @@
|
||||
import { BitMaskOptimizer } from '../../../src/ECS/Core/BitMaskOptimizer';
|
||||
import { BigIntFactory } from '../../../src/ECS/Utils/BigIntCompatibility';
|
||||
|
||||
describe('BitMaskOptimizer - 位掩码优化器测试', () => {
|
||||
let optimizer: BitMaskOptimizer;
|
||||
|
||||
beforeEach(() => {
|
||||
optimizer = BitMaskOptimizer.getInstance();
|
||||
optimizer.reset(); // 确保每个测试开始时都是干净的状态
|
||||
});
|
||||
|
||||
describe('单例模式测试', () => {
|
||||
it('应该返回同一个实例', () => {
|
||||
const instance1 = BitMaskOptimizer.getInstance();
|
||||
const instance2 = BitMaskOptimizer.getInstance();
|
||||
expect(instance1).toBe(instance2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('组件类型注册', () => {
|
||||
it('应该能够注册组件类型', () => {
|
||||
const id = optimizer.registerComponentType('Transform');
|
||||
expect(id).toBe(0);
|
||||
});
|
||||
|
||||
it('重复注册相同组件应该返回相同ID', () => {
|
||||
const id1 = optimizer.registerComponentType('Transform');
|
||||
const id2 = optimizer.registerComponentType('Transform');
|
||||
expect(id1).toBe(id2);
|
||||
});
|
||||
|
||||
it('应该能够注册多个不同组件类型', () => {
|
||||
const id1 = optimizer.registerComponentType('Transform');
|
||||
const id2 = optimizer.registerComponentType('Velocity');
|
||||
const id3 = optimizer.registerComponentType('Health');
|
||||
|
||||
expect(id1).toBe(0);
|
||||
expect(id2).toBe(1);
|
||||
expect(id3).toBe(2);
|
||||
});
|
||||
|
||||
it('应该能够获取已注册组件的类型ID', () => {
|
||||
optimizer.registerComponentType('Transform');
|
||||
const id = optimizer.getComponentTypeId('Transform');
|
||||
expect(id).toBe(0);
|
||||
});
|
||||
|
||||
it('获取未注册组件的类型ID应该返回undefined', () => {
|
||||
const id = optimizer.getComponentTypeId('UnknownComponent');
|
||||
expect(id).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('单组件掩码创建', () => {
|
||||
beforeEach(() => {
|
||||
optimizer.registerComponentType('Transform');
|
||||
optimizer.registerComponentType('Velocity');
|
||||
});
|
||||
|
||||
it('应该能够创建单个组件的掩码', () => {
|
||||
const mask = optimizer.createSingleComponentMask('Transform');
|
||||
expect(mask.toString()).toBe('1');
|
||||
});
|
||||
|
||||
it('不同组件应该有不同的掩码', () => {
|
||||
const transformMask = optimizer.createSingleComponentMask('Transform');
|
||||
const velocityMask = optimizer.createSingleComponentMask('Velocity');
|
||||
|
||||
expect(transformMask.toString()).toBe('1');
|
||||
expect(velocityMask.toString()).toBe('2');
|
||||
});
|
||||
|
||||
it('创建未注册组件的掩码应该抛出错误', () => {
|
||||
expect(() => {
|
||||
optimizer.createSingleComponentMask('UnknownComponent');
|
||||
}).toThrow('Component type not registered: UnknownComponent');
|
||||
});
|
||||
|
||||
it('相同组件的掩码应该使用缓存', () => {
|
||||
const mask1 = optimizer.createSingleComponentMask('Transform');
|
||||
const mask2 = optimizer.createSingleComponentMask('Transform');
|
||||
expect(mask1).toBe(mask2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('组合掩码创建', () => {
|
||||
beforeEach(() => {
|
||||
optimizer.registerComponentType('Transform');
|
||||
optimizer.registerComponentType('Velocity');
|
||||
optimizer.registerComponentType('Health');
|
||||
});
|
||||
|
||||
it('应该能够创建多个组件的组合掩码', () => {
|
||||
const mask = optimizer.createCombinedMask(['Transform', 'Velocity']);
|
||||
expect(mask.toString()).toBe('3'); // 1 | 2 = 3
|
||||
});
|
||||
|
||||
it('组件顺序不应该影响掩码结果', () => {
|
||||
const mask1 = optimizer.createCombinedMask(['Transform', 'Velocity']);
|
||||
const mask2 = optimizer.createCombinedMask(['Velocity', 'Transform']);
|
||||
expect(mask1).toBe(mask2);
|
||||
});
|
||||
|
||||
it('三个组件的组合掩码应该正确', () => {
|
||||
const mask = optimizer.createCombinedMask(['Transform', 'Velocity', 'Health']);
|
||||
expect(mask.toString()).toBe('7'); // 1 | 2 | 4 = 7
|
||||
});
|
||||
|
||||
it('空数组应该返回0掩码', () => {
|
||||
const mask = optimizer.createCombinedMask([]);
|
||||
expect(mask.isZero()).toBe(true);
|
||||
});
|
||||
|
||||
it('包含未注册组件应该抛出错误', () => {
|
||||
expect(() => {
|
||||
optimizer.createCombinedMask(['Transform', 'UnknownComponent']);
|
||||
}).toThrow('Component type not registered: UnknownComponent');
|
||||
});
|
||||
});
|
||||
|
||||
describe('掩码检查功能', () => {
|
||||
beforeEach(() => {
|
||||
optimizer.registerComponentType('Transform');
|
||||
optimizer.registerComponentType('Velocity');
|
||||
optimizer.registerComponentType('Health');
|
||||
});
|
||||
|
||||
it('应该能够检查掩码是否包含指定组件', () => {
|
||||
const mask = optimizer.createCombinedMask(['Transform', 'Velocity']);
|
||||
|
||||
expect(optimizer.maskContainsComponent(mask, 'Transform')).toBe(true);
|
||||
expect(optimizer.maskContainsComponent(mask, 'Velocity')).toBe(true);
|
||||
expect(optimizer.maskContainsComponent(mask, 'Health')).toBe(false);
|
||||
});
|
||||
|
||||
it('应该能够检查掩码是否包含所有指定组件', () => {
|
||||
const mask = optimizer.createCombinedMask(['Transform', 'Velocity', 'Health']);
|
||||
|
||||
expect(optimizer.maskContainsAllComponents(mask, ['Transform'])).toBe(true);
|
||||
expect(optimizer.maskContainsAllComponents(mask, ['Transform', 'Velocity'])).toBe(true);
|
||||
expect(optimizer.maskContainsAllComponents(mask, ['Transform', 'Velocity', 'Health'])).toBe(true);
|
||||
});
|
||||
|
||||
it('不完全包含时maskContainsAllComponents应该返回false', () => {
|
||||
const mask = optimizer.createCombinedMask(['Transform']);
|
||||
|
||||
expect(optimizer.maskContainsAllComponents(mask, ['Transform', 'Velocity'])).toBe(false);
|
||||
});
|
||||
|
||||
it('应该能够检查掩码是否包含任一指定组件', () => {
|
||||
const mask = optimizer.createCombinedMask(['Transform']);
|
||||
|
||||
expect(optimizer.maskContainsAnyComponent(mask, ['Transform', 'Velocity'])).toBe(true);
|
||||
expect(optimizer.maskContainsAnyComponent(mask, ['Velocity', 'Health'])).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('掩码操作功能', () => {
|
||||
beforeEach(() => {
|
||||
optimizer.registerComponentType('Transform');
|
||||
optimizer.registerComponentType('Velocity');
|
||||
optimizer.registerComponentType('Health');
|
||||
});
|
||||
|
||||
it('应该能够向掩码添加组件', () => {
|
||||
let mask = optimizer.createSingleComponentMask('Transform');
|
||||
mask = optimizer.addComponentToMask(mask, 'Velocity');
|
||||
|
||||
expect(optimizer.maskContainsComponent(mask, 'Transform')).toBe(true);
|
||||
expect(optimizer.maskContainsComponent(mask, 'Velocity')).toBe(true);
|
||||
});
|
||||
|
||||
it('应该能够从掩码移除组件', () => {
|
||||
let mask = optimizer.createCombinedMask(['Transform', 'Velocity']);
|
||||
mask = optimizer.removeComponentFromMask(mask, 'Velocity');
|
||||
|
||||
expect(optimizer.maskContainsComponent(mask, 'Transform')).toBe(true);
|
||||
expect(optimizer.maskContainsComponent(mask, 'Velocity')).toBe(false);
|
||||
});
|
||||
|
||||
it('移除不存在的组件不应该影响掩码', () => {
|
||||
const originalMask = optimizer.createSingleComponentMask('Transform');
|
||||
const newMask = optimizer.removeComponentFromMask(originalMask, 'Velocity');
|
||||
|
||||
expect(newMask.equals(originalMask)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('工具功能', () => {
|
||||
beforeEach(() => {
|
||||
optimizer.registerComponentType('Transform');
|
||||
optimizer.registerComponentType('Velocity');
|
||||
optimizer.registerComponentType('Health');
|
||||
});
|
||||
|
||||
it('应该能够将掩码转换为组件名称数组', () => {
|
||||
const mask = optimizer.createCombinedMask(['Transform', 'Health']);
|
||||
const componentNames = optimizer.maskToComponentNames(mask);
|
||||
|
||||
expect(componentNames).toContain('Transform');
|
||||
expect(componentNames).toContain('Health');
|
||||
expect(componentNames).not.toContain('Velocity');
|
||||
expect(componentNames.length).toBe(2);
|
||||
});
|
||||
|
||||
it('空掩码应该返回空数组', () => {
|
||||
const componentNames = optimizer.maskToComponentNames(BigIntFactory.zero());
|
||||
expect(componentNames).toEqual([]);
|
||||
});
|
||||
|
||||
it('应该能够获取掩码中组件的数量', () => {
|
||||
const mask1 = optimizer.createSingleComponentMask('Transform');
|
||||
const mask2 = optimizer.createCombinedMask(['Transform', 'Velocity']);
|
||||
const mask3 = optimizer.createCombinedMask(['Transform', 'Velocity', 'Health']);
|
||||
|
||||
expect(optimizer.getComponentCount(mask1)).toBe(1);
|
||||
expect(optimizer.getComponentCount(mask2)).toBe(2);
|
||||
expect(optimizer.getComponentCount(mask3)).toBe(3);
|
||||
});
|
||||
|
||||
it('空掩码的组件数量应该为0', () => {
|
||||
expect(optimizer.getComponentCount(BigIntFactory.zero())).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('缓存和性能优化', () => {
|
||||
beforeEach(() => {
|
||||
optimizer.registerComponentType('Transform');
|
||||
optimizer.registerComponentType('Velocity');
|
||||
optimizer.registerComponentType('Health');
|
||||
});
|
||||
|
||||
it('应该能够预计算常用掩码组合', () => {
|
||||
const commonCombinations = [
|
||||
['Transform', 'Velocity'],
|
||||
['Transform', 'Health'],
|
||||
['Velocity', 'Health']
|
||||
];
|
||||
|
||||
optimizer.precomputeCommonMasks(commonCombinations);
|
||||
|
||||
// 验证掩码已被缓存
|
||||
const stats = optimizer.getCacheStats();
|
||||
expect(stats.size).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('应该能够获取缓存统计信息', () => {
|
||||
optimizer.createSingleComponentMask('Transform');
|
||||
optimizer.createCombinedMask(['Transform', 'Velocity']);
|
||||
|
||||
const stats = optimizer.getCacheStats();
|
||||
expect(stats.size).toBeGreaterThan(0);
|
||||
expect(stats.componentTypes).toBe(3);
|
||||
});
|
||||
|
||||
it('应该能够清空缓存', () => {
|
||||
optimizer.createSingleComponentMask('Transform');
|
||||
optimizer.clearCache();
|
||||
|
||||
const stats = optimizer.getCacheStats();
|
||||
expect(stats.size).toBe(0);
|
||||
expect(stats.componentTypes).toBe(3); // 组件类型不会被清除
|
||||
});
|
||||
|
||||
it('应该能够重置优化器', () => {
|
||||
optimizer.registerComponentType('NewComponent');
|
||||
optimizer.createSingleComponentMask('Transform');
|
||||
|
||||
optimizer.reset();
|
||||
|
||||
const stats = optimizer.getCacheStats();
|
||||
expect(stats.size).toBe(0);
|
||||
expect(stats.componentTypes).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('边界情况和错误处理', () => {
|
||||
it('处理大量组件类型注册', () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const id = optimizer.registerComponentType(`Component${i}`);
|
||||
expect(id).toBe(i);
|
||||
}
|
||||
});
|
||||
|
||||
it('处理大掩码值', () => {
|
||||
// 注册64个组件类型
|
||||
for (let i = 0; i < 64; i++) {
|
||||
optimizer.registerComponentType(`Component${i}`);
|
||||
}
|
||||
|
||||
const mask = optimizer.createSingleComponentMask('Component63');
|
||||
expect(mask.toString()).toBe(BigIntFactory.one().shiftLeft(63).toString());
|
||||
});
|
||||
|
||||
it('空组件名称数组的组合掩码', () => {
|
||||
const mask = optimizer.createCombinedMask([]);
|
||||
expect(mask.isZero()).toBe(true);
|
||||
expect(optimizer.getComponentCount(mask)).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('性能测试', () => {
|
||||
beforeEach(() => {
|
||||
// 注册一些组件类型
|
||||
for (let i = 0; i < 10; i++) {
|
||||
optimizer.registerComponentType(`Component${i}`);
|
||||
}
|
||||
});
|
||||
|
||||
it('大量掩码创建应该高效', () => {
|
||||
const startTime = performance.now();
|
||||
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
optimizer.createSingleComponentMask('Component0');
|
||||
}
|
||||
|
||||
const endTime = performance.now();
|
||||
expect(endTime - startTime).toBeLessThan(100); // 应该在100ms内完成
|
||||
});
|
||||
|
||||
it('大量掩码检查应该高效', () => {
|
||||
const mask = optimizer.createCombinedMask(['Component0', 'Component1', 'Component2']);
|
||||
const startTime = performance.now();
|
||||
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
optimizer.maskContainsComponent(mask, 'Component1');
|
||||
}
|
||||
|
||||
const endTime = performance.now();
|
||||
expect(endTime - startTime).toBeLessThan(100); // 应该在100ms内完成
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user