archetypesystem只负责原型管理,querysytem负责查询和缓存

This commit is contained in:
YHH
2025-09-29 11:01:39 +08:00
parent d62bf9f7f9
commit be11060674
2 changed files with 54 additions and 117 deletions

View File

@@ -15,12 +15,8 @@ export interface Archetype {
id: ArchetypeId;
/** 包含的组件类型 */
componentTypes: ComponentType[];
/** 属于该原型的实体列表 */
entities: Entity[];
/** 原型创建时间 */
createdAt: number;
/** 最后更新时间 */
updatedAt: number;
/** 属于该原型的实体集合 */
entities: Set<Entity>;
}
/**
@@ -31,10 +27,6 @@ export interface ArchetypeQueryResult {
archetypes: Archetype[];
/** 所有匹配实体的总数 */
totalEntities: number;
/** 查询执行时间(毫秒) */
executionTime: number;
/** 是否使用了缓存 */
fromCache: boolean;
}
/**
@@ -45,21 +37,18 @@ export interface ArchetypeQueryResult {
export class ArchetypeSystem {
/** 所有原型的映射表 */
private _archetypes = new Map<ArchetypeId, Archetype>();
/** 实体到原型的映射 */
private _entityToArchetype = new Map<Entity, Archetype>();
/** 组件类型到原型的映射 */
private _componentToArchetypes = new Map<ComponentType, Set<Archetype>>();
/** 查询缓存 */
private _queryCache = new Map<string, {
result: ArchetypeQueryResult;
timestamp: number;
}>();
private _cacheTimeout = 5000;
private _maxCacheSize = 100;
/** 实体组件类型缓存 */
private _entityComponentTypesCache = new Map<Entity, ComponentType[]>();
/** 原型ID缓存 */
private _archetypeIdCache = new Map<string, ArchetypeId>();
/**
* 添加实体到原型系统
@@ -67,18 +56,16 @@ export class ArchetypeSystem {
public addEntity(entity: Entity): void {
const componentTypes = this.getEntityComponentTypes(entity);
const archetypeId = this.generateArchetypeId(componentTypes);
let archetype = this._archetypes.get(archetypeId);
if (!archetype) {
archetype = this.createArchetype(componentTypes);
}
archetype.entities.push(entity);
archetype.updatedAt = Date.now();
archetype.entities.add(entity);
this._entityToArchetype.set(entity, archetype);
this.updateComponentIndexes(archetype, componentTypes, true);
this.invalidateQueryCache();
}
/**
@@ -88,14 +75,11 @@ export class ArchetypeSystem {
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();
}
archetype.entities.delete(entity);
// 清理实体相关缓存
this._entityComponentTypesCache.delete(entity);
this._entityToArchetype.delete(entity);
this.invalidateQueryCache();
}
/**
@@ -108,6 +92,9 @@ export class ArchetypeSystem {
*/
public updateEntity(entity: Entity): void {
const currentArchetype = this._entityToArchetype.get(entity);
// 清理实体组件类型缓存,强制重新计算
this._entityComponentTypesCache.delete(entity);
const newComponentTypes = this.getEntityComponentTypes(entity);
const newArchetypeId = this.generateArchetypeId(newComponentTypes);
@@ -116,13 +103,12 @@ export class ArchetypeSystem {
return;
}
const affectedComponentTypes = new Set<ComponentType>();
// 从旧原型中移除实体
if (currentArchetype) {
const index = currentArchetype.entities.indexOf(entity);
if (index !== -1) {
currentArchetype.entities.splice(index, 1);
currentArchetype.updatedAt = Date.now();
}
currentArchetype.entities.delete(entity);
currentArchetype.componentTypes.forEach(type => affectedComponentTypes.add(type));
}
// 获取或创建新原型
@@ -132,9 +118,9 @@ export class ArchetypeSystem {
}
// 将实体添加到新原型
newArchetype.entities.push(entity);
newArchetype.updatedAt = Date.now();
newArchetype.entities.add(entity);
this._entityToArchetype.set(entity, newArchetype);
newComponentTypes.forEach(type => affectedComponentTypes.add(type));
// 更新组件索引
if (currentArchetype) {
@@ -142,27 +128,12 @@ export class ArchetypeSystem {
}
this.updateComponentIndexes(newArchetype, newComponentTypes, true);
// 使查询缓存失效
this.invalidateQueryCache();
}
/**
* 查询包含指定组件组合的原型
*/
public queryArchetypes(componentTypes: ComponentType[], operation: 'AND' | 'OR' = 'AND'): ArchetypeQueryResult {
const startTime = performance.now();
const cacheKey = `${operation}:${componentTypes.map(t => getComponentTypeName(t)).sort().join(',')}`;
// 检查缓存
const cached = this._queryCache.get(cacheKey);
if (cached && (Date.now() - cached.timestamp < this._cacheTimeout)) {
return {
...cached.result,
executionTime: performance.now() - startTime,
fromCache: true
};
}
const matchingArchetypes: Archetype[] = [];
let totalEntities = 0;
@@ -171,7 +142,7 @@ export class ArchetypeSystem {
for (const archetype of this._archetypes.values()) {
if (this.archetypeContainsAllComponents(archetype, componentTypes)) {
matchingArchetypes.push(archetype);
totalEntities += archetype.entities.length;
totalEntities += archetype.entities.size;
}
}
} else {
@@ -188,24 +159,14 @@ export class ArchetypeSystem {
for (const archetype of foundArchetypes) {
matchingArchetypes.push(archetype);
totalEntities += archetype.entities.length;
totalEntities += archetype.entities.size;
}
}
const result: ArchetypeQueryResult = {
return {
archetypes: matchingArchetypes,
totalEntities,
executionTime: performance.now() - startTime,
fromCache: false
totalEntities
};
// 缓存结果
this._queryCache.set(cacheKey, {
result,
timestamp: Date.now()
});
return result;
}
/**
@@ -229,24 +190,38 @@ export class ArchetypeSystem {
this._archetypes.clear();
this._entityToArchetype.clear();
this._componentToArchetypes.clear();
this._queryCache.clear();
this._entityComponentTypesCache.clear();
this._archetypeIdCache.clear();
}
/**
* 获取实体的组件类型列表
*/
private getEntityComponentTypes(entity: Entity): ComponentType[] {
return entity.components.map(component => component.constructor as ComponentType);
let componentTypes = this._entityComponentTypesCache.get(entity);
if (!componentTypes) {
componentTypes = entity.components.map(component => component.constructor as ComponentType);
this._entityComponentTypesCache.set(entity, componentTypes);
}
return componentTypes;
}
/**
* 生成原型ID
*/
private generateArchetypeId(componentTypes: ComponentType[]): ArchetypeId {
return componentTypes
// 创建缓存键
const cacheKey = componentTypes
.map(type => getComponentTypeName(type))
.sort()
.join('|');
let archetypeId = this._archetypeIdCache.get(cacheKey);
if (!archetypeId) {
archetypeId = cacheKey;
this._archetypeIdCache.set(cacheKey, archetypeId);
}
return archetypeId;
}
/**
@@ -258,9 +233,7 @@ export class ArchetypeSystem {
const archetype: Archetype = {
id,
componentTypes: [...componentTypes],
entities: [],
createdAt: Date.now(),
updatedAt: Date.now()
entities: new Set<Entity>()
};
this._archetypes.set(id, archetype);
@@ -301,10 +274,5 @@ export class ArchetypeSystem {
}
}
/**
* 使查询缓存失效
*/
private invalidateQueryCache(): void {
this._queryCache.clear();
}
}

View File

@@ -66,13 +66,6 @@ interface QueryCacheEntry {
* 高性能实体查询系统
*
* 提供快速的实体查询功能,支持按组件类型、标签、名称等多种方式查询实体。
* 系统采用多级索引和智能缓存机制,确保在大量实体场景下的查询性能。
*
* 主要特性:
* - 支持单组件和多组件查询
* - 自动索引管理和缓存优化
* - WebAssembly计算加速如果可用
* - 详细的性能统计信息
*
* @example
* ```typescript
@@ -96,12 +89,8 @@ export class QuerySystem {
private cacheMaxSize = 1000;
private cacheTimeout = 5000; // 5秒缓存过期
// 性能优化缓存
private componentNameCache = new WeakMap<ComponentType, string>();
private cacheKeyCache = new Map<string, string>();
private componentMaskCache = new Map<string, BitMask64Data>();
// 新增性能优化系统
private componentIndexManager: ComponentIndexManager;
private archetypeSystem: ArchetypeSystem;
@@ -862,7 +851,6 @@ export class QuerySystem {
*/
private clearQueryCache(): void {
this.queryCache.clear();
this.cacheKeyCache.clear();
this.componentMaskCache.clear();
}
@@ -872,34 +860,19 @@ export class QuerySystem {
private generateCacheKey(prefix: string, componentTypes: ComponentType[]): string {
// 快速路径:单组件查询
if (componentTypes.length === 1) {
let name = this.componentNameCache.get(componentTypes[0]);
if (!name) {
name = getComponentTypeName(componentTypes[0]);
this.componentNameCache.set(componentTypes[0], name);
}
const name = getComponentTypeName(componentTypes[0]);
return `${prefix}:${name}`;
}
// 多组件查询:使用排序后的类型名称创建键
const sortKey = componentTypes.map(t => {
let name = this.componentNameCache.get(t);
if (!name) {
name = getComponentTypeName(t);
this.componentNameCache.set(t, name);
}
const name = getComponentTypeName(t);
return name;
}).sort().join(',');
const fullKey = `${prefix}:${sortKey}`;
// 检查缓存的键是否已存在
let cachedKey = this.cacheKeyCache.get(fullKey);
if (!cachedKey) {
cachedKey = fullKey;
this.cacheKeyCache.set(fullKey, cachedKey);
}
return cachedKey;
return fullKey;
}
/**
@@ -923,11 +896,7 @@ export class QuerySystem {
private createComponentMask(componentTypes: ComponentType[]): BitMask64Data {
// 生成缓存键
const cacheKey = componentTypes.map(t => {
let name = this.componentNameCache.get(t);
if (!name) {
name = getComponentTypeName(t);
this.componentNameCache.set(t, name);
}
const name = getComponentTypeName(t);
return name;
}).sort().join(',');
@@ -1026,7 +995,7 @@ export class QuerySystem {
archetypeSystem: this.archetypeSystem.getAllArchetypes().map(a => ({
id: a.id,
componentTypes: a.componentTypes.map(t => getComponentTypeName(t)),
entityCount: a.entities.length
entityCount: a.entities.size
}))
},
cacheStats: {