修复QuerySystem/ArchetypeSystem未响应实体增删Component的问题
This commit is contained in:
@@ -87,16 +87,64 @@ export class ArchetypeSystem {
|
||||
public removeEntity(entity: Entity): void {
|
||||
const archetype = this._entityToArchetype.get(entity);
|
||||
if (!archetype) return;
|
||||
|
||||
|
||||
const index = archetype.entities.indexOf(entity);
|
||||
if (index !== -1) {
|
||||
archetype.entities.splice(index, 1);
|
||||
archetype.updatedAt = Date.now();
|
||||
}
|
||||
|
||||
|
||||
this._entityToArchetype.delete(entity);
|
||||
this.invalidateQueryCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新实体的原型归属
|
||||
*
|
||||
* 当实体的组件组合发生变化时调用此方法,将实体从旧原型移动到新原型。
|
||||
* 如果新的组件组合对应的原型不存在,将自动创建新原型。
|
||||
*
|
||||
* @param entity 要更新的实体
|
||||
*/
|
||||
public updateEntity(entity: Entity): void {
|
||||
const currentArchetype = this._entityToArchetype.get(entity);
|
||||
const newComponentTypes = this.getEntityComponentTypes(entity);
|
||||
const newArchetypeId = this.generateArchetypeId(newComponentTypes);
|
||||
|
||||
// 如果实体已在正确的原型中,无需更新
|
||||
if (currentArchetype && currentArchetype.id === newArchetypeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 从旧原型中移除实体
|
||||
if (currentArchetype) {
|
||||
const index = currentArchetype.entities.indexOf(entity);
|
||||
if (index !== -1) {
|
||||
currentArchetype.entities.splice(index, 1);
|
||||
currentArchetype.updatedAt = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
// 获取或创建新原型
|
||||
let newArchetype = this._archetypes.get(newArchetypeId);
|
||||
if (!newArchetype) {
|
||||
newArchetype = this.createArchetype(newComponentTypes);
|
||||
}
|
||||
|
||||
// 将实体添加到新原型
|
||||
newArchetype.entities.push(entity);
|
||||
newArchetype.updatedAt = Date.now();
|
||||
this._entityToArchetype.set(entity, newArchetype);
|
||||
|
||||
// 更新组件索引
|
||||
if (currentArchetype) {
|
||||
this.updateComponentIndexes(currentArchetype, currentArchetype.componentTypes, false);
|
||||
}
|
||||
this.updateComponentIndexes(newArchetype, newComponentTypes, true);
|
||||
|
||||
// 使查询缓存失效
|
||||
this.invalidateQueryCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询包含指定组件组合的原型
|
||||
|
||||
@@ -229,9 +229,9 @@ export class QuerySystem {
|
||||
|
||||
/**
|
||||
* 从查询系统移除实体
|
||||
*
|
||||
*
|
||||
* 从查询系统中移除指定实体,并清理相关索引。
|
||||
*
|
||||
*
|
||||
* @param entity 要移除的实体
|
||||
*/
|
||||
public removeEntity(entity: Entity): void {
|
||||
@@ -244,12 +244,47 @@ export class QuerySystem {
|
||||
this.archetypeSystem.removeEntity(entity);
|
||||
|
||||
this.clearQueryCache();
|
||||
|
||||
|
||||
// 更新版本号
|
||||
this._version++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新实体在查询系统中的索引
|
||||
*
|
||||
* 当实体的组件组合发生变化时调用此方法,高效地更新实体在查询系统中的索引。
|
||||
*
|
||||
* @param entity 要更新的实体
|
||||
*/
|
||||
public updateEntity(entity: Entity): void {
|
||||
// 检查实体是否在查询系统中
|
||||
if (!this.entities.includes(entity)) {
|
||||
// 如果实体不在系统中,直接添加
|
||||
this.addEntity(entity);
|
||||
return;
|
||||
}
|
||||
|
||||
// 先从索引中移除实体的旧状态
|
||||
this.removeEntityFromIndexes(entity);
|
||||
|
||||
// 更新ArchetypeSystem中的实体状态
|
||||
this.archetypeSystem.updateEntity(entity);
|
||||
|
||||
// 更新ComponentIndexManager中的实体状态
|
||||
this.componentIndexManager.removeEntity(entity);
|
||||
this.componentIndexManager.addEntity(entity);
|
||||
|
||||
// 重新添加实体到索引(基于新的组件状态)
|
||||
this.addEntityToIndexes(entity);
|
||||
|
||||
// 清理查询缓存,因为实体组件状态已改变
|
||||
this.clearQueryCache();
|
||||
|
||||
// 更新版本号以使缓存失效
|
||||
this._version++;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将实体添加到各种索引中
|
||||
*/
|
||||
|
||||
@@ -71,6 +71,19 @@ export class Entity {
|
||||
* 用于发射组件相关事件
|
||||
*/
|
||||
public static eventBus: EventBus | null = null;
|
||||
|
||||
/**
|
||||
* 通知Scene中的QuerySystem实体组件发生变动
|
||||
*
|
||||
* @param entity 发生组件变动的实体
|
||||
*/
|
||||
private static notifyQuerySystems(entity: Entity): void {
|
||||
// 只通知Scene中的QuerySystem
|
||||
if (entity.scene && entity.scene.querySystem) {
|
||||
entity.scene.querySystem.updateEntity(entity);
|
||||
entity.scene.clearSystemEntityCaches();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体名称
|
||||
@@ -369,12 +382,9 @@ export class Entity {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (this.scene && this.scene.querySystem) {
|
||||
this.scene.querySystem.removeEntity(this);
|
||||
this.scene.querySystem.addEntity(this);
|
||||
this.scene.clearSystemEntityCaches();
|
||||
}
|
||||
|
||||
// 通知所有相关的QuerySystem组件已变动
|
||||
Entity.notifyQuerySystems(this);
|
||||
|
||||
return component;
|
||||
}
|
||||
@@ -521,11 +531,8 @@ export class Entity {
|
||||
|
||||
component.entity = null as any;
|
||||
|
||||
if (this.scene && this.scene.querySystem) {
|
||||
this.scene.querySystem.removeEntity(this);
|
||||
this.scene.querySystem.addEntity(this);
|
||||
this.scene.clearSystemEntityCaches();
|
||||
}
|
||||
// 通知所有相关的QuerySystem组件已变动
|
||||
Entity.notifyQuerySystems(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -564,8 +571,11 @@ export class Entity {
|
||||
|
||||
component.entity = null as any;
|
||||
}
|
||||
|
||||
|
||||
this.components.length = 0;
|
||||
|
||||
// 通知所有相关的QuerySystem组件已全部移除
|
||||
Entity.notifyQuerySystems(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Entity } from '../Entity';
|
||||
import { PerformanceMonitor } from '../../Utils/PerformanceMonitor';
|
||||
import { Matcher } from '../Utils/Matcher';
|
||||
import { Matcher, type QueryCondition } from '../Utils/Matcher';
|
||||
import type { Scene } from '../Scene';
|
||||
import type { ISystemBase } from '../../Types';
|
||||
import type { QuerySystem } from '../Core/QuerySystem';
|
||||
@@ -274,7 +274,7 @@ export abstract class EntitySystem implements ISystemBase {
|
||||
/**
|
||||
* 检查是否为单一条件查询
|
||||
*/
|
||||
private isSingleCondition(condition: any): boolean {
|
||||
private isSingleCondition(condition: QueryCondition): boolean {
|
||||
const flags =
|
||||
((condition.all.length > 0) ? 1 : 0) |
|
||||
((condition.any.length > 0) ? 2 : 0) |
|
||||
@@ -289,7 +289,7 @@ export abstract class EntitySystem implements ISystemBase {
|
||||
/**
|
||||
* 执行单一条件查询
|
||||
*/
|
||||
private executeSingleConditionQuery(condition: any, querySystem: any): readonly Entity[] {
|
||||
private executeSingleConditionQuery(condition: QueryCondition, querySystem: QuerySystem): readonly Entity[] {
|
||||
// 按标签查询
|
||||
if (condition.tag !== undefined) {
|
||||
return querySystem.queryByTag(condition.tag).entities;
|
||||
@@ -324,7 +324,7 @@ export abstract class EntitySystem implements ISystemBase {
|
||||
/**
|
||||
* 执行复合查询
|
||||
*/
|
||||
private executeComplexQueryWithIdSets(condition: any, querySystem: QuerySystem): readonly Entity[] {
|
||||
private executeComplexQueryWithIdSets(condition: QueryCondition, querySystem: QuerySystem): readonly Entity[] {
|
||||
let resultIds: Set<number> | null = null;
|
||||
|
||||
// 1. 应用标签条件作为基础集合
|
||||
@@ -492,7 +492,7 @@ export abstract class EntitySystem implements ISystemBase {
|
||||
*
|
||||
* 使用基于ID集合的单次扫描算法进行复杂查询
|
||||
*/
|
||||
private executeComplexQuery(condition: any, querySystem: QuerySystem): readonly Entity[] {
|
||||
private executeComplexQuery(condition: QueryCondition, querySystem: QuerySystem): readonly Entity[] {
|
||||
return this.executeComplexQueryWithIdSets(condition, querySystem);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { getComponentTypeName } from '../Decorators';
|
||||
/**
|
||||
* 查询条件类型
|
||||
*/
|
||||
interface QueryCondition {
|
||||
export interface QueryCondition {
|
||||
all: ComponentType[];
|
||||
any: ComponentType[];
|
||||
none: ComponentType[];
|
||||
|
||||
Reference in New Issue
Block a user