系统添加缓存实体机制避免频繁开销
This commit is contained in:
@@ -373,6 +373,7 @@ export class Entity {
|
|||||||
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);
|
||||||
|
this.scene.clearSystemEntityCaches();
|
||||||
}
|
}
|
||||||
|
|
||||||
return component;
|
return component;
|
||||||
@@ -523,6 +524,7 @@ export class Entity {
|
|||||||
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);
|
||||||
|
this.scene.clearSystemEntityCaches();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,11 @@ export interface IScene {
|
|||||||
*/
|
*/
|
||||||
createEntity(name: string): Entity;
|
createEntity(name: string): Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除所有EntitySystem的实体缓存
|
||||||
|
*/
|
||||||
|
clearSystemEntityCaches(): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加实体
|
* 添加实体
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -207,6 +207,16 @@ export class Scene implements IScene {
|
|||||||
return this.addEntity(entity);
|
return this.addEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除所有EntitySystem的实体缓存
|
||||||
|
* 当实体或组件发生变化时调用
|
||||||
|
*/
|
||||||
|
public clearSystemEntityCaches(): void {
|
||||||
|
for (const system of this.entityProcessors.processors) {
|
||||||
|
system.clearEntityCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在场景的实体列表中添加一个实体
|
* 在场景的实体列表中添加一个实体
|
||||||
* @param entity 要添加的实体
|
* @param entity 要添加的实体
|
||||||
@@ -219,6 +229,11 @@ export class Scene implements IScene {
|
|||||||
// 将实体添加到查询系统(可延迟缓存清理)
|
// 将实体添加到查询系统(可延迟缓存清理)
|
||||||
this.querySystem.addEntity(entity, deferCacheClear);
|
this.querySystem.addEntity(entity, deferCacheClear);
|
||||||
|
|
||||||
|
// 清除系统缓存以确保系统能及时发现新实体
|
||||||
|
if (!deferCacheClear) {
|
||||||
|
this.clearSystemEntityCaches();
|
||||||
|
}
|
||||||
|
|
||||||
// 触发实体添加事件
|
// 触发实体添加事件
|
||||||
this.eventSystem.emitSync('entity:added', { entity, scene: this });
|
this.eventSystem.emitSync('entity:added', { entity, scene: this });
|
||||||
|
|
||||||
|
|||||||
@@ -50,12 +50,23 @@ export abstract class EntitySystem implements ISystemBase {
|
|||||||
private _trackedEntities: Set<Entity> = new Set();
|
private _trackedEntities: Set<Entity> = new Set();
|
||||||
private _eventListeners: EventListenerRecord[] = [];
|
private _eventListeners: EventListenerRecord[] = [];
|
||||||
private _frameEntities: Entity[] | null = null;
|
private _frameEntities: Entity[] | null = null;
|
||||||
|
private _cachedEntities: Entity[] | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取系统处理的实体列表
|
* 获取系统处理的实体列表
|
||||||
*/
|
*/
|
||||||
public get entities(): readonly Entity[] {
|
public get entities(): readonly Entity[] {
|
||||||
return this._frameEntities || [];
|
// 如果在update周期内,优先使用_frameEntities
|
||||||
|
if (this._frameEntities !== null) {
|
||||||
|
return this._frameEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则使用持久缓存
|
||||||
|
if (this._cachedEntities === null) {
|
||||||
|
this._cachedEntities = this.queryEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._cachedEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,6 +152,8 @@ export abstract class EntitySystem implements ISystemBase {
|
|||||||
|
|
||||||
// 框架内部初始化:触发一次实体查询,以便正确跟踪现有实体
|
// 框架内部初始化:触发一次实体查询,以便正确跟踪现有实体
|
||||||
if (this.scene) {
|
if (this.scene) {
|
||||||
|
// 清理缓存确保初始化时重新查询
|
||||||
|
this._cachedEntities = null;
|
||||||
this.queryEntities();
|
this.queryEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +170,14 @@ export abstract class EntitySystem implements ISystemBase {
|
|||||||
// 子类可以重写此方法进行初始化
|
// 子类可以重写此方法进行初始化
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除实体缓存(内部使用)
|
||||||
|
* 当Scene中的实体发生变化时调用
|
||||||
|
*/
|
||||||
|
public clearEntityCache(): void {
|
||||||
|
this._cachedEntities = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置系统状态
|
* 重置系统状态
|
||||||
*
|
*
|
||||||
@@ -166,6 +187,8 @@ export abstract class EntitySystem implements ISystemBase {
|
|||||||
this.scene = null;
|
this.scene = null;
|
||||||
this._initialized = false;
|
this._initialized = false;
|
||||||
this._trackedEntities.clear();
|
this._trackedEntities.clear();
|
||||||
|
this._cachedEntities = null;
|
||||||
|
this._frameEntities = null;
|
||||||
|
|
||||||
// 清理所有事件监听器
|
// 清理所有事件监听器
|
||||||
this.cleanupEventListeners();
|
this.cleanupEventListeners();
|
||||||
@@ -522,12 +545,14 @@ export abstract class EntitySystem implements ISystemBase {
|
|||||||
*/
|
*/
|
||||||
private updateEntityTracking(currentEntities: Entity[]): void {
|
private updateEntityTracking(currentEntities: Entity[]): void {
|
||||||
const currentSet = new Set(currentEntities);
|
const currentSet = new Set(currentEntities);
|
||||||
|
let hasChanged = false;
|
||||||
|
|
||||||
// 检查新增的实体
|
// 检查新增的实体
|
||||||
for (const entity of currentEntities) {
|
for (const entity of currentEntities) {
|
||||||
if (!this._trackedEntities.has(entity)) {
|
if (!this._trackedEntities.has(entity)) {
|
||||||
this._trackedEntities.add(entity);
|
this._trackedEntities.add(entity);
|
||||||
this.onAdded(entity);
|
this.onAdded(entity);
|
||||||
|
hasChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,8 +561,14 @@ export abstract class EntitySystem implements ISystemBase {
|
|||||||
if (!currentSet.has(entity)) {
|
if (!currentSet.has(entity)) {
|
||||||
this._trackedEntities.delete(entity);
|
this._trackedEntities.delete(entity);
|
||||||
this.onRemoved(entity);
|
this.onRemoved(entity);
|
||||||
|
hasChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果实体发生了变化,使缓存失效
|
||||||
|
if (hasChanged) {
|
||||||
|
this._cachedEntities = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user