refactor: 规范化代码注释和更新核心模块 - 移除冗余JSDoc注释,统一代码风格

This commit is contained in:
YHH
2025-06-09 13:24:54 +08:00
parent e219fc47ba
commit 4095f1e946
7 changed files with 995 additions and 95 deletions

View File

@@ -1,3 +1,5 @@
import type { IComponent } from '../Types';
/**
* 游戏组件基类
*
@@ -18,7 +20,7 @@
* }
* ```
*/
export abstract class Component {
export abstract class Component implements IComponent {
/**
* 组件ID生成器
*

View File

@@ -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: [],

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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';
/**
* 游戏场景类

View File

@@ -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;

View File

@@ -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>;
}