避免splice开销问题,改为SwapPop + typeId → denseIndex

This commit is contained in:
YHH
2025-09-03 10:56:33 +08:00
parent dbddbbdfb8
commit 7792710694

View File

@@ -74,92 +74,66 @@ export class Entity {
/** /**
* 实体名称 * 实体名称
*
* 用于标识和调试的友好名称。
*/ */
public name: string; public name: string;
/** /**
* 实体唯一标识符 * 实体唯一标识符
*
* 在场景中唯一的数字标识符。
*/ */
public readonly id: number; public readonly id: number;
/** /**
* 组件集合 * 组件集合
*
* 存储实体拥有的所有组件。
*/ */
public readonly components: Component[] = []; public readonly components: Component[] = [];
/** /**
* 所属场景引用 * 所属场景引用
*
* 指向实体所在的场景实例。
*/ */
public scene: IScene | null = null; public scene: IScene | null = null;
/** /**
* 更新间隔 * 更新间隔
*
* 控制实体更新的频率,值越大更新越不频繁。
*/ */
public updateInterval: number = 1; public updateInterval: number = 1;
/** /**
* 销毁状态标志 * 销毁状态标志
*
* 标记实体是否已被销毁。
*/ */
public _isDestroyed: boolean = false; public _isDestroyed: boolean = false;
/** /**
* 父实体引用 * 父实体引用
*
* 指向父级实体,用于构建实体层次结构。
*/ */
private _parent: Entity | null = null; private _parent: Entity | null = null;
/** /**
* 子实体集合 * 子实体集合
*
* 存储所有子级实体的数组。
*/ */
private _children: Entity[] = []; private _children: Entity[] = [];
/** /**
* 激活状态 * 激活状态
*
* 控制实体是否处于激活状态。
*/ */
private _active: boolean = true; private _active: boolean = true;
/** /**
* 实体标签 * 实体标签
*
* 用于分类和查询的数字标签。
*/ */
private _tag: number = 0; private _tag: number = 0;
/** /**
* 启用状态 * 启用状态
*
* 控制实体是否启用更新和处理。
*/ */
private _enabled: boolean = true; private _enabled: boolean = true;
/** /**
* 更新顺序 * 更新顺序
*
* 控制实体在系统中的更新优先级。
*/ */
private _updateOrder: number = 0; private _updateOrder: number = 0;
/** /**
* 组件位掩码 * 组件位掩码
*
* 用于快速查询实体拥有的组件类型。
*/ */
private _componentMask: BitMask64Data = BitMask64Utils.clone(BitMask64Utils.ZERO); private _componentMask: BitMask64Data = BitMask64Utils.clone(BitMask64Utils.ZERO);
@@ -168,6 +142,11 @@ export class Entity {
*/ */
private _componentsByTypeId: (Component | undefined)[] = []; private _componentsByTypeId: (Component | undefined)[] = [];
/**
* typeId到components数组中密集索引的映射表
*/
private _componentDenseIndexByTypeId: number[] = [];
/** /**
* 构造函数 * 构造函数
* *
@@ -181,7 +160,6 @@ export class Entity {
/** /**
* 获取销毁状态 * 获取销毁状态
*
* @returns 如果实体已被销毁则返回true * @returns 如果实体已被销毁则返回true
*/ */
public get isDestroyed(): boolean { public get isDestroyed(): boolean {
@@ -190,7 +168,6 @@ export class Entity {
/** /**
* 获取父实体 * 获取父实体
*
* @returns 父实体如果没有父实体则返回null * @returns 父实体如果没有父实体则返回null
*/ */
public get parent(): Entity | null { public get parent(): Entity | null {
@@ -338,21 +315,20 @@ export class Entity {
private addComponentInternal<T extends Component>(component: T): T { private addComponentInternal<T extends Component>(component: T): T {
const componentType = component.constructor as ComponentType<T>; const componentType = component.constructor as ComponentType<T>;
// 注册组件类型(如果尚未注册)
if (!ComponentRegistry.isRegistered(componentType)) { if (!ComponentRegistry.isRegistered(componentType)) {
ComponentRegistry.register(componentType); ComponentRegistry.register(componentType);
} }
const typeId = ComponentRegistry.getBitIndex(componentType); const typeId = ComponentRegistry.getBitIndex(componentType);
// 设置组件的实体引用
component.entity = this; component.entity = this;
// 直址存储
this._componentsByTypeId[typeId] = component; this._componentsByTypeId[typeId] = component;
const denseIndex = this.components.length;
this._componentDenseIndexByTypeId[typeId] = denseIndex;
this.components.push(component); this.components.push(component);
// 更新位掩码
const componentMask = ComponentRegistry.getBitMask(componentType); const componentMask = ComponentRegistry.getBitMask(componentType);
BitMask64Utils.orInPlace(this._componentMask, componentMask); BitMask64Utils.orInPlace(this._componentMask, componentMask);
@@ -369,23 +345,18 @@ export class Entity {
public addComponent<T extends Component>(component: T): T { public addComponent<T extends Component>(component: T): T {
const componentType = component.constructor as ComponentType<T>; const componentType = component.constructor as ComponentType<T>;
// 检查是否已有此类型的组件
if (this.hasComponent(componentType)) { if (this.hasComponent(componentType)) {
throw new Error(`Entity ${this.name} already has component ${getComponentTypeName(componentType)}`); throw new Error(`Entity ${this.name} already has component ${getComponentTypeName(componentType)}`);
} }
// 使用内部方法添加组件
this.addComponentInternal(component); this.addComponentInternal(component);
// 如果场景存在且有组件存储管理器,添加到存储器
if (this.scene && this.scene.componentStorageManager) { if (this.scene && this.scene.componentStorageManager) {
this.scene.componentStorageManager.addComponent(this.id, component); this.scene.componentStorageManager.addComponent(this.id, component);
} }
// 调用组件的生命周期方法
component.onAddedToEntity(); component.onAddedToEntity();
// 发射组件添加事件
if (Entity.eventBus) { if (Entity.eventBus) {
Entity.eventBus.emitComponentAdded({ Entity.eventBus.emitComponentAdded({
timestamp: Date.now(), timestamp: Date.now(),
@@ -399,9 +370,7 @@ export class Entity {
} }
// 通知QuerySystem实体组件已改变需要重新索引
if (this.scene && this.scene.querySystem) { if (this.scene && this.scene.querySystem) {
// 移除旧的索引,重新添加以更新索引
this.scene.querySystem.removeEntity(this); this.scene.querySystem.removeEntity(this);
this.scene.querySystem.addEntity(this); this.scene.querySystem.addEntity(this);
} }
@@ -416,7 +385,6 @@ export class Entity {
* @returns 组件实例或null * @returns 组件实例或null
*/ */
public getComponent<T extends Component>(type: ComponentType<T>): T | null { public getComponent<T extends Component>(type: ComponentType<T>): T | null {
// 首先检查位掩码快速排除O(1)
if (!ComponentRegistry.isRegistered(type)) { if (!ComponentRegistry.isRegistered(type)) {
return null; return null;
} }
@@ -426,7 +394,6 @@ export class Entity {
return null; return null;
} }
// 直址访问
const typeId = ComponentRegistry.getBitIndex(type); const typeId = ComponentRegistry.getBitIndex(type);
const component = this._componentsByTypeId[typeId]; const component = this._componentsByTypeId[typeId];
@@ -434,25 +401,24 @@ export class Entity {
return component as T; return component as T;
} }
// 如果场景有组件存储管理器,从存储器获取
if (this.scene && this.scene.componentStorageManager) { if (this.scene && this.scene.componentStorageManager) {
const storageComponent = this.scene.componentStorageManager.getComponent(this.id, type); const storageComponent = this.scene.componentStorageManager.getComponent(this.id, type);
if (storageComponent) { if (storageComponent) {
// 同步到稀疏数组
this._componentsByTypeId[typeId] = storageComponent; this._componentsByTypeId[typeId] = storageComponent;
if (!this.components.includes(storageComponent)) { if (!this.components.includes(storageComponent)) {
const denseIndex = this.components.length;
this._componentDenseIndexByTypeId[typeId] = denseIndex;
this.components.push(storageComponent); this.components.push(storageComponent);
} }
return storageComponent; return storageComponent;
} }
} }
// 最后回退到线性搜索
for (let i = 0; i < this.components.length; i++) { for (let i = 0; i < this.components.length; i++) {
const component = this.components[i]; const component = this.components[i];
if (component instanceof type) { if (component instanceof type) {
// 同步到稀疏数组
this._componentsByTypeId[typeId] = component; this._componentsByTypeId[typeId] = component;
this._componentDenseIndexByTypeId[typeId] = i;
return component as T; return component as T;
} }
} }
@@ -504,33 +470,42 @@ export class Entity {
public removeComponent(component: Component): void { public removeComponent(component: Component): void {
const componentType = component.constructor as ComponentType; const componentType = component.constructor as ComponentType;
// 从稀疏数组中移除 if (!ComponentRegistry.isRegistered(componentType)) {
if (ComponentRegistry.isRegistered(componentType)) { return;
}
const typeId = ComponentRegistry.getBitIndex(componentType); const typeId = ComponentRegistry.getBitIndex(componentType);
this._componentsByTypeId[typeId] = undefined; this._componentsByTypeId[typeId] = undefined;
// 更新位掩码 BitMask64Utils.clearBit(this._componentMask, typeId);
const bitIndex = ComponentRegistry.getBitIndex(componentType);
BitMask64Utils.clearBit(this._componentMask, bitIndex); const denseIndex = this._componentDenseIndexByTypeId[typeId];
if (denseIndex !== undefined && denseIndex < this.components.length) {
const lastIndex = this.components.length - 1;
if (denseIndex !== lastIndex) {
const lastComponent = this.components[lastIndex];
this.components[denseIndex] = lastComponent;
const lastComponentType = lastComponent.constructor as ComponentType;
const lastTypeId = ComponentRegistry.getBitIndex(lastComponentType);
this._componentDenseIndexByTypeId[lastTypeId] = denseIndex;
} }
// 从迭代数组中移除 this.components.pop();
const index = this.components.indexOf(component);
if (index !== -1) {
this.components.splice(index, 1);
} }
// 从组件存储管理器中移除 this._componentDenseIndexByTypeId[typeId] = -1;
if (this.scene && this.scene.componentStorageManager) { if (this.scene && this.scene.componentStorageManager) {
this.scene.componentStorageManager.removeComponent(this.id, componentType); this.scene.componentStorageManager.removeComponent(this.id, componentType);
} }
// 调用组件的生命周期方法
if (component.onRemovedFromEntity) { if (component.onRemovedFromEntity) {
component.onRemovedFromEntity(); component.onRemovedFromEntity();
} }
// 发射组件移除事件
if (Entity.eventBus) { if (Entity.eventBus) {
Entity.eventBus.emitComponentRemoved({ Entity.eventBus.emitComponentRemoved({
timestamp: Date.now(), timestamp: Date.now(),
@@ -543,13 +518,9 @@ export class Entity {
}); });
} }
// 清除组件的实体引用
component.entity = null as any; component.entity = null as any;
// 通知QuerySystem实体组件已改变需要重新索引
if (this.scene && this.scene.querySystem) { if (this.scene && this.scene.querySystem) {
// 移除旧的索引,重新添加以更新索引
this.scene.querySystem.removeEntity(this); this.scene.querySystem.removeEntity(this);
this.scene.querySystem.addEntity(this); this.scene.querySystem.addEntity(this);
} }
@@ -574,32 +545,25 @@ export class Entity {
* 移除所有组件 * 移除所有组件
*/ */
public removeAllComponents(): void { public removeAllComponents(): void {
// 复制组件列表,避免在迭代时修改
const componentsToRemove = [...this.components]; const componentsToRemove = [...this.components];
// 清空稀疏数组和位掩码
this._componentsByTypeId.length = 0; this._componentsByTypeId.length = 0;
this._componentDenseIndexByTypeId.length = 0;
BitMask64Utils.clear(this._componentMask); BitMask64Utils.clear(this._componentMask);
// 移除组件
for (const component of componentsToRemove) { for (const component of componentsToRemove) {
const componentType = component.constructor as ComponentType; const componentType = component.constructor as ComponentType;
// 从组件存储管理器中移除
if (this.scene && this.scene.componentStorageManager) { if (this.scene && this.scene.componentStorageManager) {
this.scene.componentStorageManager.removeComponent(this.id, componentType); this.scene.componentStorageManager.removeComponent(this.id, componentType);
} }
// 调用组件的生命周期方法
component.onRemovedFromEntity(); component.onRemovedFromEntity();
// 清除组件的实体引用
component.entity = null as any; component.entity = null as any;
} }
// 清空组件列表
this.components.length = 0; this.components.length = 0;
} }
/** /**
@@ -615,7 +579,6 @@ export class Entity {
try { try {
addedComponents.push(this.addComponent(component)); addedComponents.push(this.addComponent(component));
} catch (error) { } catch (error) {
// 如果某个组件添加失败,继续添加其他组件
Entity._logger.warn(`添加组件失败 ${getComponentInstanceTypeName(component)}:`, error); Entity._logger.warn(`添加组件失败 ${getComponentInstanceTypeName(component)}:`, error);
} }
} }
@@ -674,16 +637,13 @@ export class Entity {
return child; // 已经是子实体 return child; // 已经是子实体
} }
// 如果子实体已有父实体,先从原父实体移除
if (child._parent) { if (child._parent) {
child._parent.removeChild(child); child._parent.removeChild(child);
} }
// 设置父子关系
child._parent = this; child._parent = this;
this._children.push(child); this._children.push(child);
// 如果子实体还没有场景,设置为父实体的场景
if (!child.scene && this.scene) { if (!child.scene && this.scene) {
child.scene = this.scene; child.scene = this.scene;
this.scene.addEntity(child); this.scene.addEntity(child);
@@ -704,7 +664,6 @@ export class Entity {
return false; return false;
} }
// 移除父子关系
this._children.splice(index, 1); this._children.splice(index, 1);
child._parent = null; child._parent = null;
@@ -715,7 +674,6 @@ export class Entity {
* 移除所有子实体 * 移除所有子实体
*/ */
public removeAllChildren(): void { public removeAllChildren(): void {
// 复制子实体列表,避免在迭代时修改
const childrenToRemove = [...this._children]; const childrenToRemove = [...this._children];
for (const child of childrenToRemove) { for (const child of childrenToRemove) {
@@ -731,14 +689,12 @@ export class Entity {
* @returns 找到的子实体或null * @returns 找到的子实体或null
*/ */
public findChild(name: string, recursive: boolean = false): Entity | null { public findChild(name: string, recursive: boolean = false): Entity | null {
// 在直接子实体中查找
for (const child of this._children) { for (const child of this._children) {
if (child.name === name) { if (child.name === name) {
return child; return child;
} }
} }
// 递归查找
if (recursive) { if (recursive) {
for (const child of this._children) { for (const child of this._children) {
const found = child.findChild(name, true); const found = child.findChild(name, true);
@@ -761,14 +717,12 @@ export class Entity {
public findChildrenByTag(tag: number, recursive: boolean = false): Entity[] { public findChildrenByTag(tag: number, recursive: boolean = false): Entity[] {
const result: Entity[] = []; const result: Entity[] = [];
// 在直接子实体中查找
for (const child of this._children) { for (const child of this._children) {
if (child.tag === tag) { if (child.tag === tag) {
result.push(child); result.push(child);
} }
} }
// 递归查找
if (recursive) { if (recursive) {
for (const child of this._children) { for (const child of this._children) {
result.push(...child.findChildrenByTag(tag, true)); result.push(...child.findChildrenByTag(tag, true));
@@ -852,14 +806,12 @@ export class Entity {
* 活跃状态改变时的回调 * 活跃状态改变时的回调
*/ */
private onActiveChanged(): void { private onActiveChanged(): void {
// 通知所有组件活跃状态改变
for (const component of this.components) { for (const component of this.components) {
if ('onActiveChanged' in component && typeof component.onActiveChanged === 'function') { if ('onActiveChanged' in component && typeof component.onActiveChanged === 'function') {
(component as any).onActiveChanged(); (component as any).onActiveChanged();
} }
} }
// 通知场景实体状态改变
if (this.scene && this.scene.eventSystem) { if (this.scene && this.scene.eventSystem) {
this.scene.eventSystem.emitSync('entity:activeChanged', { this.scene.eventSystem.emitSync('entity:activeChanged', {
entity: this, entity: this,
@@ -879,14 +831,12 @@ export class Entity {
return; return;
} }
// 更新所有组件
for (const component of this.components) { for (const component of this.components) {
if (component.enabled) { if (component.enabled) {
component.update(); component.update();
} }
} }
// 更新所有子实体
for (const child of this._children) { for (const child of this._children) {
child.update(); child.update();
} }
@@ -904,28 +854,22 @@ export class Entity {
this._isDestroyed = true; this._isDestroyed = true;
// 销毁所有子实体
const childrenToDestroy = [...this._children]; const childrenToDestroy = [...this._children];
for (const child of childrenToDestroy) { for (const child of childrenToDestroy) {
child.destroy(); child.destroy();
} }
// 从父实体中移除
if (this._parent) { if (this._parent) {
this._parent.removeChild(this); this._parent.removeChild(this);
} }
// 移除所有组件
this.removeAllComponents(); this.removeAllComponents();
// 从场景中移除
if (this.scene) { if (this.scene) {
// 从查询系统中移除
if (this.scene.querySystem) { if (this.scene.querySystem) {
this.scene.querySystem.removeEntity(this); this.scene.querySystem.removeEntity(this);
} }
// 从实体列表中移除
if (this.scene.entities) { if (this.scene.entities) {
this.scene.entities.remove(this); this.scene.entities.remove(this);
} }
@@ -971,6 +915,7 @@ export class Entity {
childIds: number[]; childIds: number[];
depth: number; depth: number;
indexMappingSize: number; indexMappingSize: number;
denseIndexMappingSize: number;
} { } {
return { return {
name: this.name, name: this.name,
@@ -986,7 +931,8 @@ export class Entity {
childCount: this._children.length, childCount: this._children.length,
childIds: this._children.map(c => c.id), childIds: this._children.map(c => c.id),
depth: this.getDepth(), depth: this.getDepth(),
indexMappingSize: this._componentsByTypeId.filter(c => c !== undefined).length indexMappingSize: this._componentsByTypeId.filter(c => c !== undefined).length,
denseIndexMappingSize: this._componentDenseIndexByTypeId.filter(idx => idx !== -1 && idx !== undefined).length
}; };
} }
} }