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生成器
|
||||
*
|
||||
|
||||
@@ -5,6 +5,9 @@ import { ecsCore } from '../../Utils/WasmCore';
|
||||
import { ComponentPoolManager } from './ComponentPool';
|
||||
import { BitMaskOptimizer } from './BitMaskOptimizer';
|
||||
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 entityIndex: EntityIndex;
|
||||
private indexDirty = true;
|
||||
|
||||
|
||||
// 查询缓存系统
|
||||
private queryCache = new Map<string, QueryCacheEntry>();
|
||||
private cacheMaxSize = 1000;
|
||||
private cacheTimeout = 5000; // 5秒缓存过期
|
||||
|
||||
|
||||
// 优化组件
|
||||
private componentPoolManager: ComponentPoolManager;
|
||||
private bitMaskOptimizer: BitMaskOptimizer;
|
||||
private indexUpdateBatcher: IndexUpdateBatcher;
|
||||
|
||||
|
||||
// 新增性能优化系统
|
||||
private componentIndexManager: ComponentIndexManager;
|
||||
private archetypeSystem: ArchetypeSystem;
|
||||
private dirtyTrackingSystem: DirtyTrackingSystem;
|
||||
|
||||
// 性能统计
|
||||
private queryStats = {
|
||||
totalQueries: 0,
|
||||
cacheHits: 0,
|
||||
indexHits: 0,
|
||||
linearScans: 0
|
||||
linearScans: 0,
|
||||
archetypeHits: 0,
|
||||
dirtyChecks: 0
|
||||
};
|
||||
|
||||
constructor() {
|
||||
@@ -110,32 +120,37 @@ export class QuerySystem {
|
||||
byTag: new Map(),
|
||||
byName: new Map()
|
||||
};
|
||||
|
||||
|
||||
// 初始化优化组件
|
||||
this.componentPoolManager = ComponentPoolManager.getInstance();
|
||||
this.bitMaskOptimizer = BitMaskOptimizer.getInstance();
|
||||
this.indexUpdateBatcher = new IndexUpdateBatcher();
|
||||
|
||||
|
||||
// 初始化新的性能优化系统
|
||||
this.componentIndexManager = new ComponentIndexManager(IndexType.HASH);
|
||||
this.archetypeSystem = new ArchetypeSystem();
|
||||
this.dirtyTrackingSystem = new DirtyTrackingSystem();
|
||||
|
||||
// 设置索引更新批处理器的回调
|
||||
this.indexUpdateBatcher.onBatchAdd = (entities) => {
|
||||
for (const entity of entities) {
|
||||
this.addEntityToIndexes(entity);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.indexUpdateBatcher.onBatchRemove = (entities) => {
|
||||
for (const entity of entities) {
|
||||
this.removeEntityFromIndexes(entity);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.indexUpdateBatcher.onBatchUpdate = (updates) => {
|
||||
for (const update of updates) {
|
||||
this.removeEntityFromIndexes(update.entity);
|
||||
this.addEntityToIndexes(update.entity);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.initializeWasm();
|
||||
}
|
||||
|
||||
@@ -149,7 +164,7 @@ export class QuerySystem {
|
||||
try {
|
||||
const wasmLoaded = await ecsCore.initialize();
|
||||
this.wasmAvailable = wasmLoaded && ecsCore.isUsingWasm();
|
||||
|
||||
|
||||
if (this.wasmAvailable) {
|
||||
console.log('QuerySystem: WebAssembly计算加速已启用');
|
||||
} else {
|
||||
@@ -188,7 +203,11 @@ export class QuerySystem {
|
||||
if (!this.entities.includes(entity)) {
|
||||
this.entities.push(entity);
|
||||
this.addEntityToIndexes(entity);
|
||||
|
||||
|
||||
this.componentIndexManager.addEntity(entity);
|
||||
this.archetypeSystem.addEntity(entity);
|
||||
this.dirtyTrackingSystem.markDirty(entity, DirtyFlag.COMPONENT_ADDED);
|
||||
|
||||
// 只有在非延迟模式下才立即清理缓存
|
||||
if (!deferCacheClear) {
|
||||
this.clearQueryCache();
|
||||
@@ -206,11 +225,11 @@ export class QuerySystem {
|
||||
*/
|
||||
public addEntities(entities: Entity[]): void {
|
||||
if (entities.length === 0) return;
|
||||
|
||||
|
||||
// 使用Set来快速检查重复
|
||||
const existingIds = new Set(this.entities.map(e => e.id));
|
||||
let addedCount = 0;
|
||||
|
||||
|
||||
for (const entity of entities) {
|
||||
if (!existingIds.has(entity.id)) {
|
||||
this.entities.push(entity);
|
||||
@@ -219,7 +238,7 @@ export class QuerySystem {
|
||||
addedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 只在有实体被添加时才清理缓存
|
||||
if (addedCount > 0) {
|
||||
this.clearQueryCache();
|
||||
@@ -236,17 +255,17 @@ export class QuerySystem {
|
||||
*/
|
||||
public addEntitiesUnchecked(entities: Entity[]): void {
|
||||
if (entities.length === 0) return;
|
||||
|
||||
|
||||
// 避免调用栈溢出,分批添加
|
||||
for (const entity of entities) {
|
||||
this.entities.push(entity);
|
||||
}
|
||||
|
||||
|
||||
// 批量更新索引
|
||||
for (const entity of entities) {
|
||||
this.addEntityToIndexes(entity);
|
||||
}
|
||||
|
||||
|
||||
// 清理缓存
|
||||
this.clearQueryCache();
|
||||
}
|
||||
@@ -263,6 +282,11 @@ export class QuerySystem {
|
||||
if (index !== -1) {
|
||||
this.entities.splice(index, 1);
|
||||
this.removeEntityFromIndexes(entity);
|
||||
|
||||
this.componentIndexManager.removeEntity(entity);
|
||||
this.archetypeSystem.removeEntity(entity);
|
||||
this.dirtyTrackingSystem.markDirty(entity, DirtyFlag.COMPONENT_REMOVED);
|
||||
|
||||
this.clearQueryCache();
|
||||
}
|
||||
}
|
||||
@@ -272,7 +296,7 @@ export class QuerySystem {
|
||||
*/
|
||||
private addEntityToIndexes(entity: Entity): void {
|
||||
const mask = entity.componentMask;
|
||||
|
||||
|
||||
// 组件掩码索引 - 优化Map操作
|
||||
let maskSet = this.entityIndex.byMask.get(mask);
|
||||
if (!maskSet) {
|
||||
@@ -280,7 +304,7 @@ export class QuerySystem {
|
||||
this.entityIndex.byMask.set(mask, maskSet);
|
||||
}
|
||||
maskSet.add(entity);
|
||||
|
||||
|
||||
// 组件类型索引 - 批量处理
|
||||
const components = entity.components;
|
||||
for (let i = 0; i < components.length; i++) {
|
||||
@@ -292,7 +316,7 @@ export class QuerySystem {
|
||||
}
|
||||
typeSet.add(entity);
|
||||
}
|
||||
|
||||
|
||||
// 标签索引 - 只在有标签时处理
|
||||
const tag = entity.tag;
|
||||
if (tag !== undefined) {
|
||||
@@ -303,7 +327,7 @@ export class QuerySystem {
|
||||
}
|
||||
tagSet.add(entity);
|
||||
}
|
||||
|
||||
|
||||
// 名称索引 - 只在有名称时处理
|
||||
const name = entity.name;
|
||||
if (name) {
|
||||
@@ -321,7 +345,7 @@ export class QuerySystem {
|
||||
*/
|
||||
private removeEntityFromIndexes(entity: Entity): void {
|
||||
const mask = entity.componentMask;
|
||||
|
||||
|
||||
// 从组件掩码索引移除
|
||||
const maskSet = this.entityIndex.byMask.get(mask);
|
||||
if (maskSet) {
|
||||
@@ -330,7 +354,7 @@ export class QuerySystem {
|
||||
this.entityIndex.byMask.delete(mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 从组件类型索引移除
|
||||
for (const component of entity.components) {
|
||||
const componentType = component.constructor as ComponentType;
|
||||
@@ -342,7 +366,7 @@ export class QuerySystem {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 从标签索引移除
|
||||
if (entity.tag !== undefined) {
|
||||
const tagSet = this.entityIndex.byTag.get(entity.tag);
|
||||
@@ -353,7 +377,7 @@ export class QuerySystem {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 从名称索引移除
|
||||
if (entity.name) {
|
||||
const nameSet = this.entityIndex.byName.get(entity.name);
|
||||
@@ -377,11 +401,11 @@ export class QuerySystem {
|
||||
this.entityIndex.byComponentType.clear();
|
||||
this.entityIndex.byTag.clear();
|
||||
this.entityIndex.byName.clear();
|
||||
|
||||
|
||||
for (const entity of this.entities) {
|
||||
this.addEntityToIndexes(entity);
|
||||
}
|
||||
|
||||
|
||||
this.indexDirty = false;
|
||||
}
|
||||
|
||||
@@ -404,10 +428,10 @@ export class QuerySystem {
|
||||
public queryAll(...componentTypes: ComponentType[]): QueryResult {
|
||||
const startTime = performance.now();
|
||||
this.queryStats.totalQueries++;
|
||||
|
||||
|
||||
// 生成缓存键
|
||||
const cacheKey = `all:${componentTypes.map(t => t.name).sort().join(',')}`;
|
||||
|
||||
|
||||
// 检查缓存
|
||||
const cached = this.getFromCache(cacheKey);
|
||||
if (cached) {
|
||||
@@ -419,21 +443,28 @@ export class QuerySystem {
|
||||
fromCache: true
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
let entities: Entity[];
|
||||
|
||||
// 单组件查询:直接使用索引
|
||||
if (componentTypes.length === 1) {
|
||||
|
||||
const archetypeResult = this.archetypeSystem.queryArchetypes(componentTypes, 'AND');
|
||||
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++;
|
||||
entities = Array.from(this.entityIndex.byComponentType.get(componentTypes[0]) || []);
|
||||
const indexResult = this.componentIndexManager.query(componentTypes[0]);
|
||||
entities = Array.from(indexResult);
|
||||
} else {
|
||||
// 多组件查询:使用高效算法
|
||||
entities = this.queryMultipleComponents(componentTypes);
|
||||
const indexResult = this.componentIndexManager.queryMultiple(componentTypes, 'AND');
|
||||
entities = Array.from(indexResult);
|
||||
}
|
||||
|
||||
|
||||
// 缓存结果
|
||||
this.addToCache(cacheKey, entities);
|
||||
|
||||
|
||||
return {
|
||||
entities,
|
||||
count: entities.length,
|
||||
@@ -455,7 +486,7 @@ export class QuerySystem {
|
||||
// 找到最小的组件集合作为起点
|
||||
let smallestSet: Set<Entity> | null = null;
|
||||
let smallestSize = Infinity;
|
||||
|
||||
|
||||
for (const componentType of componentTypes) {
|
||||
const set = this.entityIndex.byComponentType.get(componentType);
|
||||
if (!set || set.size === 0) {
|
||||
@@ -466,22 +497,22 @@ export class QuerySystem {
|
||||
smallestSet = set;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!smallestSet) {
|
||||
this.queryStats.linearScans++;
|
||||
return this.queryByLinearScan(componentTypes);
|
||||
}
|
||||
|
||||
|
||||
// 从最小集合开始,逐步过滤
|
||||
const mask = this.createComponentMask(componentTypes);
|
||||
const result: Entity[] = [];
|
||||
|
||||
|
||||
for (const entity of smallestSet) {
|
||||
if ((entity.componentMask & mask) === mask) {
|
||||
result.push(entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -496,7 +527,7 @@ export class QuerySystem {
|
||||
*/
|
||||
private queryByLinearScan(componentTypes: ComponentType[]): Entity[] {
|
||||
const mask = this.createComponentMask(componentTypes);
|
||||
return this.entities.filter(entity =>
|
||||
return this.entities.filter(entity =>
|
||||
(entity.componentMask & mask) === mask
|
||||
);
|
||||
}
|
||||
@@ -520,9 +551,9 @@ export class QuerySystem {
|
||||
public queryAny(...componentTypes: ComponentType[]): QueryResult {
|
||||
const startTime = performance.now();
|
||||
this.queryStats.totalQueries++;
|
||||
|
||||
|
||||
const cacheKey = `any:${componentTypes.map(t => t.name).sort().join(',')}`;
|
||||
|
||||
|
||||
// 检查缓存
|
||||
const cached = this.getFromCache(cacheKey);
|
||||
if (cached) {
|
||||
@@ -534,21 +565,22 @@ export class QuerySystem {
|
||||
fromCache: true
|
||||
};
|
||||
}
|
||||
|
||||
// 使用集合合并
|
||||
const entitySet = new Set<Entity>();
|
||||
for (const componentType of componentTypes) {
|
||||
const typeEntities = this.entityIndex.byComponentType.get(componentType);
|
||||
if (typeEntities) {
|
||||
for (const entity of typeEntities) {
|
||||
entitySet.add(entity);
|
||||
}
|
||||
|
||||
const archetypeResult = this.archetypeSystem.queryArchetypes(componentTypes, 'OR');
|
||||
let entities: Entity[];
|
||||
|
||||
if (archetypeResult.archetypes.length > 0) {
|
||||
this.queryStats.archetypeHits++;
|
||||
entities = [];
|
||||
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);
|
||||
|
||||
|
||||
return {
|
||||
entities,
|
||||
count: entities.length,
|
||||
@@ -576,9 +608,9 @@ export class QuerySystem {
|
||||
public queryNone(...componentTypes: ComponentType[]): QueryResult {
|
||||
const startTime = performance.now();
|
||||
this.queryStats.totalQueries++;
|
||||
|
||||
|
||||
const cacheKey = `none:${componentTypes.map(t => t.name).sort().join(',')}`;
|
||||
|
||||
|
||||
// 检查缓存
|
||||
const cached = this.getFromCache(cacheKey);
|
||||
if (cached) {
|
||||
@@ -590,14 +622,14 @@ export class QuerySystem {
|
||||
fromCache: true
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const mask = this.createComponentMask(componentTypes);
|
||||
const entities = this.entities.filter(entity =>
|
||||
const entities = this.entities.filter(entity =>
|
||||
(entity.componentMask & mask) === BigInt(0)
|
||||
);
|
||||
|
||||
|
||||
this.addToCache(cacheKey, entities);
|
||||
|
||||
|
||||
return {
|
||||
entities,
|
||||
count: entities.length,
|
||||
@@ -624,9 +656,9 @@ export class QuerySystem {
|
||||
public queryByTag(tag: number): QueryResult {
|
||||
const startTime = performance.now();
|
||||
this.queryStats.totalQueries++;
|
||||
|
||||
|
||||
const cacheKey = `tag:${tag}`;
|
||||
|
||||
|
||||
// 检查缓存
|
||||
const cached = this.getFromCache(cacheKey);
|
||||
if (cached) {
|
||||
@@ -638,14 +670,14 @@ export class QuerySystem {
|
||||
fromCache: true
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// 使用索引查询
|
||||
this.queryStats.indexHits++;
|
||||
const entities = Array.from(this.entityIndex.byTag.get(tag) || []);
|
||||
|
||||
|
||||
// 缓存结果
|
||||
this.addToCache(cacheKey, entities);
|
||||
|
||||
|
||||
return {
|
||||
entities,
|
||||
count: entities.length,
|
||||
@@ -672,9 +704,9 @@ export class QuerySystem {
|
||||
public queryByName(name: string): QueryResult {
|
||||
const startTime = performance.now();
|
||||
this.queryStats.totalQueries++;
|
||||
|
||||
|
||||
const cacheKey = `name:${name}`;
|
||||
|
||||
|
||||
// 检查缓存
|
||||
const cached = this.getFromCache(cacheKey);
|
||||
if (cached) {
|
||||
@@ -686,14 +718,14 @@ export class QuerySystem {
|
||||
fromCache: true
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// 使用索引查询
|
||||
this.queryStats.indexHits++;
|
||||
const entities = Array.from(this.entityIndex.byName.get(name) || []);
|
||||
|
||||
|
||||
// 缓存结果
|
||||
this.addToCache(cacheKey, entities);
|
||||
|
||||
|
||||
return {
|
||||
entities,
|
||||
count: entities.length,
|
||||
@@ -720,9 +752,9 @@ export class QuerySystem {
|
||||
public queryByComponent<T extends Component>(componentType: ComponentType<T>): QueryResult {
|
||||
const startTime = performance.now();
|
||||
this.queryStats.totalQueries++;
|
||||
|
||||
|
||||
const cacheKey = `component:${componentType.name}`;
|
||||
|
||||
|
||||
// 检查缓存
|
||||
const cached = this.getFromCache(cacheKey);
|
||||
if (cached) {
|
||||
@@ -734,14 +766,14 @@ export class QuerySystem {
|
||||
fromCache: true
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// 使用索引查询
|
||||
this.queryStats.indexHits++;
|
||||
const entities = Array.from(this.entityIndex.byComponentType.get(componentType) || []);
|
||||
|
||||
|
||||
// 缓存结果
|
||||
this.addToCache(cacheKey, entities);
|
||||
|
||||
|
||||
return {
|
||||
entities,
|
||||
count: entities.length,
|
||||
@@ -756,13 +788,13 @@ export class QuerySystem {
|
||||
private getFromCache(cacheKey: string): Entity[] | null {
|
||||
const entry = this.queryCache.get(cacheKey);
|
||||
if (!entry) return null;
|
||||
|
||||
|
||||
// 检查缓存是否过期
|
||||
if (Date.now() - entry.timestamp > this.cacheTimeout) {
|
||||
this.queryCache.delete(cacheKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
entry.hitCount++;
|
||||
return entry.entities;
|
||||
}
|
||||
@@ -775,7 +807,7 @@ export class QuerySystem {
|
||||
if (this.queryCache.size >= this.cacheMaxSize) {
|
||||
this.cleanupCache();
|
||||
}
|
||||
|
||||
|
||||
this.queryCache.set(cacheKey, {
|
||||
entities: [...entities], // 复制数组避免引用问题
|
||||
timestamp: Date.now(),
|
||||
@@ -794,12 +826,12 @@ export class QuerySystem {
|
||||
this.queryCache.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 如果还是太满,移除最少使用的条目
|
||||
if (this.queryCache.size >= this.cacheMaxSize) {
|
||||
const entries = Array.from(this.queryCache.entries());
|
||||
entries.sort((a, b) => a[1].hitCount - b[1].hitCount);
|
||||
|
||||
|
||||
const toRemove = Math.floor(this.cacheMaxSize * 0.2); // 移除20%
|
||||
for (let i = 0; i < toRemove && i < entries.length; i++) {
|
||||
this.queryCache.delete(entries[i][0]);
|
||||
@@ -841,7 +873,7 @@ export class QuerySystem {
|
||||
* 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) {
|
||||
try {
|
||||
const entityIds = updates.map(u => u.entityId);
|
||||
@@ -855,7 +887,7 @@ export class QuerySystem {
|
||||
} else {
|
||||
this.batchUpdateComponentsJS(updates);
|
||||
}
|
||||
|
||||
|
||||
// 批量更新后清除缓存
|
||||
this.clearQueryCache();
|
||||
}
|
||||
@@ -863,7 +895,7 @@ export class QuerySystem {
|
||||
/**
|
||||
* JavaScript实现的批量更新
|
||||
*/
|
||||
private batchUpdateComponentsJS(updates: Array<{entityId: number, componentMask: bigint}>): void {
|
||||
private batchUpdateComponentsJS(updates: Array<{ entityId: number, componentMask: bigint }>): void {
|
||||
for (const update of updates) {
|
||||
const entity = this.entities.find(e => e.id === update.entityId);
|
||||
if (entity) {
|
||||
@@ -897,7 +929,7 @@ export class QuerySystem {
|
||||
wasmEnabled: this.wasmAvailable,
|
||||
cacheStats: {
|
||||
size: this.queryCache.size,
|
||||
hitRate: this.queryStats.totalQueries > 0 ?
|
||||
hitRate: this.queryStats.totalQueries > 0 ?
|
||||
(this.queryStats.cacheHits / this.queryStats.totalQueries * 100).toFixed(2) + '%' : '0%'
|
||||
}
|
||||
}
|
||||
@@ -929,12 +961,12 @@ export class QuerySystem {
|
||||
private createComponentMask(componentTypes: ComponentType[]): bigint {
|
||||
// 使用位掩码优化器创建掩码
|
||||
const componentNames = componentTypes.map(type => type.name);
|
||||
|
||||
|
||||
// 确保组件类型已注册到优化器
|
||||
for (const name of componentNames) {
|
||||
this.bitMaskOptimizer.registerComponentType(name);
|
||||
}
|
||||
|
||||
|
||||
return this.bitMaskOptimizer.createCombinedMask(componentNames);
|
||||
}
|
||||
|
||||
@@ -960,8 +992,15 @@ export class QuerySystem {
|
||||
cacheHits: number;
|
||||
indexHits: number;
|
||||
linearScans: number;
|
||||
archetypeHits: number;
|
||||
dirtyChecks: number;
|
||||
cacheHitRate: string;
|
||||
};
|
||||
optimizationStats: {
|
||||
componentIndex: any;
|
||||
archetypeSystem: any;
|
||||
dirtyTracking: any;
|
||||
};
|
||||
} {
|
||||
return {
|
||||
entityCount: this.entities.length,
|
||||
@@ -974,11 +1013,89 @@ export class QuerySystem {
|
||||
accelerationStatus: this.getAccelerationStatus(),
|
||||
queryStats: {
|
||||
...this.queryStats,
|
||||
cacheHitRate: this.queryStats.totalQueries > 0 ?
|
||||
cacheHitRate: this.queryStats.totalQueries > 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 {
|
||||
const startTime = performance.now();
|
||||
|
||||
|
||||
// 简化实现:目前只支持单一条件
|
||||
if (this.conditions.length === 1) {
|
||||
const condition = this.conditions[0];
|
||||
@@ -1070,7 +1187,7 @@ export class QueryBuilder {
|
||||
return this.querySystem.queryNone(...condition.componentTypes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 多条件查询的复杂实现留待后续扩展
|
||||
return {
|
||||
entities: [],
|
||||
|
||||
@@ -16,3 +16,194 @@ export enum CoreEvents {
|
||||
*/
|
||||
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 { 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 eventBus: EventBus | null = null;
|
||||
|
||||
/**
|
||||
* 实体名称
|
||||
*
|
||||
@@ -538,6 +547,19 @@ export class Entity {
|
||||
// 调用组件的生命周期方法
|
||||
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) {
|
||||
for (const processor of this.scene.entityProcessors.processors) {
|
||||
@@ -744,6 +766,19 @@ export class Entity {
|
||||
// 调用组件的生命周期方法
|
||||
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;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { EntitySystem } from './Systems/EntitySystem';
|
||||
import { ComponentStorageManager } from './Core/ComponentStorage';
|
||||
import { QuerySystem } from './Core/QuerySystem';
|
||||
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 { PerformanceMonitor } from '../../Utils/PerformanceMonitor';
|
||||
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 _updateOrder: number = 0;
|
||||
private _enabled: boolean = true;
|
||||
|
||||
@@ -21,4 +21,557 @@ export enum ComponentTransform {
|
||||
Position = 1,
|
||||
Scale = 2,
|
||||
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