From a5e70bcd992131e4bfcd920cf3bb3eef693dc467 Mon Sep 17 00:00:00 2001 From: YHH <359807859@qq.com> Date: Tue, 30 Sep 2025 16:38:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DQuerySystem=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=8E=A9=E7=A0=81=E7=B4=A2=E5=BC=95=E4=BD=BF=E7=94=A8toString(?= =?UTF-8?q?)=E8=BF=94=E5=9B=9E[object=20Object]=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20#70?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/ECS/Core/QuerySystem.ts | 4 +- .../core/tests/ECS/Core/QuerySystem.test.ts | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/packages/core/src/ECS/Core/QuerySystem.ts b/packages/core/src/ECS/Core/QuerySystem.ts index 3e2b22d7..c432d26a 100644 --- a/packages/core/src/ECS/Core/QuerySystem.ts +++ b/packages/core/src/ECS/Core/QuerySystem.ts @@ -290,7 +290,7 @@ export class QuerySystem { const mask = entity.componentMask; // 组件掩码索引 - const maskKey = mask.toString(); + const maskKey = BitMask64Utils.toString(mask, 16); const maskSet = this.entityIndex.byMask.get(maskKey) || this.createAndSetMaskIndex(maskKey); maskSet.add(entity); @@ -348,7 +348,7 @@ export class QuerySystem { const mask = entity.componentMask; // 从组件掩码索引移除 - const maskKey = mask.toString(); + const maskKey = BitMask64Utils.toString(mask, 16); const maskSet = this.entityIndex.byMask.get(maskKey); if (maskSet) { maskSet.delete(entity); diff --git a/packages/core/tests/ECS/Core/QuerySystem.test.ts b/packages/core/tests/ECS/Core/QuerySystem.test.ts index ca5950a4..6e94b2fd 100644 --- a/packages/core/tests/ECS/Core/QuerySystem.test.ts +++ b/packages/core/tests/ECS/Core/QuerySystem.test.ts @@ -1049,4 +1049,60 @@ describe('QuerySystem - 查询系统测试', () => { } }); }); + + describe('组件掩码字符串索引', () => { + test('应该为不同的组件组合生成不同的掩码字符串', () => { + // 创建具有不同组件组合的实体 + const entity1 = new Entity('Entity1', 101); + const entity2 = new Entity('Entity2', 102); + const entity3 = new Entity('Entity3', 103); + + entity1.addComponent(new PositionComponent(1, 1)); + entity2.addComponent(new VelocityComponent(2, 2)); + entity3.addComponent(new PositionComponent(3, 3)); + entity3.addComponent(new VelocityComponent(4, 4)); + + const allEntities = [...entities, entity1, entity2, entity3]; + querySystem.setEntities(allEntities); + + // 查询包含指定组件的实体(queryAll 是包含关系,不是仅有) + const withPosition = querySystem.queryAll(PositionComponent); + const withVelocity = querySystem.queryAll(VelocityComponent); + const withBoth = querySystem.queryAll(PositionComponent, VelocityComponent); + + // entity1 应该在 withPosition 中 + expect(withPosition.entities.some(e => e.id === 101)).toBe(true); + // entity2 应该在 withVelocity 中 + expect(withVelocity.entities.some(e => e.id === 102)).toBe(true); + // entity3 应该在所有查询中(因为它包含 Position 和 Velocity) + expect(withPosition.entities.some(e => e.id === 103)).toBe(true); + expect(withVelocity.entities.some(e => e.id === 103)).toBe(true); + expect(withBoth.entities.some(e => e.id === 103)).toBe(true); + + // withBoth 只应该包含同时有两个组件的实体 + expect(withBoth.entities.some(e => e.id === 101)).toBe(false); // 只有 Position + expect(withBoth.entities.some(e => e.id === 102)).toBe(false); // 只有 Velocity + }); + + test('相同组件组合的实体应该使用相同的掩码索引', () => { + const entity1 = new Entity('Entity1', 201); + const entity2 = new Entity('Entity2', 202); + + // 两个实体都有相同的组件组合 + entity1.addComponent(new PositionComponent(1, 1)); + entity1.addComponent(new VelocityComponent(2, 2)); + + entity2.addComponent(new PositionComponent(3, 3)); + entity2.addComponent(new VelocityComponent(4, 4)); + + const allEntities = [...entities, entity1, entity2]; + querySystem.setEntities(allEntities); + + // 查询应该同时返回这两个实体 + const result = querySystem.queryAll(PositionComponent, VelocityComponent); + + expect(result.entities.some(e => e.id === 201)).toBe(true); + expect(result.entities.some(e => e.id === 202)).toBe(true); + }); + }); }); \ No newline at end of file