refactor: 规范化代码注释和更新核心模块 - 移除冗余JSDoc注释,统一代码风格
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
import type { IComponent } from '../Types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 游戏组件基类
|
* 游戏组件基类
|
||||||
*
|
*
|
||||||
@@ -18,7 +20,7 @@
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export abstract class Component {
|
export abstract class Component implements IComponent {
|
||||||
/**
|
/**
|
||||||
* 组件ID生成器
|
* 组件ID生成器
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import { ecsCore } from '../../Utils/WasmCore';
|
|||||||
import { ComponentPoolManager } from './ComponentPool';
|
import { ComponentPoolManager } from './ComponentPool';
|
||||||
import { BitMaskOptimizer } from './BitMaskOptimizer';
|
import { BitMaskOptimizer } from './BitMaskOptimizer';
|
||||||
import { IndexUpdateBatcher } from './IndexUpdateBatcher';
|
import { IndexUpdateBatcher } from './IndexUpdateBatcher';
|
||||||
|
import { ComponentIndexManager, IndexType } from './ComponentIndex';
|
||||||
|
import { ArchetypeSystem, Archetype, ArchetypeQueryResult } from './ArchetypeSystem';
|
||||||
|
import { DirtyTrackingSystem, DirtyFlag } from './DirtyTrackingSystem';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询条件类型
|
* 查询条件类型
|
||||||
@@ -84,23 +87,30 @@ export class QuerySystem {
|
|||||||
private wasmAvailable = false;
|
private wasmAvailable = false;
|
||||||
private entityIndex: EntityIndex;
|
private entityIndex: EntityIndex;
|
||||||
private indexDirty = true;
|
private indexDirty = true;
|
||||||
|
|
||||||
// 查询缓存系统
|
// 查询缓存系统
|
||||||
private queryCache = new Map<string, QueryCacheEntry>();
|
private queryCache = new Map<string, QueryCacheEntry>();
|
||||||
private cacheMaxSize = 1000;
|
private cacheMaxSize = 1000;
|
||||||
private cacheTimeout = 5000; // 5秒缓存过期
|
private cacheTimeout = 5000; // 5秒缓存过期
|
||||||
|
|
||||||
// 优化组件
|
// 优化组件
|
||||||
private componentPoolManager: ComponentPoolManager;
|
private componentPoolManager: ComponentPoolManager;
|
||||||
private bitMaskOptimizer: BitMaskOptimizer;
|
private bitMaskOptimizer: BitMaskOptimizer;
|
||||||
private indexUpdateBatcher: IndexUpdateBatcher;
|
private indexUpdateBatcher: IndexUpdateBatcher;
|
||||||
|
|
||||||
|
// 新增性能优化系统
|
||||||
|
private componentIndexManager: ComponentIndexManager;
|
||||||
|
private archetypeSystem: ArchetypeSystem;
|
||||||
|
private dirtyTrackingSystem: DirtyTrackingSystem;
|
||||||
|
|
||||||
// 性能统计
|
// 性能统计
|
||||||
private queryStats = {
|
private queryStats = {
|
||||||
totalQueries: 0,
|
totalQueries: 0,
|
||||||
cacheHits: 0,
|
cacheHits: 0,
|
||||||
indexHits: 0,
|
indexHits: 0,
|
||||||
linearScans: 0
|
linearScans: 0,
|
||||||
|
archetypeHits: 0,
|
||||||
|
dirtyChecks: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -110,32 +120,37 @@ export class QuerySystem {
|
|||||||
byTag: new Map(),
|
byTag: new Map(),
|
||||||
byName: new Map()
|
byName: new Map()
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化优化组件
|
// 初始化优化组件
|
||||||
this.componentPoolManager = ComponentPoolManager.getInstance();
|
this.componentPoolManager = ComponentPoolManager.getInstance();
|
||||||
this.bitMaskOptimizer = BitMaskOptimizer.getInstance();
|
this.bitMaskOptimizer = BitMaskOptimizer.getInstance();
|
||||||
this.indexUpdateBatcher = new IndexUpdateBatcher();
|
this.indexUpdateBatcher = new IndexUpdateBatcher();
|
||||||
|
|
||||||
|
// 初始化新的性能优化系统
|
||||||
|
this.componentIndexManager = new ComponentIndexManager(IndexType.HASH);
|
||||||
|
this.archetypeSystem = new ArchetypeSystem();
|
||||||
|
this.dirtyTrackingSystem = new DirtyTrackingSystem();
|
||||||
|
|
||||||
// 设置索引更新批处理器的回调
|
// 设置索引更新批处理器的回调
|
||||||
this.indexUpdateBatcher.onBatchAdd = (entities) => {
|
this.indexUpdateBatcher.onBatchAdd = (entities) => {
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
this.addEntityToIndexes(entity);
|
this.addEntityToIndexes(entity);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.indexUpdateBatcher.onBatchRemove = (entities) => {
|
this.indexUpdateBatcher.onBatchRemove = (entities) => {
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
this.removeEntityFromIndexes(entity);
|
this.removeEntityFromIndexes(entity);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.indexUpdateBatcher.onBatchUpdate = (updates) => {
|
this.indexUpdateBatcher.onBatchUpdate = (updates) => {
|
||||||
for (const update of updates) {
|
for (const update of updates) {
|
||||||
this.removeEntityFromIndexes(update.entity);
|
this.removeEntityFromIndexes(update.entity);
|
||||||
this.addEntityToIndexes(update.entity);
|
this.addEntityToIndexes(update.entity);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.initializeWasm();
|
this.initializeWasm();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +164,7 @@ export class QuerySystem {
|
|||||||
try {
|
try {
|
||||||
const wasmLoaded = await ecsCore.initialize();
|
const wasmLoaded = await ecsCore.initialize();
|
||||||
this.wasmAvailable = wasmLoaded && ecsCore.isUsingWasm();
|
this.wasmAvailable = wasmLoaded && ecsCore.isUsingWasm();
|
||||||
|
|
||||||
if (this.wasmAvailable) {
|
if (this.wasmAvailable) {
|
||||||
console.log('QuerySystem: WebAssembly计算加速已启用');
|
console.log('QuerySystem: WebAssembly计算加速已启用');
|
||||||
} else {
|
} else {
|
||||||
@@ -188,7 +203,11 @@ export class QuerySystem {
|
|||||||
if (!this.entities.includes(entity)) {
|
if (!this.entities.includes(entity)) {
|
||||||
this.entities.push(entity);
|
this.entities.push(entity);
|
||||||
this.addEntityToIndexes(entity);
|
this.addEntityToIndexes(entity);
|
||||||
|
|
||||||
|
this.componentIndexManager.addEntity(entity);
|
||||||
|
this.archetypeSystem.addEntity(entity);
|
||||||
|
this.dirtyTrackingSystem.markDirty(entity, DirtyFlag.COMPONENT_ADDED);
|
||||||
|
|
||||||
// 只有在非延迟模式下才立即清理缓存
|
// 只有在非延迟模式下才立即清理缓存
|
||||||
if (!deferCacheClear) {
|
if (!deferCacheClear) {
|
||||||
this.clearQueryCache();
|
this.clearQueryCache();
|
||||||
@@ -206,11 +225,11 @@ export class QuerySystem {
|
|||||||
*/
|
*/
|
||||||
public addEntities(entities: Entity[]): void {
|
public addEntities(entities: Entity[]): void {
|
||||||
if (entities.length === 0) return;
|
if (entities.length === 0) return;
|
||||||
|
|
||||||
// 使用Set来快速检查重复
|
// 使用Set来快速检查重复
|
||||||
const existingIds = new Set(this.entities.map(e => e.id));
|
const existingIds = new Set(this.entities.map(e => e.id));
|
||||||
let addedCount = 0;
|
let addedCount = 0;
|
||||||
|
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
if (!existingIds.has(entity.id)) {
|
if (!existingIds.has(entity.id)) {
|
||||||
this.entities.push(entity);
|
this.entities.push(entity);
|
||||||
@@ -219,7 +238,7 @@ export class QuerySystem {
|
|||||||
addedCount++;
|
addedCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只在有实体被添加时才清理缓存
|
// 只在有实体被添加时才清理缓存
|
||||||
if (addedCount > 0) {
|
if (addedCount > 0) {
|
||||||
this.clearQueryCache();
|
this.clearQueryCache();
|
||||||
@@ -236,17 +255,17 @@ export class QuerySystem {
|
|||||||
*/
|
*/
|
||||||
public addEntitiesUnchecked(entities: Entity[]): void {
|
public addEntitiesUnchecked(entities: Entity[]): void {
|
||||||
if (entities.length === 0) return;
|
if (entities.length === 0) return;
|
||||||
|
|
||||||
// 避免调用栈溢出,分批添加
|
// 避免调用栈溢出,分批添加
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
this.entities.push(entity);
|
this.entities.push(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量更新索引
|
// 批量更新索引
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
this.addEntityToIndexes(entity);
|
this.addEntityToIndexes(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理缓存
|
// 清理缓存
|
||||||
this.clearQueryCache();
|
this.clearQueryCache();
|
||||||
}
|
}
|
||||||
@@ -263,6 +282,11 @@ export class QuerySystem {
|
|||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
this.entities.splice(index, 1);
|
this.entities.splice(index, 1);
|
||||||
this.removeEntityFromIndexes(entity);
|
this.removeEntityFromIndexes(entity);
|
||||||
|
|
||||||
|
this.componentIndexManager.removeEntity(entity);
|
||||||
|
this.archetypeSystem.removeEntity(entity);
|
||||||
|
this.dirtyTrackingSystem.markDirty(entity, DirtyFlag.COMPONENT_REMOVED);
|
||||||
|
|
||||||
this.clearQueryCache();
|
this.clearQueryCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -272,7 +296,7 @@ export class QuerySystem {
|
|||||||
*/
|
*/
|
||||||
private addEntityToIndexes(entity: Entity): void {
|
private addEntityToIndexes(entity: Entity): void {
|
||||||
const mask = entity.componentMask;
|
const mask = entity.componentMask;
|
||||||
|
|
||||||
// 组件掩码索引 - 优化Map操作
|
// 组件掩码索引 - 优化Map操作
|
||||||
let maskSet = this.entityIndex.byMask.get(mask);
|
let maskSet = this.entityIndex.byMask.get(mask);
|
||||||
if (!maskSet) {
|
if (!maskSet) {
|
||||||
@@ -280,7 +304,7 @@ export class QuerySystem {
|
|||||||
this.entityIndex.byMask.set(mask, maskSet);
|
this.entityIndex.byMask.set(mask, maskSet);
|
||||||
}
|
}
|
||||||
maskSet.add(entity);
|
maskSet.add(entity);
|
||||||
|
|
||||||
// 组件类型索引 - 批量处理
|
// 组件类型索引 - 批量处理
|
||||||
const components = entity.components;
|
const components = entity.components;
|
||||||
for (let i = 0; i < components.length; i++) {
|
for (let i = 0; i < components.length; i++) {
|
||||||
@@ -292,7 +316,7 @@ export class QuerySystem {
|
|||||||
}
|
}
|
||||||
typeSet.add(entity);
|
typeSet.add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 标签索引 - 只在有标签时处理
|
// 标签索引 - 只在有标签时处理
|
||||||
const tag = entity.tag;
|
const tag = entity.tag;
|
||||||
if (tag !== undefined) {
|
if (tag !== undefined) {
|
||||||
@@ -303,7 +327,7 @@ export class QuerySystem {
|
|||||||
}
|
}
|
||||||
tagSet.add(entity);
|
tagSet.add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 名称索引 - 只在有名称时处理
|
// 名称索引 - 只在有名称时处理
|
||||||
const name = entity.name;
|
const name = entity.name;
|
||||||
if (name) {
|
if (name) {
|
||||||
@@ -321,7 +345,7 @@ export class QuerySystem {
|
|||||||
*/
|
*/
|
||||||
private removeEntityFromIndexes(entity: Entity): void {
|
private removeEntityFromIndexes(entity: Entity): void {
|
||||||
const mask = entity.componentMask;
|
const mask = entity.componentMask;
|
||||||
|
|
||||||
// 从组件掩码索引移除
|
// 从组件掩码索引移除
|
||||||
const maskSet = this.entityIndex.byMask.get(mask);
|
const maskSet = this.entityIndex.byMask.get(mask);
|
||||||
if (maskSet) {
|
if (maskSet) {
|
||||||
@@ -330,7 +354,7 @@ export class QuerySystem {
|
|||||||
this.entityIndex.byMask.delete(mask);
|
this.entityIndex.byMask.delete(mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从组件类型索引移除
|
// 从组件类型索引移除
|
||||||
for (const component of entity.components) {
|
for (const component of entity.components) {
|
||||||
const componentType = component.constructor as ComponentType;
|
const componentType = component.constructor as ComponentType;
|
||||||
@@ -342,7 +366,7 @@ export class QuerySystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从标签索引移除
|
// 从标签索引移除
|
||||||
if (entity.tag !== undefined) {
|
if (entity.tag !== undefined) {
|
||||||
const tagSet = this.entityIndex.byTag.get(entity.tag);
|
const tagSet = this.entityIndex.byTag.get(entity.tag);
|
||||||
@@ -353,7 +377,7 @@ export class QuerySystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从名称索引移除
|
// 从名称索引移除
|
||||||
if (entity.name) {
|
if (entity.name) {
|
||||||
const nameSet = this.entityIndex.byName.get(entity.name);
|
const nameSet = this.entityIndex.byName.get(entity.name);
|
||||||
@@ -377,11 +401,11 @@ export class QuerySystem {
|
|||||||
this.entityIndex.byComponentType.clear();
|
this.entityIndex.byComponentType.clear();
|
||||||
this.entityIndex.byTag.clear();
|
this.entityIndex.byTag.clear();
|
||||||
this.entityIndex.byName.clear();
|
this.entityIndex.byName.clear();
|
||||||
|
|
||||||
for (const entity of this.entities) {
|
for (const entity of this.entities) {
|
||||||
this.addEntityToIndexes(entity);
|
this.addEntityToIndexes(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.indexDirty = false;
|
this.indexDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,10 +428,10 @@ export class QuerySystem {
|
|||||||
public queryAll(...componentTypes: ComponentType[]): QueryResult {
|
public queryAll(...componentTypes: ComponentType[]): QueryResult {
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
this.queryStats.totalQueries++;
|
this.queryStats.totalQueries++;
|
||||||
|
|
||||||
// 生成缓存键
|
// 生成缓存键
|
||||||
const cacheKey = `all:${componentTypes.map(t => t.name).sort().join(',')}`;
|
const cacheKey = `all:${componentTypes.map(t => t.name).sort().join(',')}`;
|
||||||
|
|
||||||
// 检查缓存
|
// 检查缓存
|
||||||
const cached = this.getFromCache(cacheKey);
|
const cached = this.getFromCache(cacheKey);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
@@ -419,21 +443,28 @@ export class QuerySystem {
|
|||||||
fromCache: true
|
fromCache: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let entities: Entity[];
|
let entities: Entity[];
|
||||||
|
|
||||||
// 单组件查询:直接使用索引
|
const archetypeResult = this.archetypeSystem.queryArchetypes(componentTypes, 'AND');
|
||||||
if (componentTypes.length === 1) {
|
if (archetypeResult.archetypes.length > 0) {
|
||||||
|
this.queryStats.archetypeHits++;
|
||||||
|
entities = [];
|
||||||
|
for (const archetype of archetypeResult.archetypes) {
|
||||||
|
entities.push(...archetype.entities);
|
||||||
|
}
|
||||||
|
} else if (componentTypes.length === 1) {
|
||||||
this.queryStats.indexHits++;
|
this.queryStats.indexHits++;
|
||||||
entities = Array.from(this.entityIndex.byComponentType.get(componentTypes[0]) || []);
|
const indexResult = this.componentIndexManager.query(componentTypes[0]);
|
||||||
|
entities = Array.from(indexResult);
|
||||||
} else {
|
} else {
|
||||||
// 多组件查询:使用高效算法
|
const indexResult = this.componentIndexManager.queryMultiple(componentTypes, 'AND');
|
||||||
entities = this.queryMultipleComponents(componentTypes);
|
entities = Array.from(indexResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存结果
|
// 缓存结果
|
||||||
this.addToCache(cacheKey, entities);
|
this.addToCache(cacheKey, entities);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entities,
|
entities,
|
||||||
count: entities.length,
|
count: entities.length,
|
||||||
@@ -455,7 +486,7 @@ export class QuerySystem {
|
|||||||
// 找到最小的组件集合作为起点
|
// 找到最小的组件集合作为起点
|
||||||
let smallestSet: Set<Entity> | null = null;
|
let smallestSet: Set<Entity> | null = null;
|
||||||
let smallestSize = Infinity;
|
let smallestSize = Infinity;
|
||||||
|
|
||||||
for (const componentType of componentTypes) {
|
for (const componentType of componentTypes) {
|
||||||
const set = this.entityIndex.byComponentType.get(componentType);
|
const set = this.entityIndex.byComponentType.get(componentType);
|
||||||
if (!set || set.size === 0) {
|
if (!set || set.size === 0) {
|
||||||
@@ -466,22 +497,22 @@ export class QuerySystem {
|
|||||||
smallestSet = set;
|
smallestSet = set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!smallestSet) {
|
if (!smallestSet) {
|
||||||
this.queryStats.linearScans++;
|
this.queryStats.linearScans++;
|
||||||
return this.queryByLinearScan(componentTypes);
|
return this.queryByLinearScan(componentTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从最小集合开始,逐步过滤
|
// 从最小集合开始,逐步过滤
|
||||||
const mask = this.createComponentMask(componentTypes);
|
const mask = this.createComponentMask(componentTypes);
|
||||||
const result: Entity[] = [];
|
const result: Entity[] = [];
|
||||||
|
|
||||||
for (const entity of smallestSet) {
|
for (const entity of smallestSet) {
|
||||||
if ((entity.componentMask & mask) === mask) {
|
if ((entity.componentMask & mask) === mask) {
|
||||||
result.push(entity);
|
result.push(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,7 +527,7 @@ export class QuerySystem {
|
|||||||
*/
|
*/
|
||||||
private queryByLinearScan(componentTypes: ComponentType[]): Entity[] {
|
private queryByLinearScan(componentTypes: ComponentType[]): Entity[] {
|
||||||
const mask = this.createComponentMask(componentTypes);
|
const mask = this.createComponentMask(componentTypes);
|
||||||
return this.entities.filter(entity =>
|
return this.entities.filter(entity =>
|
||||||
(entity.componentMask & mask) === mask
|
(entity.componentMask & mask) === mask
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -520,9 +551,9 @@ export class QuerySystem {
|
|||||||
public queryAny(...componentTypes: ComponentType[]): QueryResult {
|
public queryAny(...componentTypes: ComponentType[]): QueryResult {
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
this.queryStats.totalQueries++;
|
this.queryStats.totalQueries++;
|
||||||
|
|
||||||
const cacheKey = `any:${componentTypes.map(t => t.name).sort().join(',')}`;
|
const cacheKey = `any:${componentTypes.map(t => t.name).sort().join(',')}`;
|
||||||
|
|
||||||
// 检查缓存
|
// 检查缓存
|
||||||
const cached = this.getFromCache(cacheKey);
|
const cached = this.getFromCache(cacheKey);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
@@ -534,21 +565,22 @@ export class QuerySystem {
|
|||||||
fromCache: true
|
fromCache: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用集合合并
|
const archetypeResult = this.archetypeSystem.queryArchetypes(componentTypes, 'OR');
|
||||||
const entitySet = new Set<Entity>();
|
let entities: Entity[];
|
||||||
for (const componentType of componentTypes) {
|
|
||||||
const typeEntities = this.entityIndex.byComponentType.get(componentType);
|
if (archetypeResult.archetypes.length > 0) {
|
||||||
if (typeEntities) {
|
this.queryStats.archetypeHits++;
|
||||||
for (const entity of typeEntities) {
|
entities = [];
|
||||||
entitySet.add(entity);
|
for (const archetype of archetypeResult.archetypes) {
|
||||||
}
|
entities.push(...archetype.entities);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const indexResult = this.componentIndexManager.queryMultiple(componentTypes, 'OR');
|
||||||
|
entities = Array.from(indexResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
const entities = Array.from(entitySet);
|
|
||||||
this.addToCache(cacheKey, entities);
|
this.addToCache(cacheKey, entities);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entities,
|
entities,
|
||||||
count: entities.length,
|
count: entities.length,
|
||||||
@@ -576,9 +608,9 @@ export class QuerySystem {
|
|||||||
public queryNone(...componentTypes: ComponentType[]): QueryResult {
|
public queryNone(...componentTypes: ComponentType[]): QueryResult {
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
this.queryStats.totalQueries++;
|
this.queryStats.totalQueries++;
|
||||||
|
|
||||||
const cacheKey = `none:${componentTypes.map(t => t.name).sort().join(',')}`;
|
const cacheKey = `none:${componentTypes.map(t => t.name).sort().join(',')}`;
|
||||||
|
|
||||||
// 检查缓存
|
// 检查缓存
|
||||||
const cached = this.getFromCache(cacheKey);
|
const cached = this.getFromCache(cacheKey);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
@@ -590,14 +622,14 @@ export class QuerySystem {
|
|||||||
fromCache: true
|
fromCache: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const mask = this.createComponentMask(componentTypes);
|
const mask = this.createComponentMask(componentTypes);
|
||||||
const entities = this.entities.filter(entity =>
|
const entities = this.entities.filter(entity =>
|
||||||
(entity.componentMask & mask) === BigInt(0)
|
(entity.componentMask & mask) === BigInt(0)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.addToCache(cacheKey, entities);
|
this.addToCache(cacheKey, entities);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entities,
|
entities,
|
||||||
count: entities.length,
|
count: entities.length,
|
||||||
@@ -624,9 +656,9 @@ export class QuerySystem {
|
|||||||
public queryByTag(tag: number): QueryResult {
|
public queryByTag(tag: number): QueryResult {
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
this.queryStats.totalQueries++;
|
this.queryStats.totalQueries++;
|
||||||
|
|
||||||
const cacheKey = `tag:${tag}`;
|
const cacheKey = `tag:${tag}`;
|
||||||
|
|
||||||
// 检查缓存
|
// 检查缓存
|
||||||
const cached = this.getFromCache(cacheKey);
|
const cached = this.getFromCache(cacheKey);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
@@ -638,14 +670,14 @@ export class QuerySystem {
|
|||||||
fromCache: true
|
fromCache: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用索引查询
|
// 使用索引查询
|
||||||
this.queryStats.indexHits++;
|
this.queryStats.indexHits++;
|
||||||
const entities = Array.from(this.entityIndex.byTag.get(tag) || []);
|
const entities = Array.from(this.entityIndex.byTag.get(tag) || []);
|
||||||
|
|
||||||
// 缓存结果
|
// 缓存结果
|
||||||
this.addToCache(cacheKey, entities);
|
this.addToCache(cacheKey, entities);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entities,
|
entities,
|
||||||
count: entities.length,
|
count: entities.length,
|
||||||
@@ -672,9 +704,9 @@ export class QuerySystem {
|
|||||||
public queryByName(name: string): QueryResult {
|
public queryByName(name: string): QueryResult {
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
this.queryStats.totalQueries++;
|
this.queryStats.totalQueries++;
|
||||||
|
|
||||||
const cacheKey = `name:${name}`;
|
const cacheKey = `name:${name}`;
|
||||||
|
|
||||||
// 检查缓存
|
// 检查缓存
|
||||||
const cached = this.getFromCache(cacheKey);
|
const cached = this.getFromCache(cacheKey);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
@@ -686,14 +718,14 @@ export class QuerySystem {
|
|||||||
fromCache: true
|
fromCache: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用索引查询
|
// 使用索引查询
|
||||||
this.queryStats.indexHits++;
|
this.queryStats.indexHits++;
|
||||||
const entities = Array.from(this.entityIndex.byName.get(name) || []);
|
const entities = Array.from(this.entityIndex.byName.get(name) || []);
|
||||||
|
|
||||||
// 缓存结果
|
// 缓存结果
|
||||||
this.addToCache(cacheKey, entities);
|
this.addToCache(cacheKey, entities);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entities,
|
entities,
|
||||||
count: entities.length,
|
count: entities.length,
|
||||||
@@ -720,9 +752,9 @@ export class QuerySystem {
|
|||||||
public queryByComponent<T extends Component>(componentType: ComponentType<T>): QueryResult {
|
public queryByComponent<T extends Component>(componentType: ComponentType<T>): QueryResult {
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
this.queryStats.totalQueries++;
|
this.queryStats.totalQueries++;
|
||||||
|
|
||||||
const cacheKey = `component:${componentType.name}`;
|
const cacheKey = `component:${componentType.name}`;
|
||||||
|
|
||||||
// 检查缓存
|
// 检查缓存
|
||||||
const cached = this.getFromCache(cacheKey);
|
const cached = this.getFromCache(cacheKey);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
@@ -734,14 +766,14 @@ export class QuerySystem {
|
|||||||
fromCache: true
|
fromCache: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用索引查询
|
// 使用索引查询
|
||||||
this.queryStats.indexHits++;
|
this.queryStats.indexHits++;
|
||||||
const entities = Array.from(this.entityIndex.byComponentType.get(componentType) || []);
|
const entities = Array.from(this.entityIndex.byComponentType.get(componentType) || []);
|
||||||
|
|
||||||
// 缓存结果
|
// 缓存结果
|
||||||
this.addToCache(cacheKey, entities);
|
this.addToCache(cacheKey, entities);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entities,
|
entities,
|
||||||
count: entities.length,
|
count: entities.length,
|
||||||
@@ -756,13 +788,13 @@ export class QuerySystem {
|
|||||||
private getFromCache(cacheKey: string): Entity[] | null {
|
private getFromCache(cacheKey: string): Entity[] | null {
|
||||||
const entry = this.queryCache.get(cacheKey);
|
const entry = this.queryCache.get(cacheKey);
|
||||||
if (!entry) return null;
|
if (!entry) return null;
|
||||||
|
|
||||||
// 检查缓存是否过期
|
// 检查缓存是否过期
|
||||||
if (Date.now() - entry.timestamp > this.cacheTimeout) {
|
if (Date.now() - entry.timestamp > this.cacheTimeout) {
|
||||||
this.queryCache.delete(cacheKey);
|
this.queryCache.delete(cacheKey);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.hitCount++;
|
entry.hitCount++;
|
||||||
return entry.entities;
|
return entry.entities;
|
||||||
}
|
}
|
||||||
@@ -775,7 +807,7 @@ export class QuerySystem {
|
|||||||
if (this.queryCache.size >= this.cacheMaxSize) {
|
if (this.queryCache.size >= this.cacheMaxSize) {
|
||||||
this.cleanupCache();
|
this.cleanupCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.queryCache.set(cacheKey, {
|
this.queryCache.set(cacheKey, {
|
||||||
entities: [...entities], // 复制数组避免引用问题
|
entities: [...entities], // 复制数组避免引用问题
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
@@ -794,12 +826,12 @@ export class QuerySystem {
|
|||||||
this.queryCache.delete(key);
|
this.queryCache.delete(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果还是太满,移除最少使用的条目
|
// 如果还是太满,移除最少使用的条目
|
||||||
if (this.queryCache.size >= this.cacheMaxSize) {
|
if (this.queryCache.size >= this.cacheMaxSize) {
|
||||||
const entries = Array.from(this.queryCache.entries());
|
const entries = Array.from(this.queryCache.entries());
|
||||||
entries.sort((a, b) => a[1].hitCount - b[1].hitCount);
|
entries.sort((a, b) => a[1].hitCount - b[1].hitCount);
|
||||||
|
|
||||||
const toRemove = Math.floor(this.cacheMaxSize * 0.2); // 移除20%
|
const toRemove = Math.floor(this.cacheMaxSize * 0.2); // 移除20%
|
||||||
for (let i = 0; i < toRemove && i < entries.length; i++) {
|
for (let i = 0; i < toRemove && i < entries.length; i++) {
|
||||||
this.queryCache.delete(entries[i][0]);
|
this.queryCache.delete(entries[i][0]);
|
||||||
@@ -841,7 +873,7 @@ export class QuerySystem {
|
|||||||
* querySystem.batchUpdateComponents(updates);
|
* querySystem.batchUpdateComponents(updates);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public batchUpdateComponents(updates: Array<{entityId: number, componentMask: bigint}>): void {
|
public batchUpdateComponents(updates: Array<{ entityId: number, componentMask: bigint }>): void {
|
||||||
if (this.wasmAvailable && updates.length > 100) {
|
if (this.wasmAvailable && updates.length > 100) {
|
||||||
try {
|
try {
|
||||||
const entityIds = updates.map(u => u.entityId);
|
const entityIds = updates.map(u => u.entityId);
|
||||||
@@ -855,7 +887,7 @@ export class QuerySystem {
|
|||||||
} else {
|
} else {
|
||||||
this.batchUpdateComponentsJS(updates);
|
this.batchUpdateComponentsJS(updates);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量更新后清除缓存
|
// 批量更新后清除缓存
|
||||||
this.clearQueryCache();
|
this.clearQueryCache();
|
||||||
}
|
}
|
||||||
@@ -863,7 +895,7 @@ export class QuerySystem {
|
|||||||
/**
|
/**
|
||||||
* JavaScript实现的批量更新
|
* JavaScript实现的批量更新
|
||||||
*/
|
*/
|
||||||
private batchUpdateComponentsJS(updates: Array<{entityId: number, componentMask: bigint}>): void {
|
private batchUpdateComponentsJS(updates: Array<{ entityId: number, componentMask: bigint }>): void {
|
||||||
for (const update of updates) {
|
for (const update of updates) {
|
||||||
const entity = this.entities.find(e => e.id === update.entityId);
|
const entity = this.entities.find(e => e.id === update.entityId);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
@@ -897,7 +929,7 @@ export class QuerySystem {
|
|||||||
wasmEnabled: this.wasmAvailable,
|
wasmEnabled: this.wasmAvailable,
|
||||||
cacheStats: {
|
cacheStats: {
|
||||||
size: this.queryCache.size,
|
size: this.queryCache.size,
|
||||||
hitRate: this.queryStats.totalQueries > 0 ?
|
hitRate: this.queryStats.totalQueries > 0 ?
|
||||||
(this.queryStats.cacheHits / this.queryStats.totalQueries * 100).toFixed(2) + '%' : '0%'
|
(this.queryStats.cacheHits / this.queryStats.totalQueries * 100).toFixed(2) + '%' : '0%'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -929,12 +961,12 @@ export class QuerySystem {
|
|||||||
private createComponentMask(componentTypes: ComponentType[]): bigint {
|
private createComponentMask(componentTypes: ComponentType[]): bigint {
|
||||||
// 使用位掩码优化器创建掩码
|
// 使用位掩码优化器创建掩码
|
||||||
const componentNames = componentTypes.map(type => type.name);
|
const componentNames = componentTypes.map(type => type.name);
|
||||||
|
|
||||||
// 确保组件类型已注册到优化器
|
// 确保组件类型已注册到优化器
|
||||||
for (const name of componentNames) {
|
for (const name of componentNames) {
|
||||||
this.bitMaskOptimizer.registerComponentType(name);
|
this.bitMaskOptimizer.registerComponentType(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.bitMaskOptimizer.createCombinedMask(componentNames);
|
return this.bitMaskOptimizer.createCombinedMask(componentNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -960,8 +992,15 @@ export class QuerySystem {
|
|||||||
cacheHits: number;
|
cacheHits: number;
|
||||||
indexHits: number;
|
indexHits: number;
|
||||||
linearScans: number;
|
linearScans: number;
|
||||||
|
archetypeHits: number;
|
||||||
|
dirtyChecks: number;
|
||||||
cacheHitRate: string;
|
cacheHitRate: string;
|
||||||
};
|
};
|
||||||
|
optimizationStats: {
|
||||||
|
componentIndex: any;
|
||||||
|
archetypeSystem: any;
|
||||||
|
dirtyTracking: any;
|
||||||
|
};
|
||||||
} {
|
} {
|
||||||
return {
|
return {
|
||||||
entityCount: this.entities.length,
|
entityCount: this.entities.length,
|
||||||
@@ -974,11 +1013,89 @@ export class QuerySystem {
|
|||||||
accelerationStatus: this.getAccelerationStatus(),
|
accelerationStatus: this.getAccelerationStatus(),
|
||||||
queryStats: {
|
queryStats: {
|
||||||
...this.queryStats,
|
...this.queryStats,
|
||||||
cacheHitRate: this.queryStats.totalQueries > 0 ?
|
cacheHitRate: this.queryStats.totalQueries > 0 ?
|
||||||
(this.queryStats.cacheHits / this.queryStats.totalQueries * 100).toFixed(2) + '%' : '0%'
|
(this.queryStats.cacheHits / this.queryStats.totalQueries * 100).toFixed(2) + '%' : '0%'
|
||||||
|
},
|
||||||
|
optimizationStats: {
|
||||||
|
componentIndex: this.componentIndexManager.getStats(),
|
||||||
|
archetypeSystem: this.archetypeSystem.getAllArchetypes().map(a => ({
|
||||||
|
id: a.id,
|
||||||
|
componentTypes: a.componentTypes.map(t => t.name),
|
||||||
|
entityCount: a.entities.length
|
||||||
|
})),
|
||||||
|
dirtyTracking: this.dirtyTrackingSystem.getStats()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换组件索引类型
|
||||||
|
*
|
||||||
|
* @param indexType 新的索引类型
|
||||||
|
*/
|
||||||
|
public switchComponentIndexType(indexType: IndexType): void {
|
||||||
|
this.componentIndexManager.switchIndexType(indexType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置脏标记系统
|
||||||
|
*
|
||||||
|
* @param batchSize 批处理大小
|
||||||
|
* @param maxProcessingTime 最大处理时间
|
||||||
|
*/
|
||||||
|
public configureDirtyTracking(batchSize: number, maxProcessingTime: number): void {
|
||||||
|
this.dirtyTrackingSystem.configureBatchProcessing(batchSize, maxProcessingTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动触发性能优化
|
||||||
|
*/
|
||||||
|
public optimizePerformance(): void {
|
||||||
|
this.dirtyTrackingSystem.processDirtyEntities();
|
||||||
|
this.cleanupCache();
|
||||||
|
|
||||||
|
const stats = this.componentIndexManager.getStats();
|
||||||
|
if (stats.avgQueryTime > 2.0 && stats.type !== IndexType.HASH) {
|
||||||
|
this.switchComponentIndexType(IndexType.HASH);
|
||||||
|
} else if (stats.memoryUsage > 50 * 1024 * 1024 && stats.type !== IndexType.BITMAP) {
|
||||||
|
this.switchComponentIndexType(IndexType.BITMAP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始新的帧
|
||||||
|
*/
|
||||||
|
public beginFrame(): void {
|
||||||
|
this.dirtyTrackingSystem.beginFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束当前帧
|
||||||
|
*/
|
||||||
|
public endFrame(): void {
|
||||||
|
this.dirtyTrackingSystem.endFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记实体组件已修改(用于脏标记追踪)
|
||||||
|
*
|
||||||
|
* @param entity 修改的实体
|
||||||
|
* @param componentTypes 修改的组件类型
|
||||||
|
*/
|
||||||
|
public markEntityDirty(entity: Entity, componentTypes: ComponentType[]): void {
|
||||||
|
this.queryStats.dirtyChecks++;
|
||||||
|
this.dirtyTrackingSystem.markDirty(entity, DirtyFlag.COMPONENT_MODIFIED, componentTypes);
|
||||||
|
this.clearQueryCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实体所属的原型信息
|
||||||
|
*
|
||||||
|
* @param entity 要查询的实体
|
||||||
|
*/
|
||||||
|
public getEntityArchetype(entity: Entity): Archetype | undefined {
|
||||||
|
return this.archetypeSystem.getEntityArchetype(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1057,7 +1174,7 @@ export class QueryBuilder {
|
|||||||
*/
|
*/
|
||||||
public execute(): QueryResult {
|
public execute(): QueryResult {
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
|
|
||||||
// 简化实现:目前只支持单一条件
|
// 简化实现:目前只支持单一条件
|
||||||
if (this.conditions.length === 1) {
|
if (this.conditions.length === 1) {
|
||||||
const condition = this.conditions[0];
|
const condition = this.conditions[0];
|
||||||
@@ -1070,7 +1187,7 @@ export class QueryBuilder {
|
|||||||
return this.querySystem.queryNone(...condition.componentTypes);
|
return this.querySystem.queryNone(...condition.componentTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 多条件查询的复杂实现留待后续扩展
|
// 多条件查询的复杂实现留待后续扩展
|
||||||
return {
|
return {
|
||||||
entities: [],
|
entities: [],
|
||||||
|
|||||||
@@ -16,3 +16,194 @@ export enum CoreEvents {
|
|||||||
*/
|
*/
|
||||||
renderChanged,
|
renderChanged,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECS事件类型枚举
|
||||||
|
* 定义实体组件系统中的所有事件类型
|
||||||
|
*/
|
||||||
|
export enum ECSEventType {
|
||||||
|
// 实体相关事件
|
||||||
|
ENTITY_CREATED = 'entity:created',
|
||||||
|
ENTITY_DESTROYED = 'entity:destroyed',
|
||||||
|
ENTITY_ENABLED = 'entity:enabled',
|
||||||
|
ENTITY_DISABLED = 'entity:disabled',
|
||||||
|
ENTITY_TAG_ADDED = 'entity:tag:added',
|
||||||
|
ENTITY_TAG_REMOVED = 'entity:tag:removed',
|
||||||
|
ENTITY_NAME_CHANGED = 'entity:name:changed',
|
||||||
|
|
||||||
|
// 组件相关事件
|
||||||
|
COMPONENT_ADDED = 'component:added',
|
||||||
|
COMPONENT_REMOVED = 'component:removed',
|
||||||
|
COMPONENT_MODIFIED = 'component:modified',
|
||||||
|
COMPONENT_ENABLED = 'component:enabled',
|
||||||
|
COMPONENT_DISABLED = 'component:disabled',
|
||||||
|
|
||||||
|
// 系统相关事件
|
||||||
|
SYSTEM_ADDED = 'system:added',
|
||||||
|
SYSTEM_REMOVED = 'system:removed',
|
||||||
|
SYSTEM_ENABLED = 'system:enabled',
|
||||||
|
SYSTEM_DISABLED = 'system:disabled',
|
||||||
|
SYSTEM_PROCESSING_START = 'system:processing:start',
|
||||||
|
SYSTEM_PROCESSING_END = 'system:processing:end',
|
||||||
|
SYSTEM_ERROR = 'system:error',
|
||||||
|
|
||||||
|
// 场景相关事件
|
||||||
|
SCENE_CREATED = 'scene:created',
|
||||||
|
SCENE_DESTROYED = 'scene:destroyed',
|
||||||
|
SCENE_ACTIVATED = 'scene:activated',
|
||||||
|
SCENE_DEACTIVATED = 'scene:deactivated',
|
||||||
|
SCENE_PAUSED = 'scene:paused',
|
||||||
|
SCENE_RESUMED = 'scene:resumed',
|
||||||
|
|
||||||
|
// 查询相关事件
|
||||||
|
QUERY_EXECUTED = 'query:executed',
|
||||||
|
QUERY_CACHE_HIT = 'query:cache:hit',
|
||||||
|
QUERY_CACHE_MISS = 'query:cache:miss',
|
||||||
|
QUERY_OPTIMIZED = 'query:optimized',
|
||||||
|
|
||||||
|
// 性能相关事件
|
||||||
|
PERFORMANCE_WARNING = 'performance:warning',
|
||||||
|
PERFORMANCE_CRITICAL = 'performance:critical',
|
||||||
|
MEMORY_USAGE_HIGH = 'memory:usage:high',
|
||||||
|
FRAME_RATE_DROP = 'frame:rate:drop',
|
||||||
|
|
||||||
|
// 索引相关事件
|
||||||
|
INDEX_CREATED = 'index:created',
|
||||||
|
INDEX_UPDATED = 'index:updated',
|
||||||
|
INDEX_OPTIMIZED = 'index:optimized',
|
||||||
|
|
||||||
|
// Archetype相关事件
|
||||||
|
ARCHETYPE_CREATED = 'archetype:created',
|
||||||
|
ARCHETYPE_ENTITY_ADDED = 'archetype:entity:added',
|
||||||
|
ARCHETYPE_ENTITY_REMOVED = 'archetype:entity:removed',
|
||||||
|
|
||||||
|
// 脏标记相关事件
|
||||||
|
DIRTY_MARK_ADDED = 'dirty:mark:added',
|
||||||
|
DIRTY_BATCH_PROCESSED = 'dirty:batch:processed',
|
||||||
|
|
||||||
|
// 错误和警告事件
|
||||||
|
ERROR_OCCURRED = 'error:occurred',
|
||||||
|
WARNING_ISSUED = 'warning:issued',
|
||||||
|
|
||||||
|
// 生命周期事件
|
||||||
|
FRAMEWORK_INITIALIZED = 'framework:initialized',
|
||||||
|
FRAMEWORK_SHUTDOWN = 'framework:shutdown',
|
||||||
|
|
||||||
|
// 调试相关事件
|
||||||
|
DEBUG_INFO = 'debug:info',
|
||||||
|
DEBUG_STATS_UPDATED = 'debug:stats:updated'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件优先级枚举
|
||||||
|
* 定义事件处理的优先级级别
|
||||||
|
*/
|
||||||
|
export enum EventPriority {
|
||||||
|
LOWEST = 0,
|
||||||
|
LOW = 25,
|
||||||
|
NORMAL = 50,
|
||||||
|
HIGH = 75,
|
||||||
|
HIGHEST = 100,
|
||||||
|
CRITICAL = 200
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预定义的事件类型常量
|
||||||
|
* 提供类型安全的事件类型字符串
|
||||||
|
*/
|
||||||
|
export const EVENT_TYPES = {
|
||||||
|
// 核心事件
|
||||||
|
CORE: {
|
||||||
|
SCENE_CHANGED: 'core:scene:changed',
|
||||||
|
FRAME_UPDATED: 'core:frame:updated',
|
||||||
|
RENDER_CHANGED: 'core:render:changed'
|
||||||
|
},
|
||||||
|
|
||||||
|
// 实体事件
|
||||||
|
ENTITY: {
|
||||||
|
CREATED: ECSEventType.ENTITY_CREATED,
|
||||||
|
DESTROYED: ECSEventType.ENTITY_DESTROYED,
|
||||||
|
ENABLED: ECSEventType.ENTITY_ENABLED,
|
||||||
|
DISABLED: ECSEventType.ENTITY_DISABLED,
|
||||||
|
TAG_ADDED: ECSEventType.ENTITY_TAG_ADDED,
|
||||||
|
TAG_REMOVED: ECSEventType.ENTITY_TAG_REMOVED,
|
||||||
|
NAME_CHANGED: ECSEventType.ENTITY_NAME_CHANGED
|
||||||
|
},
|
||||||
|
|
||||||
|
// 组件事件
|
||||||
|
COMPONENT: {
|
||||||
|
ADDED: ECSEventType.COMPONENT_ADDED,
|
||||||
|
REMOVED: ECSEventType.COMPONENT_REMOVED,
|
||||||
|
MODIFIED: ECSEventType.COMPONENT_MODIFIED,
|
||||||
|
ENABLED: ECSEventType.COMPONENT_ENABLED,
|
||||||
|
DISABLED: ECSEventType.COMPONENT_DISABLED
|
||||||
|
},
|
||||||
|
|
||||||
|
// 系统事件
|
||||||
|
SYSTEM: {
|
||||||
|
ADDED: ECSEventType.SYSTEM_ADDED,
|
||||||
|
REMOVED: ECSEventType.SYSTEM_REMOVED,
|
||||||
|
ENABLED: ECSEventType.SYSTEM_ENABLED,
|
||||||
|
DISABLED: ECSEventType.SYSTEM_DISABLED,
|
||||||
|
PROCESSING_START: ECSEventType.SYSTEM_PROCESSING_START,
|
||||||
|
PROCESSING_END: ECSEventType.SYSTEM_PROCESSING_END,
|
||||||
|
ERROR: ECSEventType.SYSTEM_ERROR
|
||||||
|
},
|
||||||
|
|
||||||
|
// 性能事件
|
||||||
|
PERFORMANCE: {
|
||||||
|
WARNING: ECSEventType.PERFORMANCE_WARNING,
|
||||||
|
CRITICAL: ECSEventType.PERFORMANCE_CRITICAL,
|
||||||
|
MEMORY_HIGH: ECSEventType.MEMORY_USAGE_HIGH,
|
||||||
|
FRAME_DROP: ECSEventType.FRAME_RATE_DROP
|
||||||
|
}
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件类型验证器
|
||||||
|
* 验证事件类型是否有效
|
||||||
|
*/
|
||||||
|
export class EventTypeValidator {
|
||||||
|
private static validTypes = new Set([
|
||||||
|
...Object.values(CoreEvents).map(e => e.toString()),
|
||||||
|
...Object.values(ECSEventType),
|
||||||
|
...Object.values(EVENT_TYPES.CORE),
|
||||||
|
...Object.values(EVENT_TYPES.ENTITY),
|
||||||
|
...Object.values(EVENT_TYPES.COMPONENT),
|
||||||
|
...Object.values(EVENT_TYPES.SYSTEM),
|
||||||
|
...Object.values(EVENT_TYPES.PERFORMANCE)
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证事件类型是否有效
|
||||||
|
* @param eventType 事件类型
|
||||||
|
* @returns 是否有效
|
||||||
|
*/
|
||||||
|
public static isValid(eventType: string): boolean {
|
||||||
|
return this.validTypes.has(eventType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有有效的事件类型
|
||||||
|
* @returns 事件类型数组
|
||||||
|
*/
|
||||||
|
public static getAllValidTypes(): string[] {
|
||||||
|
return Array.from(this.validTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加自定义事件类型
|
||||||
|
* @param eventType 事件类型
|
||||||
|
*/
|
||||||
|
public static addCustomType(eventType: string): void {
|
||||||
|
this.validTypes.add(eventType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除自定义事件类型
|
||||||
|
* @param eventType 事件类型
|
||||||
|
*/
|
||||||
|
public static removeCustomType(eventType: string): void {
|
||||||
|
this.validTypes.delete(eventType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { Component } from './Component';
|
import { Component } from './Component';
|
||||||
import { ComponentRegistry, ComponentType } from './Core/ComponentStorage';
|
import { ComponentRegistry, ComponentType } from './Core/ComponentStorage';
|
||||||
|
import { EventBus } from './Core/EventBus';
|
||||||
|
import { ECSEventType } from './CoreEvents';
|
||||||
|
import { IComponentEventData } from '../Types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体比较器
|
* 实体比较器
|
||||||
@@ -192,6 +195,12 @@ export class Entity {
|
|||||||
*/
|
*/
|
||||||
public static entityComparer: EntityComparer = new EntityComparer();
|
public static entityComparer: EntityComparer = new EntityComparer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局事件总线实例
|
||||||
|
* 用于发射组件相关事件
|
||||||
|
*/
|
||||||
|
public static eventBus: EventBus | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体名称
|
* 实体名称
|
||||||
*
|
*
|
||||||
@@ -538,6 +547,19 @@ export class Entity {
|
|||||||
// 调用组件的生命周期方法
|
// 调用组件的生命周期方法
|
||||||
component.onAddedToEntity();
|
component.onAddedToEntity();
|
||||||
|
|
||||||
|
// 发射组件添加事件
|
||||||
|
if (Entity.eventBus) {
|
||||||
|
Entity.eventBus.emitComponentAdded({
|
||||||
|
timestamp: Date.now(),
|
||||||
|
source: 'Entity',
|
||||||
|
entityId: this.id,
|
||||||
|
entityName: this.name,
|
||||||
|
entityTag: this.tag?.toString(),
|
||||||
|
componentType: componentType.name,
|
||||||
|
component: component
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 通知场景实体已改变
|
// 通知场景实体已改变
|
||||||
if (this.scene && this.scene.entityProcessors) {
|
if (this.scene && this.scene.entityProcessors) {
|
||||||
for (const processor of this.scene.entityProcessors.processors) {
|
for (const processor of this.scene.entityProcessors.processors) {
|
||||||
@@ -744,6 +766,19 @@ export class Entity {
|
|||||||
// 调用组件的生命周期方法
|
// 调用组件的生命周期方法
|
||||||
component.onRemovedFromEntity();
|
component.onRemovedFromEntity();
|
||||||
|
|
||||||
|
// 发射组件移除事件
|
||||||
|
if (Entity.eventBus) {
|
||||||
|
Entity.eventBus.emitComponentRemoved({
|
||||||
|
timestamp: Date.now(),
|
||||||
|
source: 'Entity',
|
||||||
|
entityId: this.id,
|
||||||
|
entityName: this.name,
|
||||||
|
entityTag: this.tag?.toString(),
|
||||||
|
componentType: componentType.name,
|
||||||
|
component: component
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 清除组件的实体引用
|
// 清除组件的实体引用
|
||||||
component.entity = null as any;
|
component.entity = null as any;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { EntitySystem } from './Systems/EntitySystem';
|
|||||||
import { ComponentStorageManager } from './Core/ComponentStorage';
|
import { ComponentStorageManager } from './Core/ComponentStorage';
|
||||||
import { QuerySystem } from './Core/QuerySystem';
|
import { QuerySystem } from './Core/QuerySystem';
|
||||||
import { TypeSafeEventSystem, GlobalEventSystem } from './Core/EventSystem';
|
import { TypeSafeEventSystem, GlobalEventSystem } from './Core/EventSystem';
|
||||||
|
import type { IScene } from '../Types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 游戏场景类
|
* 游戏场景类
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Core } from '../../Core';
|
|||||||
import { Matcher } from '../Utils/Matcher';
|
import { Matcher } from '../Utils/Matcher';
|
||||||
import { PerformanceMonitor } from '../../Utils/PerformanceMonitor';
|
import { PerformanceMonitor } from '../../Utils/PerformanceMonitor';
|
||||||
import type { Scene } from '../Scene';
|
import type { Scene } from '../Scene';
|
||||||
|
import type { ISystemBase } from '../../Types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体系统的基类
|
* 实体系统的基类
|
||||||
@@ -27,7 +28,7 @@ import type { Scene } from '../Scene';
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export abstract class EntitySystem {
|
export abstract class EntitySystem implements ISystemBase {
|
||||||
private _entities: Entity[] = [];
|
private _entities: Entity[] = [];
|
||||||
private _updateOrder: number = 0;
|
private _updateOrder: number = 0;
|
||||||
private _enabled: boolean = true;
|
private _enabled: boolean = true;
|
||||||
|
|||||||
@@ -21,4 +21,557 @@ export enum ComponentTransform {
|
|||||||
Position = 1,
|
Position = 1,
|
||||||
Scale = 2,
|
Scale = 2,
|
||||||
Rotation = 4
|
Rotation = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组件接口
|
||||||
|
*
|
||||||
|
* 定义组件的基本契约,所有组件都应该实现此接口
|
||||||
|
*/
|
||||||
|
export interface IComponent {
|
||||||
|
/** 组件唯一标识符 */
|
||||||
|
readonly id: number;
|
||||||
|
/** 组件所属的实体ID */
|
||||||
|
entityId?: string | number;
|
||||||
|
/** 组件启用状态 */
|
||||||
|
enabled: boolean;
|
||||||
|
/** 更新顺序 */
|
||||||
|
updateOrder: number;
|
||||||
|
|
||||||
|
/** 组件添加到实体时的回调 */
|
||||||
|
onAddedToEntity(): void;
|
||||||
|
/** 组件从实体移除时的回调 */
|
||||||
|
onRemovedFromEntity(): void;
|
||||||
|
/** 组件启用时的回调 */
|
||||||
|
onEnabled(): void;
|
||||||
|
/** 组件禁用时的回调 */
|
||||||
|
onDisabled(): void;
|
||||||
|
/** 更新组件 */
|
||||||
|
update(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体接口
|
||||||
|
*
|
||||||
|
* 定义实体的基本契约,所有实体都应该实现此接口
|
||||||
|
*/
|
||||||
|
export interface IEntity {
|
||||||
|
/** 实体唯一标识符 */
|
||||||
|
readonly id: string | number;
|
||||||
|
/** 实体名称 */
|
||||||
|
name: string;
|
||||||
|
/** 实体激活状态 */
|
||||||
|
active: boolean;
|
||||||
|
/** 实体启用状态 */
|
||||||
|
enabled: boolean;
|
||||||
|
/** 实体是否已销毁 */
|
||||||
|
readonly isDestroyed: boolean;
|
||||||
|
/** 更新顺序 */
|
||||||
|
updateOrder: number;
|
||||||
|
/** 实体标签 */
|
||||||
|
tag: number;
|
||||||
|
|
||||||
|
/** 添加组件 */
|
||||||
|
addComponent<T extends IComponent>(component: T): T;
|
||||||
|
/** 创建并添加组件 */
|
||||||
|
createComponent<T extends IComponent>(componentType: ComponentType<T>, ...args: any[]): T;
|
||||||
|
/** 获取组件 */
|
||||||
|
getComponent<T extends IComponent>(type: ComponentType<T>): T | null;
|
||||||
|
/** 获取或创建组件 */
|
||||||
|
getOrCreateComponent<T extends IComponent>(type: ComponentType<T>, ...args: any[]): T;
|
||||||
|
/** 移除组件 */
|
||||||
|
removeComponent(component: IComponent): void;
|
||||||
|
/** 通过类型移除组件 */
|
||||||
|
removeComponentByType<T extends IComponent>(type: ComponentType<T>): T | null;
|
||||||
|
/** 检查是否有组件 */
|
||||||
|
hasComponent<T extends IComponent>(type: ComponentType<T>): boolean;
|
||||||
|
/** 获取所有指定类型的组件 */
|
||||||
|
getComponents<T extends IComponent>(type: ComponentType<T>): T[];
|
||||||
|
|
||||||
|
/** 添加子实体 */
|
||||||
|
addChild(child: IEntity): IEntity;
|
||||||
|
/** 移除子实体 */
|
||||||
|
removeChild(child: IEntity): boolean;
|
||||||
|
/** 查找子实体 */
|
||||||
|
findChild(name: string, recursive?: boolean): IEntity | null;
|
||||||
|
|
||||||
|
/** 更新实体 */
|
||||||
|
update(): void;
|
||||||
|
/** 销毁实体 */
|
||||||
|
destroy(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体基础接口(向后兼容)
|
||||||
|
*
|
||||||
|
* 为现有的Entity类提供更灵活的类型定义
|
||||||
|
*/
|
||||||
|
export interface IEntityBase {
|
||||||
|
/** 实体唯一标识符 */
|
||||||
|
readonly id: string | number;
|
||||||
|
/** 实体名称 */
|
||||||
|
name: string;
|
||||||
|
/** 实体激活状态 */
|
||||||
|
active: boolean;
|
||||||
|
/** 实体启用状态 */
|
||||||
|
enabled: boolean;
|
||||||
|
/** 实体是否已销毁 */
|
||||||
|
readonly isDestroyed: boolean;
|
||||||
|
/** 更新顺序 */
|
||||||
|
updateOrder: number;
|
||||||
|
/** 实体标签 */
|
||||||
|
tag: number;
|
||||||
|
|
||||||
|
/** 添加组件(泛型版本) */
|
||||||
|
addComponent<T>(component: T): T;
|
||||||
|
/** 获取组件(泛型版本) */
|
||||||
|
getComponent<T>(type: ComponentClass<T>): T | null;
|
||||||
|
/** 检查是否有组件(泛型版本) */
|
||||||
|
hasComponent<T>(type: ComponentClass<T>): boolean;
|
||||||
|
|
||||||
|
/** 添加子实体 */
|
||||||
|
addChild(child: any): any;
|
||||||
|
/** 移除子实体 */
|
||||||
|
removeChild(child: any): boolean;
|
||||||
|
/** 查找子实体 */
|
||||||
|
findChild(name: string, recursive?: boolean): any;
|
||||||
|
|
||||||
|
/** 更新实体 */
|
||||||
|
update(): void;
|
||||||
|
/** 销毁实体 */
|
||||||
|
destroy(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统接口
|
||||||
|
*
|
||||||
|
* 定义系统的基本契约,所有系统都应该实现此接口
|
||||||
|
*/
|
||||||
|
export interface ISystem {
|
||||||
|
/** 系统名称 */
|
||||||
|
readonly systemName: string;
|
||||||
|
/** 系统处理的实体列表 */
|
||||||
|
readonly entities: readonly IEntity[];
|
||||||
|
/** 更新顺序/优先级 */
|
||||||
|
updateOrder: number;
|
||||||
|
/** 系统启用状态 */
|
||||||
|
enabled: boolean;
|
||||||
|
|
||||||
|
/** 系统初始化 */
|
||||||
|
initialize(): void;
|
||||||
|
/** 更新系统(主要处理阶段) */
|
||||||
|
update(): void;
|
||||||
|
/** 延迟更新系统 */
|
||||||
|
lateUpdate?(): void;
|
||||||
|
|
||||||
|
/** 当实体添加到系统时的回调 */
|
||||||
|
onEntityAdded?(entity: IEntity): void;
|
||||||
|
/** 当实体从系统移除时的回调 */
|
||||||
|
onEntityRemoved?(entity: IEntity): void;
|
||||||
|
/** 当实体组件发生变化时的回调 */
|
||||||
|
onEntityChanged?(entity: IEntity): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统基础接口(向后兼容)
|
||||||
|
*
|
||||||
|
* 为现有的EntitySystem类提供更灵活的类型定义
|
||||||
|
*/
|
||||||
|
export interface ISystemBase {
|
||||||
|
/** 系统名称 */
|
||||||
|
readonly systemName: string;
|
||||||
|
/** 系统处理的实体列表(泛型版本) */
|
||||||
|
readonly entities: readonly any[];
|
||||||
|
/** 更新顺序/优先级 */
|
||||||
|
updateOrder: number;
|
||||||
|
/** 系统启用状态 */
|
||||||
|
enabled: boolean;
|
||||||
|
|
||||||
|
/** 系统初始化 */
|
||||||
|
initialize(): void;
|
||||||
|
/** 更新系统(主要处理阶段) */
|
||||||
|
update(): void;
|
||||||
|
/** 延迟更新系统 */
|
||||||
|
lateUpdate?(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 场景接口
|
||||||
|
*
|
||||||
|
* 定义场景的基本契约
|
||||||
|
*/
|
||||||
|
export interface IScene {
|
||||||
|
/** 场景名称 */
|
||||||
|
name: string;
|
||||||
|
/** 场景中的实体列表 */
|
||||||
|
readonly entities: readonly IEntity[];
|
||||||
|
/** 场景中的系统列表 */
|
||||||
|
readonly systems: readonly ISystem[];
|
||||||
|
|
||||||
|
/** 创建实体 */
|
||||||
|
createEntity(name: string): IEntity;
|
||||||
|
/** 添加实体到场景 */
|
||||||
|
addEntity(entity: IEntity): void;
|
||||||
|
/** 从场景移除实体 */
|
||||||
|
removeEntity(entity: IEntity): void;
|
||||||
|
/** 查找实体 */
|
||||||
|
findEntity(name: string): IEntity | null;
|
||||||
|
|
||||||
|
/** 添加系统到场景 */
|
||||||
|
addSystem<T extends ISystem>(system: T): T;
|
||||||
|
/** 从场景移除系统 */
|
||||||
|
removeSystem(system: ISystem): void;
|
||||||
|
/** 获取系统 */
|
||||||
|
getSystem<T extends ISystem>(systemType: new (...args: any[]) => T): T | null;
|
||||||
|
|
||||||
|
/** 更新场景 */
|
||||||
|
update(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组件类型定义
|
||||||
|
*
|
||||||
|
* 用于类型安全的组件操作
|
||||||
|
*/
|
||||||
|
export type ComponentType<T extends IComponent = IComponent> = new (...args: any[]) => T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始组件类型(向后兼容)
|
||||||
|
*
|
||||||
|
* 用于与现有Component类的兼容
|
||||||
|
*/
|
||||||
|
export type ComponentClass<T = any> = new (...args: any[]) => T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体查询匹配器接口
|
||||||
|
*
|
||||||
|
* 用于查询符合特定条件的实体
|
||||||
|
*/
|
||||||
|
export interface IMatcher {
|
||||||
|
/** 必须包含的组件类型 */
|
||||||
|
all(...componentTypes: ComponentType[]): IMatcher;
|
||||||
|
/** 至少包含其中一个组件类型 */
|
||||||
|
any(...componentTypes: ComponentType[]): IMatcher;
|
||||||
|
/** 不能包含的组件类型 */
|
||||||
|
exclude(...componentTypes: ComponentType[]): IMatcher;
|
||||||
|
/** 检查实体是否匹配 */
|
||||||
|
isInterestedEntity(entity: IEntity): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性能监控接口
|
||||||
|
*/
|
||||||
|
export interface IPerformanceData {
|
||||||
|
/** 执行时间(毫秒) */
|
||||||
|
executionTime: number;
|
||||||
|
/** 调用次数 */
|
||||||
|
callCount: number;
|
||||||
|
/** 平均执行时间 */
|
||||||
|
averageTime: number;
|
||||||
|
/** 最大执行时间 */
|
||||||
|
maxTime: number;
|
||||||
|
/** 最小执行时间 */
|
||||||
|
minTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期管理接口
|
||||||
|
*/
|
||||||
|
export interface ILifecycle {
|
||||||
|
/** 初始化 */
|
||||||
|
initialize?(): void;
|
||||||
|
/** 启动 */
|
||||||
|
start?(): void;
|
||||||
|
/** 更新 */
|
||||||
|
update?(): void;
|
||||||
|
/** 延迟更新 */
|
||||||
|
lateUpdate?(): void;
|
||||||
|
/** 停止 */
|
||||||
|
stop?(): void;
|
||||||
|
/** 销毁 */
|
||||||
|
destroy?(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体管理器接口
|
||||||
|
*
|
||||||
|
* 提供统一的实体管理和查询机制,支持高效的实体操作
|
||||||
|
*/
|
||||||
|
export interface IEntityManager {
|
||||||
|
/** 所有实体数量 */
|
||||||
|
readonly entityCount: number;
|
||||||
|
/** 激活的实体数量 */
|
||||||
|
readonly activeEntityCount: number;
|
||||||
|
|
||||||
|
/** 创建实体 */
|
||||||
|
createEntity(name?: string): IEntity;
|
||||||
|
/** 销毁实体 */
|
||||||
|
destroyEntity(entity: IEntity | string | number): boolean;
|
||||||
|
/** 批量销毁实体 */
|
||||||
|
destroyEntities(entities: (IEntity | string | number)[]): number;
|
||||||
|
/** 销毁所有实体 */
|
||||||
|
destroyAllEntities(): number;
|
||||||
|
|
||||||
|
/** 根据ID获取实体 */
|
||||||
|
getEntity(id: string | number): IEntity | null;
|
||||||
|
/** 根据名称获取实体 */
|
||||||
|
getEntityByName(name: string): IEntity | null;
|
||||||
|
/** 根据名称获取所有实体 */
|
||||||
|
getEntitiesByName(name: string): IEntity[];
|
||||||
|
/** 根据标签获取实体 */
|
||||||
|
getEntitiesByTag(tag: number): IEntity[];
|
||||||
|
/** 获取所有实体 */
|
||||||
|
getAllEntities(): IEntity[];
|
||||||
|
/** 获取所有激活的实体 */
|
||||||
|
getActiveEntities(): IEntity[];
|
||||||
|
|
||||||
|
/** 获取拥有指定组件的实体 */
|
||||||
|
getEntitiesWithComponent<T extends IComponent>(componentType: ComponentType<T>): IEntity[];
|
||||||
|
/** 获取拥有指定组件的实体及其组件 */
|
||||||
|
getEntitiesWithComponentData<T extends IComponent>(componentType: ComponentType<T>): Array<{entity: IEntity, component: T}>;
|
||||||
|
/** 获取拥有所有指定组件的实体 */
|
||||||
|
getEntitiesWithComponents(...componentTypes: ComponentType[]): IEntity[];
|
||||||
|
/** 获取拥有任一指定组件的实体 */
|
||||||
|
getEntitiesWithAnyComponent(...componentTypes: ComponentType[]): IEntity[];
|
||||||
|
/** 获取不包含指定组件的实体 */
|
||||||
|
getEntitiesWithoutComponent<T extends IComponent>(componentType: ComponentType<T>): IEntity[];
|
||||||
|
|
||||||
|
/** 对所有实体执行操作 */
|
||||||
|
forEachEntity(action: (entity: IEntity) => void): void;
|
||||||
|
/** 对符合条件的实体执行操作 */
|
||||||
|
forEachEntityWhere(predicate: (entity: IEntity) => boolean, action: (entity: IEntity) => void): void;
|
||||||
|
/** 对拥有指定组件的实体执行操作 */
|
||||||
|
forEachEntityWithComponent<T extends IComponent>(
|
||||||
|
componentType: ComponentType<T>,
|
||||||
|
action: (entity: IEntity, component: T) => void
|
||||||
|
): void;
|
||||||
|
|
||||||
|
/** 查找第一个符合条件的实体 */
|
||||||
|
findEntity(predicate: (entity: IEntity) => boolean): IEntity | null;
|
||||||
|
/** 查找所有符合条件的实体 */
|
||||||
|
findEntities(predicate: (entity: IEntity) => boolean): IEntity[];
|
||||||
|
|
||||||
|
/** 获取统计信息 */
|
||||||
|
getStatistics(): {
|
||||||
|
totalEntities: number;
|
||||||
|
activeEntities: number;
|
||||||
|
destroyedEntities: number;
|
||||||
|
entitiesByTag: Map<number, number>;
|
||||||
|
componentsCount: Map<string, number>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 清理已销毁的实体 */
|
||||||
|
cleanup(): number;
|
||||||
|
/** 压缩存储空间 */
|
||||||
|
compact(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体查询构建器接口
|
||||||
|
*
|
||||||
|
* 提供流式API构建复杂的实体查询条件
|
||||||
|
*/
|
||||||
|
export interface IEntityQueryBuilder {
|
||||||
|
/** 必须包含所有指定组件 */
|
||||||
|
withAll(...componentTypes: ComponentType[]): IEntityQueryBuilder;
|
||||||
|
/** 必须包含任一指定组件 */
|
||||||
|
withAny(...componentTypes: ComponentType[]): IEntityQueryBuilder;
|
||||||
|
/** 必须不包含指定组件 */
|
||||||
|
without(...componentTypes: ComponentType[]): IEntityQueryBuilder;
|
||||||
|
/** 必须包含指定标签 */
|
||||||
|
withTag(tag: number): IEntityQueryBuilder;
|
||||||
|
/** 必须不包含指定标签 */
|
||||||
|
withoutTag(tag: number): IEntityQueryBuilder;
|
||||||
|
/** 必须处于激活状态 */
|
||||||
|
active(): IEntityQueryBuilder;
|
||||||
|
/** 必须处于启用状态 */
|
||||||
|
enabled(): IEntityQueryBuilder;
|
||||||
|
/** 自定义过滤条件 */
|
||||||
|
where(predicate: (entity: IEntity) => boolean): IEntityQueryBuilder;
|
||||||
|
|
||||||
|
/** 执行查询,返回所有匹配的实体 */
|
||||||
|
execute(): IEntity[];
|
||||||
|
/** 执行查询,返回第一个匹配的实体 */
|
||||||
|
first(): IEntity | null;
|
||||||
|
/** 执行查询,返回匹配实体的数量 */
|
||||||
|
count(): number;
|
||||||
|
/** 对查询结果执行操作 */
|
||||||
|
forEach(action: (entity: IEntity) => void): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件总线接口
|
||||||
|
* 提供类型安全的事件发布订阅机制
|
||||||
|
*/
|
||||||
|
export interface IEventBus {
|
||||||
|
/**
|
||||||
|
* 发射事件
|
||||||
|
* @param eventType 事件类型
|
||||||
|
* @param data 事件数据
|
||||||
|
*/
|
||||||
|
emit<T>(eventType: string, data: T): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步发射事件
|
||||||
|
* @param eventType 事件类型
|
||||||
|
* @param data 事件数据
|
||||||
|
*/
|
||||||
|
emitAsync<T>(eventType: string, data: T): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听事件
|
||||||
|
* @param eventType 事件类型
|
||||||
|
* @param handler 事件处理器
|
||||||
|
* @param config 监听器配置
|
||||||
|
* @returns 监听器ID
|
||||||
|
*/
|
||||||
|
on<T>(eventType: string, handler: (data: T) => void, config?: IEventListenerConfig): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听事件(一次性)
|
||||||
|
* @param eventType 事件类型
|
||||||
|
* @param handler 事件处理器
|
||||||
|
* @param config 监听器配置
|
||||||
|
* @returns 监听器ID
|
||||||
|
*/
|
||||||
|
once<T>(eventType: string, handler: (data: T) => void, config?: IEventListenerConfig): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步监听事件
|
||||||
|
* @param eventType 事件类型
|
||||||
|
* @param handler 异步事件处理器
|
||||||
|
* @param config 监听器配置
|
||||||
|
* @returns 监听器ID
|
||||||
|
*/
|
||||||
|
onAsync<T>(eventType: string, handler: (data: T) => Promise<void>, config?: IEventListenerConfig): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除事件监听器
|
||||||
|
* @param eventType 事件类型
|
||||||
|
* @param listenerId 监听器ID
|
||||||
|
*/
|
||||||
|
off(eventType: string, listenerId: string): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除指定事件类型的所有监听器
|
||||||
|
* @param eventType 事件类型
|
||||||
|
*/
|
||||||
|
offAll(eventType: string): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否有指定事件的监听器
|
||||||
|
* @param eventType 事件类型
|
||||||
|
*/
|
||||||
|
hasListeners(eventType: string): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取事件统计信息
|
||||||
|
* @param eventType 事件类型(可选)
|
||||||
|
*/
|
||||||
|
getStats(eventType?: string): IEventStats | Map<string, IEventStats>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空所有监听器
|
||||||
|
*/
|
||||||
|
clear(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件监听器配置接口
|
||||||
|
*/
|
||||||
|
export interface IEventListenerConfig {
|
||||||
|
/** 是否只执行一次 */
|
||||||
|
once?: boolean;
|
||||||
|
/** 优先级(数字越大优先级越高) */
|
||||||
|
priority?: number;
|
||||||
|
/** 是否异步执行 */
|
||||||
|
async?: boolean;
|
||||||
|
/** 执行上下文 */
|
||||||
|
context?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件统计信息接口
|
||||||
|
*/
|
||||||
|
export interface IEventStats {
|
||||||
|
/** 事件类型 */
|
||||||
|
eventType: string;
|
||||||
|
/** 监听器数量 */
|
||||||
|
listenerCount: number;
|
||||||
|
/** 触发次数 */
|
||||||
|
triggerCount: number;
|
||||||
|
/** 总执行时间(毫秒) */
|
||||||
|
totalExecutionTime: number;
|
||||||
|
/** 平均执行时间(毫秒) */
|
||||||
|
averageExecutionTime: number;
|
||||||
|
/** 最后触发时间 */
|
||||||
|
lastTriggerTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件数据基类接口
|
||||||
|
*/
|
||||||
|
export interface IEventData {
|
||||||
|
/** 事件时间戳 */
|
||||||
|
timestamp: number;
|
||||||
|
/** 事件来源 */
|
||||||
|
source?: string;
|
||||||
|
/** 事件ID */
|
||||||
|
eventId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实体事件数据接口
|
||||||
|
*/
|
||||||
|
export interface IEntityEventData extends IEventData {
|
||||||
|
/** 实体ID */
|
||||||
|
entityId: number;
|
||||||
|
/** 实体名称 */
|
||||||
|
entityName?: string;
|
||||||
|
/** 实体标签 */
|
||||||
|
entityTag?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组件事件数据接口
|
||||||
|
*/
|
||||||
|
export interface IComponentEventData extends IEntityEventData {
|
||||||
|
/** 组件类型名称 */
|
||||||
|
componentType: string;
|
||||||
|
/** 组件实例 */
|
||||||
|
component?: IComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统事件数据接口
|
||||||
|
*/
|
||||||
|
export interface ISystemEventData extends IEventData {
|
||||||
|
/** 系统名称 */
|
||||||
|
systemName: string;
|
||||||
|
/** 系统类型 */
|
||||||
|
systemType: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 场景事件数据接口
|
||||||
|
*/
|
||||||
|
export interface ISceneEventData extends IEventData {
|
||||||
|
/** 场景名称 */
|
||||||
|
sceneName: string;
|
||||||
|
/** 前一个场景名称 */
|
||||||
|
previousSceneName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性能事件数据接口
|
||||||
|
*/
|
||||||
|
export interface IPerformanceEventData extends IEventData {
|
||||||
|
/** 操作类型 */
|
||||||
|
operation: string;
|
||||||
|
/** 执行时间(毫秒) */
|
||||||
|
executionTime: number;
|
||||||
|
/** 内存使用量 */
|
||||||
|
memoryUsage?: number;
|
||||||
|
/** 额外数据 */
|
||||||
|
metadata?: Record<string, any>;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user