项目统一改用Logger控制管理
拆分pool类和FluentAPI
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Component } from '../Component';
|
||||
import { IBigIntLike, BigIntFactory } from '../Utils/BigIntCompatibility';
|
||||
import { SoAStorage, EnableSoA, HighPrecision, Float64, Int32, SerializeMap, SerializeSet, SerializeArray, DeepCopy } from './SoAStorage';
|
||||
import { createLogger } from '../../Utils/Logger';
|
||||
|
||||
// 重新导出装饰器
|
||||
export { EnableSoA, HighPrecision, Float64, Int32, SerializeMap, SerializeSet, SerializeArray, DeepCopy };
|
||||
@@ -15,6 +16,7 @@ export type ComponentType<T extends Component = Component> = new (...args: unkno
|
||||
* 管理组件类型的位掩码分配
|
||||
*/
|
||||
export class ComponentRegistry {
|
||||
protected static readonly _logger = createLogger('ComponentStorage');
|
||||
private static componentTypes = new Map<Function, number>();
|
||||
private static componentNameToType = new Map<string, Function>();
|
||||
private static componentNameToId = new Map<string, number>();
|
||||
@@ -400,6 +402,7 @@ export class ComponentStorage<T extends Component> {
|
||||
* 管理所有组件类型的存储器
|
||||
*/
|
||||
export class ComponentStorageManager {
|
||||
private static readonly _logger = createLogger('ComponentStorage');
|
||||
private storages = new Map<Function, ComponentStorage<any> | SoAStorage<any>>();
|
||||
|
||||
/**
|
||||
@@ -417,7 +420,7 @@ export class ComponentStorageManager {
|
||||
if (enableSoA) {
|
||||
// 使用SoA优化存储
|
||||
storage = new SoAStorage(componentType);
|
||||
console.log(`[SoA] 为 ${componentType.name} 启用SoA优化(适用于大规模批量操作)`);
|
||||
ComponentStorageManager._logger.info(`为 ${componentType.name} 启用SoA优化(适用于大规模批量操作)`);
|
||||
} else {
|
||||
// 默认使用原始存储
|
||||
storage = new ComponentStorage(componentType);
|
||||
|
||||
196
packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts
Normal file
196
packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts
Normal file
@@ -0,0 +1,196 @@
|
||||
import { Component } from '../../Component';
|
||||
import { IBigIntLike, BigIntFactory } from '../../Utils/BigIntCompatibility';
|
||||
import { createLogger } from '../../../Utils/Logger';
|
||||
|
||||
/**
|
||||
* 组件类型定义
|
||||
*/
|
||||
export type ComponentType<T extends Component = Component> = new (...args: unknown[]) => T;
|
||||
|
||||
/**
|
||||
* 组件注册表
|
||||
* 管理组件类型的位掩码分配
|
||||
*/
|
||||
export class ComponentRegistry {
|
||||
protected static readonly _logger = createLogger('ComponentStorage');
|
||||
private static componentTypes = new Map<Function, number>();
|
||||
private static componentNameToType = new Map<string, Function>();
|
||||
private static componentNameToId = new Map<string, number>();
|
||||
private static maskCache = new Map<string, IBigIntLike>();
|
||||
private static nextBitIndex = 0;
|
||||
private static maxComponents = 64; // 支持最多64种组件类型
|
||||
|
||||
/**
|
||||
* 注册组件类型并分配位掩码
|
||||
* @param componentType 组件类型
|
||||
* @returns 分配的位索引
|
||||
*/
|
||||
public static register<T extends Component>(componentType: ComponentType<T>): number {
|
||||
if (this.componentTypes.has(componentType)) {
|
||||
return this.componentTypes.get(componentType)!;
|
||||
}
|
||||
|
||||
if (this.nextBitIndex >= this.maxComponents) {
|
||||
throw new Error(`Maximum number of component types (${this.maxComponents}) exceeded`);
|
||||
}
|
||||
|
||||
const bitIndex = this.nextBitIndex++;
|
||||
this.componentTypes.set(componentType, bitIndex);
|
||||
this.componentNameToType.set(componentType.name, componentType);
|
||||
this.componentNameToId.set(componentType.name, bitIndex);
|
||||
return bitIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组件类型的位掩码
|
||||
* @param componentType 组件类型
|
||||
* @returns 位掩码
|
||||
*/
|
||||
public static getBitMask<T extends Component>(componentType: ComponentType<T>): IBigIntLike {
|
||||
const bitIndex = this.componentTypes.get(componentType);
|
||||
if (bitIndex === undefined) {
|
||||
throw new Error(`Component type ${componentType.name} is not registered`);
|
||||
}
|
||||
return BigIntFactory.one().shiftLeft(bitIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组件类型的位索引
|
||||
* @param componentType 组件类型
|
||||
* @returns 位索引
|
||||
*/
|
||||
public static getBitIndex<T extends Component>(componentType: ComponentType<T>): number {
|
||||
const bitIndex = this.componentTypes.get(componentType);
|
||||
if (bitIndex === undefined) {
|
||||
throw new Error(`Component type ${componentType.name} is not registered`);
|
||||
}
|
||||
return bitIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查组件类型是否已注册
|
||||
* @param componentType 组件类型
|
||||
* @returns 是否已注册
|
||||
*/
|
||||
public static isRegistered<T extends Component>(componentType: ComponentType<T>): boolean {
|
||||
return this.componentTypes.has(componentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过名称获取组件类型
|
||||
* @param componentName 组件名称
|
||||
* @returns 组件类型构造函数
|
||||
*/
|
||||
public static getComponentType(componentName: string): Function | null {
|
||||
return this.componentNameToType.get(componentName) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有已注册的组件类型
|
||||
* @returns 组件类型映射
|
||||
*/
|
||||
public static getAllRegisteredTypes(): Map<Function, number> {
|
||||
return new Map(this.componentTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有组件名称到类型的映射
|
||||
* @returns 名称到类型的映射
|
||||
*/
|
||||
public static getAllComponentNames(): Map<string, Function> {
|
||||
return new Map(this.componentNameToType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过名称获取组件类型ID
|
||||
* @param componentName 组件名称
|
||||
* @returns 组件类型ID
|
||||
*/
|
||||
public static getComponentId(componentName: string): number | undefined {
|
||||
return this.componentNameToId.get(componentName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册组件类型(通过名称)
|
||||
* @param componentName 组件名称
|
||||
* @returns 分配的组件ID
|
||||
*/
|
||||
public static registerComponentByName(componentName: string): number {
|
||||
if (this.componentNameToId.has(componentName)) {
|
||||
return this.componentNameToId.get(componentName)!;
|
||||
}
|
||||
|
||||
if (this.nextBitIndex >= this.maxComponents) {
|
||||
throw new Error(`Maximum number of component types (${this.maxComponents}) exceeded`);
|
||||
}
|
||||
|
||||
const bitIndex = this.nextBitIndex++;
|
||||
this.componentNameToId.set(componentName, bitIndex);
|
||||
return bitIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建单个组件的掩码
|
||||
* @param componentName 组件名称
|
||||
* @returns 组件掩码
|
||||
*/
|
||||
public static createSingleComponentMask(componentName: string): IBigIntLike {
|
||||
const cacheKey = `single:${componentName}`;
|
||||
|
||||
if (this.maskCache.has(cacheKey)) {
|
||||
return this.maskCache.get(cacheKey)!;
|
||||
}
|
||||
|
||||
const componentId = this.getComponentId(componentName);
|
||||
if (componentId === undefined) {
|
||||
throw new Error(`Component type ${componentName} is not registered`);
|
||||
}
|
||||
|
||||
const mask = BigIntFactory.one().shiftLeft(componentId);
|
||||
this.maskCache.set(cacheKey, mask);
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建多个组件的掩码
|
||||
* @param componentNames 组件名称数组
|
||||
* @returns 组合掩码
|
||||
*/
|
||||
public static createComponentMask(componentNames: string[]): IBigIntLike {
|
||||
const sortedNames = [...componentNames].sort();
|
||||
const cacheKey = `multi:${sortedNames.join(',')}`;
|
||||
|
||||
if (this.maskCache.has(cacheKey)) {
|
||||
return this.maskCache.get(cacheKey)!;
|
||||
}
|
||||
|
||||
let mask = BigIntFactory.zero();
|
||||
for (const name of componentNames) {
|
||||
const componentId = this.getComponentId(name);
|
||||
if (componentId !== undefined) {
|
||||
mask = mask.or(BigIntFactory.one().shiftLeft(componentId));
|
||||
}
|
||||
}
|
||||
|
||||
this.maskCache.set(cacheKey, mask);
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除掩码缓存
|
||||
*/
|
||||
public static clearMaskCache(): void {
|
||||
this.maskCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置注册表(用于测试)
|
||||
*/
|
||||
public static reset(): void {
|
||||
this.componentTypes.clear();
|
||||
this.componentNameToType.clear();
|
||||
this.componentNameToId.clear();
|
||||
this.maskCache.clear();
|
||||
this.nextBitIndex = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Entity } from '../Entity';
|
||||
import { Component } from '../Component';
|
||||
import { ComponentType } from './ComponentStorage';
|
||||
import { createLogger } from '../../Utils/Logger';
|
||||
|
||||
/**
|
||||
* 脏标记类型
|
||||
@@ -89,7 +90,7 @@ export interface DirtyStats {
|
||||
* dirtySystem.addListener({
|
||||
* flags: DirtyFlag.TRANSFORM_CHANGED,
|
||||
* callback: (data) => {
|
||||
* console.log('Entity position changed:', data.entity.name);
|
||||
* logger.debug('Entity position changed:', data.entity.name);
|
||||
* }
|
||||
* });
|
||||
*
|
||||
@@ -98,6 +99,7 @@ export interface DirtyStats {
|
||||
* ```
|
||||
*/
|
||||
export class DirtyTrackingSystem {
|
||||
private static readonly _logger = createLogger('DirtyTrackingSystem');
|
||||
/** 脏实体映射表 */
|
||||
private _dirtyEntities = new Map<Entity, DirtyData>();
|
||||
|
||||
@@ -329,7 +331,7 @@ export class DirtyTrackingSystem {
|
||||
try {
|
||||
listener.callback(dirtyData);
|
||||
} catch (error) {
|
||||
console.error('脏数据监听器错误:', error);
|
||||
DirtyTrackingSystem._logger.error('脏数据监听器错误:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -346,7 +348,7 @@ export class DirtyTrackingSystem {
|
||||
try {
|
||||
listener.callback(dirtyData);
|
||||
} catch (error) {
|
||||
console.error('脏数据监听器通知错误:', error);
|
||||
DirtyTrackingSystem._logger.error('脏数据监听器通知错误:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
ISceneEventData,
|
||||
IPerformanceEventData
|
||||
} from '../../Types';
|
||||
import { createLogger } from '../../Utils/Logger';
|
||||
import {
|
||||
TypeSafeEventSystem,
|
||||
EventListenerConfig,
|
||||
@@ -26,6 +27,7 @@ import {
|
||||
* 基于TypeSafeEventSystem,提供类型安全的事件发布订阅机制
|
||||
*/
|
||||
export class EventBus implements IEventBus {
|
||||
private static readonly _logger = createLogger('EventBus');
|
||||
private eventSystem: TypeSafeEventSystem;
|
||||
private eventIdCounter = 0;
|
||||
private isDebugMode = false;
|
||||
@@ -47,7 +49,7 @@ export class EventBus implements IEventBus {
|
||||
const enhancedData = this.enhanceEventData(eventType, data);
|
||||
|
||||
if (this.isDebugMode) {
|
||||
console.log(`[EventBus] 发射事件: ${eventType}`, enhancedData);
|
||||
EventBus._logger.info(`发射事件: ${eventType}`, enhancedData);
|
||||
}
|
||||
|
||||
this.eventSystem.emitSync(eventType, enhancedData);
|
||||
@@ -65,7 +67,7 @@ export class EventBus implements IEventBus {
|
||||
const enhancedData = this.enhanceEventData(eventType, data);
|
||||
|
||||
if (this.isDebugMode) {
|
||||
console.log(`[EventBus] 发射异步事件: ${eventType}`, enhancedData);
|
||||
EventBus._logger.info(`发射异步事件: ${eventType}`, enhancedData);
|
||||
}
|
||||
|
||||
await this.eventSystem.emit(eventType, enhancedData);
|
||||
@@ -93,7 +95,7 @@ export class EventBus implements IEventBus {
|
||||
};
|
||||
|
||||
if (this.isDebugMode) {
|
||||
console.log(`[EventBus] 添加监听器: ${eventType}`, eventConfig);
|
||||
EventBus._logger.info(`添加监听器: ${eventType}`, eventConfig);
|
||||
}
|
||||
|
||||
return this.eventSystem.on(eventType, handler, eventConfig);
|
||||
@@ -136,7 +138,7 @@ export class EventBus implements IEventBus {
|
||||
*/
|
||||
public off(eventType: string, listenerId: string): boolean {
|
||||
if (this.isDebugMode) {
|
||||
console.log(`[EventBus] 移除监听器: ${listenerId} 事件: ${eventType}`);
|
||||
EventBus._logger.info(`移除监听器: ${listenerId} 事件: ${eventType}`);
|
||||
}
|
||||
|
||||
return this.eventSystem.off(eventType, listenerId);
|
||||
@@ -148,7 +150,7 @@ export class EventBus implements IEventBus {
|
||||
*/
|
||||
public offAll(eventType: string): void {
|
||||
if (this.isDebugMode) {
|
||||
console.log(`[EventBus] 移除所有监听器: ${eventType}`);
|
||||
EventBus._logger.info(`移除所有监听器: ${eventType}`);
|
||||
}
|
||||
|
||||
this.eventSystem.offAll(eventType);
|
||||
@@ -186,7 +188,7 @@ export class EventBus implements IEventBus {
|
||||
*/
|
||||
public clear(): void {
|
||||
if (this.isDebugMode) {
|
||||
console.log('[EventBus] 清空所有监听器');
|
||||
EventBus._logger.info('清空所有监听器');
|
||||
}
|
||||
|
||||
this.eventSystem.clear();
|
||||
@@ -379,7 +381,7 @@ export class EventBus implements IEventBus {
|
||||
private validateEventType(eventType: string): void {
|
||||
if (!EventTypeValidator.isValid(eventType)) {
|
||||
if (this.isDebugMode) {
|
||||
console.warn(`[EventBus] 未知事件类型: ${eventType}`);
|
||||
EventBus._logger.warn(`未知事件类型: ${eventType}`);
|
||||
}
|
||||
// 在调试模式下添加自定义事件类型
|
||||
if (this.isDebugMode) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { createLogger } from '../../Utils/Logger';
|
||||
|
||||
/**
|
||||
* 事件处理器函数类型
|
||||
*/
|
||||
@@ -66,6 +68,7 @@ export interface EventBatchConfig {
|
||||
* 支持同步/异步事件、优先级、批处理等功能
|
||||
*/
|
||||
export class TypeSafeEventSystem {
|
||||
private static readonly _logger = createLogger('EventSystem');
|
||||
private listeners = new Map<string, InternalEventListener[]>();
|
||||
private stats = new Map<string, EventStats>();
|
||||
private batchQueue = new Map<string, any[]>();
|
||||
@@ -204,7 +207,7 @@ export class TypeSafeEventSystem {
|
||||
toRemove.push(listener.id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`事件处理器执行错误 ${eventType}:`, error);
|
||||
TypeSafeEventSystem._logger.error(`事件处理器执行错误 ${eventType}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +339,7 @@ export class TypeSafeEventSystem {
|
||||
|
||||
// 检查监听器数量限制
|
||||
if (listeners.length >= this.maxListeners) {
|
||||
console.warn(`事件类型 ${eventType} 的监听器数量超过最大限制 (${this.maxListeners})`);
|
||||
TypeSafeEventSystem._logger.warn(`事件类型 ${eventType} 的监听器数量超过最大限制 (${this.maxListeners})`);
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -392,7 +395,7 @@ export class TypeSafeEventSystem {
|
||||
toRemove.push(listener.id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`同步事件处理器执行错误 ${eventType}:`, error);
|
||||
TypeSafeEventSystem._logger.error(`同步事件处理器执行错误 ${eventType}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,7 +412,7 @@ export class TypeSafeEventSystem {
|
||||
toRemove.push(listener.id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`异步事件处理器执行错误 ${eventType}:`, error);
|
||||
TypeSafeEventSystem._logger.error(`异步事件处理器执行错误 ${eventType}:`, error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,638 +1,11 @@
|
||||
import { Entity } from '../Entity';
|
||||
import { Component } from '../Component';
|
||||
import { Scene } from '../Scene';
|
||||
import { ComponentType, ComponentStorageManager } from './ComponentStorage';
|
||||
import { QuerySystem, QueryBuilder } from './QuerySystem';
|
||||
import { TypeSafeEventSystem } from './EventSystem';
|
||||
import { EntitySystem } from '../Systems/EntitySystem';
|
||||
|
||||
/**
|
||||
* 实体构建器 - 提供流式API创建和配置实体
|
||||
*/
|
||||
export class EntityBuilder {
|
||||
private entity: Entity;
|
||||
private scene: Scene;
|
||||
private storageManager: ComponentStorageManager;
|
||||
|
||||
constructor(scene: Scene, storageManager: ComponentStorageManager) {
|
||||
this.scene = scene;
|
||||
this.storageManager = storageManager;
|
||||
this.entity = new Entity("", scene.identifierPool.checkOut());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实体名称
|
||||
* @param name 实体名称
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public named(name: string): EntityBuilder {
|
||||
this.entity.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实体标签
|
||||
* @param tag 标签
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public tagged(tag: number): EntityBuilder {
|
||||
this.entity.tag = tag;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加组件
|
||||
* @param component 组件实例
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public with<T extends Component>(component: T): EntityBuilder {
|
||||
this.entity.addComponent(component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加多个组件
|
||||
* @param components 组件数组
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withComponents(...components: Component[]): EntityBuilder {
|
||||
for (const component of components) {
|
||||
this.entity.addComponent(component);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件性添加组件
|
||||
* @param condition 条件
|
||||
* @param component 组件实例
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withIf<T extends Component>(condition: boolean, component: T): EntityBuilder {
|
||||
if (condition) {
|
||||
this.entity.addComponent(component);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用工厂函数创建并添加组件
|
||||
* @param factory 组件工厂函数
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withFactory<T extends Component>(factory: () => T): EntityBuilder {
|
||||
const component = factory();
|
||||
this.entity.addComponent(component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置组件属性
|
||||
* @param componentType 组件类型
|
||||
* @param configurator 配置函数
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public configure<T extends Component>(
|
||||
componentType: ComponentType<T>,
|
||||
configurator: (component: T) => void
|
||||
): EntityBuilder {
|
||||
const component = this.entity.getComponent(componentType);
|
||||
if (component) {
|
||||
configurator(component);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实体为启用状态
|
||||
* @param enabled 是否启用
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public enabled(enabled: boolean = true): EntityBuilder {
|
||||
this.entity.enabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实体为活跃状态
|
||||
* @param active 是否活跃
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public active(active: boolean = true): EntityBuilder {
|
||||
this.entity.active = active;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加子实体
|
||||
* @param childBuilder 子实体构建器
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withChild(childBuilder: EntityBuilder): EntityBuilder {
|
||||
const child = childBuilder.build();
|
||||
this.entity.addChild(child);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加子实体
|
||||
* @param childBuilders 子实体构建器数组
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withChildren(...childBuilders: EntityBuilder[]): EntityBuilder {
|
||||
for (const childBuilder of childBuilders) {
|
||||
const child = childBuilder.build();
|
||||
this.entity.addChild(child);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用工厂函数创建子实体
|
||||
* @param childFactory 子实体工厂函数
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withChildFactory(childFactory: (parent: Entity) => EntityBuilder): EntityBuilder {
|
||||
const childBuilder = childFactory(this.entity);
|
||||
const child = childBuilder.build();
|
||||
this.entity.addChild(child);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件性添加子实体
|
||||
* @param condition 条件
|
||||
* @param childBuilder 子实体构建器
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withChildIf(condition: boolean, childBuilder: EntityBuilder): EntityBuilder {
|
||||
if (condition) {
|
||||
const child = childBuilder.build();
|
||||
this.entity.addChild(child);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建并返回实体
|
||||
* @returns 构建的实体
|
||||
*/
|
||||
public build(): Entity {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建实体并添加到场景
|
||||
* @returns 构建的实体
|
||||
*/
|
||||
public spawn(): Entity {
|
||||
this.scene.addEntity(this.entity);
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 克隆当前构建器
|
||||
* @returns 新的实体构建器
|
||||
*/
|
||||
public clone(): EntityBuilder {
|
||||
const newBuilder = new EntityBuilder(this.scene, this.storageManager);
|
||||
// 这里需要深度克隆实体,简化实现
|
||||
newBuilder.entity = this.entity; // 实际应该是深度克隆
|
||||
return newBuilder;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景构建器 - 提供流式API创建和配置场景
|
||||
*/
|
||||
export class SceneBuilder {
|
||||
private scene: Scene;
|
||||
|
||||
constructor() {
|
||||
this.scene = new Scene();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置场景名称
|
||||
* @param name 场景名称
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public named(name: string): SceneBuilder {
|
||||
this.scene.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加实体
|
||||
* @param entity 实体
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withEntity(entity: Entity): SceneBuilder {
|
||||
this.scene.addEntity(entity);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用实体构建器添加实体
|
||||
* @param builderFn 实体构建器函数
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withEntityBuilder(builderFn: (builder: EntityBuilder) => EntityBuilder): SceneBuilder {
|
||||
const builder = new EntityBuilder(this.scene, this.scene.componentStorageManager);
|
||||
const configuredBuilder = builderFn(builder);
|
||||
const entity = configuredBuilder.build();
|
||||
this.scene.addEntity(entity);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加实体
|
||||
* @param entities 实体数组
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withEntities(...entities: Entity[]): SceneBuilder {
|
||||
for (const entity of entities) {
|
||||
this.scene.addEntity(entity);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加系统
|
||||
* @param system 系统实例
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withSystem(system: EntitySystem): SceneBuilder {
|
||||
this.scene.addSystem(system);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加系统
|
||||
* @param systems 系统数组
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withSystems(...systems: EntitySystem[]): SceneBuilder {
|
||||
for (const system of systems) {
|
||||
this.scene.addSystem(system);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建并返回场景
|
||||
* @returns 构建的场景
|
||||
*/
|
||||
public build(): Scene {
|
||||
return this.scene;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件构建器 - 提供流式API创建组件
|
||||
*/
|
||||
export class ComponentBuilder<T extends Component> {
|
||||
private component: T;
|
||||
|
||||
constructor(componentClass: new (...args: unknown[]) => T, ...args: unknown[]) {
|
||||
this.component = new componentClass(...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置组件属性
|
||||
* @param property 属性名
|
||||
* @param value 属性值
|
||||
* @returns 组件构建器
|
||||
*/
|
||||
public set<K extends keyof T>(property: K, value: T[K]): ComponentBuilder<T> {
|
||||
this.component[property] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用配置函数设置组件
|
||||
* @param configurator 配置函数
|
||||
* @returns 组件构建器
|
||||
*/
|
||||
public configure(configurator: (component: T) => void): ComponentBuilder<T> {
|
||||
configurator(this.component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件性设置属性
|
||||
* @param condition 条件
|
||||
* @param property 属性名
|
||||
* @param value 属性值
|
||||
* @returns 组件构建器
|
||||
*/
|
||||
public setIf<K extends keyof T>(condition: boolean, property: K, value: T[K]): ComponentBuilder<T> {
|
||||
if (condition) {
|
||||
this.component[property] = value;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建并返回组件
|
||||
* @returns 构建的组件
|
||||
*/
|
||||
public build(): T {
|
||||
return this.component;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ECS流式API主入口
|
||||
* 提供统一的流式接口
|
||||
*/
|
||||
export class ECSFluentAPI {
|
||||
private scene: Scene;
|
||||
private querySystem: QuerySystem;
|
||||
private eventSystem: TypeSafeEventSystem;
|
||||
|
||||
constructor(scene: Scene, querySystem: QuerySystem, eventSystem: TypeSafeEventSystem) {
|
||||
this.scene = scene;
|
||||
this.querySystem = querySystem;
|
||||
this.eventSystem = eventSystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建实体构建器
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public createEntity(): EntityBuilder {
|
||||
return new EntityBuilder(this.scene, this.scene.componentStorageManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建场景构建器
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public createScene(): SceneBuilder {
|
||||
return new SceneBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建组件构建器
|
||||
* @param componentClass 组件类
|
||||
* @param args 构造参数
|
||||
* @returns 组件构建器
|
||||
*/
|
||||
public createComponent<T extends Component>(
|
||||
componentClass: new (...args: unknown[]) => T,
|
||||
...args: unknown[]
|
||||
): ComponentBuilder<T> {
|
||||
return new ComponentBuilder(componentClass, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建查询构建器
|
||||
* @returns 查询构建器
|
||||
*/
|
||||
public query(): QueryBuilder {
|
||||
return new QueryBuilder(this.querySystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找实体(简化版)
|
||||
* @param componentTypes 组件类型
|
||||
* @returns 实体数组
|
||||
*/
|
||||
public find(...componentTypes: ComponentType[]): Entity[] {
|
||||
return this.querySystem.queryAll(...componentTypes).entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找第一个匹配的实体
|
||||
* @param componentTypes 组件类型
|
||||
* @returns 实体或null
|
||||
*/
|
||||
public findFirst(...componentTypes: ComponentType[]): Entity | null {
|
||||
const result = this.querySystem.queryAll(...componentTypes);
|
||||
return result.entities.length > 0 ? result.entities[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按名称查找实体
|
||||
* @param name 实体名称
|
||||
* @returns 实体或null
|
||||
*/
|
||||
public findByName(name: string): Entity | null {
|
||||
return this.scene.getEntityByName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按标签查找实体
|
||||
* @param tag 标签
|
||||
* @returns 实体数组
|
||||
*/
|
||||
public findByTag(tag: number): Entity[] {
|
||||
return this.scene.getEntitiesByTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发事件
|
||||
* @param eventType 事件类型
|
||||
* @param event 事件数据
|
||||
*/
|
||||
public emit<T>(eventType: string, event: T): void {
|
||||
this.eventSystem.emitSync(eventType, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步触发事件
|
||||
* @param eventType 事件类型
|
||||
* @param event 事件数据
|
||||
*/
|
||||
public async emitAsync<T>(eventType: string, event: T): Promise<void> {
|
||||
await this.eventSystem.emit(eventType, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听事件
|
||||
* @param eventType 事件类型
|
||||
* @param handler 事件处理器
|
||||
* @returns 监听器ID
|
||||
*/
|
||||
public on<T>(eventType: string, handler: (event: T) => void): string {
|
||||
return this.eventSystem.on(eventType, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次性监听事件
|
||||
* @param eventType 事件类型
|
||||
* @param handler 事件处理器
|
||||
* @returns 监听器ID
|
||||
*/
|
||||
public once<T>(eventType: string, handler: (event: T) => void): string {
|
||||
return this.eventSystem.once(eventType, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除事件监听器
|
||||
* @param eventType 事件类型
|
||||
* @param listenerId 监听器ID
|
||||
*/
|
||||
public off(eventType: string, listenerId: string): void {
|
||||
this.eventSystem.off(eventType, listenerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量操作实体
|
||||
* @param entities 实体数组
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public batch(entities: Entity[]): EntityBatchOperator {
|
||||
return new EntityBatchOperator(entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取场景统计信息
|
||||
* @returns 统计信息
|
||||
*/
|
||||
public getStats(): {
|
||||
entityCount: number;
|
||||
systemCount: number;
|
||||
componentStats: Map<string, any>;
|
||||
queryStats: unknown;
|
||||
eventStats: Map<string, any>;
|
||||
} {
|
||||
return {
|
||||
entityCount: this.scene.entities.count,
|
||||
systemCount: this.scene.systems.length,
|
||||
componentStats: this.scene.componentStorageManager.getAllStats(),
|
||||
queryStats: this.querySystem.getStats(),
|
||||
eventStats: this.eventSystem.getStats() as Map<string, any>
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体批量操作器
|
||||
* 提供对多个实体的批量操作
|
||||
*/
|
||||
export class EntityBatchOperator {
|
||||
private entities: Entity[];
|
||||
|
||||
constructor(entities: Entity[]) {
|
||||
this.entities = entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加组件
|
||||
* @param component 组件实例
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public addComponent<T extends Component>(component: T): EntityBatchOperator {
|
||||
for (const entity of this.entities) {
|
||||
entity.addComponent(component);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量移除组件
|
||||
* @param componentType 组件类型
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public removeComponent<T extends Component>(componentType: ComponentType<T>): EntityBatchOperator {
|
||||
for (const entity of this.entities) {
|
||||
entity.removeComponentByType(componentType);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置活跃状态
|
||||
* @param active 是否活跃
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public setActive(active: boolean): EntityBatchOperator {
|
||||
for (const entity of this.entities) {
|
||||
entity.active = active;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置标签
|
||||
* @param tag 标签
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public setTag(tag: number): EntityBatchOperator {
|
||||
for (const entity of this.entities) {
|
||||
entity.tag = tag;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量执行操作
|
||||
* @param operation 操作函数
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public forEach(operation: (entity: Entity, index: number) => void): EntityBatchOperator {
|
||||
this.entities.forEach(operation);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤实体
|
||||
* @param predicate 过滤条件
|
||||
* @returns 新的批量操作器
|
||||
*/
|
||||
public filter(predicate: (entity: Entity) => boolean): EntityBatchOperator {
|
||||
return new EntityBatchOperator(this.entities.filter(predicate));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实体数组
|
||||
* @returns 实体数组
|
||||
*/
|
||||
public toArray(): Entity[] {
|
||||
return this.entities.slice();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实体数量
|
||||
* @returns 实体数量
|
||||
*/
|
||||
public count(): number {
|
||||
return this.entities.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建ECS流式API实例
|
||||
* @param scene 场景
|
||||
* @param querySystem 查询系统
|
||||
* @param eventSystem 事件系统
|
||||
* @returns ECS流式API实例
|
||||
*/
|
||||
export function createECSAPI(
|
||||
scene: Scene,
|
||||
querySystem: QuerySystem,
|
||||
eventSystem: TypeSafeEventSystem
|
||||
): ECSFluentAPI {
|
||||
return new ECSFluentAPI(scene, querySystem, eventSystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局ECS流式API实例(需要在使用前初始化)
|
||||
*/
|
||||
export let ECS: ECSFluentAPI;
|
||||
|
||||
/**
|
||||
* 初始化全局ECS API
|
||||
* @param scene 场景
|
||||
* @param querySystem 查询系统
|
||||
* @param eventSystem 事件系统
|
||||
*/
|
||||
export function initializeECS(
|
||||
scene: Scene,
|
||||
querySystem: QuerySystem,
|
||||
eventSystem: TypeSafeEventSystem
|
||||
): void {
|
||||
ECS = createECSAPI(scene, querySystem, eventSystem);
|
||||
}
|
||||
// 重新导出拆分后的模块以保持向后兼容性
|
||||
export {
|
||||
EntityBuilder,
|
||||
SceneBuilder,
|
||||
ComponentBuilder,
|
||||
EntityBatchOperator,
|
||||
ECSFluentAPI,
|
||||
createECSAPI,
|
||||
initializeECS,
|
||||
ECS
|
||||
} from './FluentAPI/index';
|
||||
55
packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts
Normal file
55
packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Component } from '../../Component';
|
||||
|
||||
/**
|
||||
* 组件构建器 - 提供流式API创建组件
|
||||
*/
|
||||
export class ComponentBuilder<T extends Component> {
|
||||
private component: T;
|
||||
|
||||
constructor(componentClass: new (...args: unknown[]) => T, ...args: unknown[]) {
|
||||
this.component = new componentClass(...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置组件属性
|
||||
* @param property 属性名
|
||||
* @param value 属性值
|
||||
* @returns 组件构建器
|
||||
*/
|
||||
public set<K extends keyof T>(property: K, value: T[K]): ComponentBuilder<T> {
|
||||
this.component[property] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用配置函数设置组件
|
||||
* @param configurator 配置函数
|
||||
* @returns 组件构建器
|
||||
*/
|
||||
public configure(configurator: (component: T) => void): ComponentBuilder<T> {
|
||||
configurator(this.component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件性设置属性
|
||||
* @param condition 条件
|
||||
* @param property 属性名
|
||||
* @param value 属性值
|
||||
* @returns 组件构建器
|
||||
*/
|
||||
public setIf<K extends keyof T>(condition: boolean, property: K, value: T[K]): ComponentBuilder<T> {
|
||||
if (condition) {
|
||||
this.component[property] = value;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建并返回组件
|
||||
* @returns 构建的组件
|
||||
*/
|
||||
public build(): T {
|
||||
return this.component;
|
||||
}
|
||||
}
|
||||
210
packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts
Normal file
210
packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
import { Entity } from '../../Entity';
|
||||
import { Component } from '../../Component';
|
||||
import { Scene } from '../../Scene';
|
||||
import { ComponentType } from '../ComponentStorage';
|
||||
import { QuerySystem, QueryBuilder } from '../QuerySystem';
|
||||
import { TypeSafeEventSystem } from '../EventSystem';
|
||||
import { EntityBuilder } from './EntityBuilder';
|
||||
import { SceneBuilder } from './SceneBuilder';
|
||||
import { ComponentBuilder } from './ComponentBuilder';
|
||||
import { EntityBatchOperator } from './EntityBatchOperator';
|
||||
|
||||
/**
|
||||
* ECS流式API主入口
|
||||
* 提供统一的流式接口
|
||||
*/
|
||||
export class ECSFluentAPI {
|
||||
private scene: Scene;
|
||||
private querySystem: QuerySystem;
|
||||
private eventSystem: TypeSafeEventSystem;
|
||||
|
||||
constructor(scene: Scene, querySystem: QuerySystem, eventSystem: TypeSafeEventSystem) {
|
||||
this.scene = scene;
|
||||
this.querySystem = querySystem;
|
||||
this.eventSystem = eventSystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建实体构建器
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public createEntity(): EntityBuilder {
|
||||
return new EntityBuilder(this.scene, this.scene.componentStorageManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建场景构建器
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public createScene(): SceneBuilder {
|
||||
return new SceneBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建组件构建器
|
||||
* @param componentClass 组件类
|
||||
* @param args 构造参数
|
||||
* @returns 组件构建器
|
||||
*/
|
||||
public createComponent<T extends Component>(
|
||||
componentClass: new (...args: unknown[]) => T,
|
||||
...args: unknown[]
|
||||
): ComponentBuilder<T> {
|
||||
return new ComponentBuilder(componentClass, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建查询构建器
|
||||
* @returns 查询构建器
|
||||
*/
|
||||
public query(): QueryBuilder {
|
||||
return new QueryBuilder(this.querySystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找实体(简化版)
|
||||
* @param componentTypes 组件类型
|
||||
* @returns 实体数组
|
||||
*/
|
||||
public find(...componentTypes: ComponentType[]): Entity[] {
|
||||
return this.querySystem.queryAll(...componentTypes).entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找第一个匹配的实体
|
||||
* @param componentTypes 组件类型
|
||||
* @returns 实体或null
|
||||
*/
|
||||
public findFirst(...componentTypes: ComponentType[]): Entity | null {
|
||||
const result = this.querySystem.queryAll(...componentTypes);
|
||||
return result.entities.length > 0 ? result.entities[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按名称查找实体
|
||||
* @param name 实体名称
|
||||
* @returns 实体或null
|
||||
*/
|
||||
public findByName(name: string): Entity | null {
|
||||
return this.scene.getEntityByName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按标签查找实体
|
||||
* @param tag 标签
|
||||
* @returns 实体数组
|
||||
*/
|
||||
public findByTag(tag: number): Entity[] {
|
||||
return this.scene.getEntitiesByTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发事件
|
||||
* @param eventType 事件类型
|
||||
* @param event 事件数据
|
||||
*/
|
||||
public emit<T>(eventType: string, event: T): void {
|
||||
this.eventSystem.emitSync(eventType, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步触发事件
|
||||
* @param eventType 事件类型
|
||||
* @param event 事件数据
|
||||
*/
|
||||
public async emitAsync<T>(eventType: string, event: T): Promise<void> {
|
||||
await this.eventSystem.emit(eventType, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听事件
|
||||
* @param eventType 事件类型
|
||||
* @param handler 事件处理器
|
||||
* @returns 监听器ID
|
||||
*/
|
||||
public on<T>(eventType: string, handler: (event: T) => void): string {
|
||||
return this.eventSystem.on(eventType, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次性监听事件
|
||||
* @param eventType 事件类型
|
||||
* @param handler 事件处理器
|
||||
* @returns 监听器ID
|
||||
*/
|
||||
public once<T>(eventType: string, handler: (event: T) => void): string {
|
||||
return this.eventSystem.once(eventType, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除事件监听器
|
||||
* @param eventType 事件类型
|
||||
* @param listenerId 监听器ID
|
||||
*/
|
||||
public off(eventType: string, listenerId: string): void {
|
||||
this.eventSystem.off(eventType, listenerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量操作实体
|
||||
* @param entities 实体数组
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public batch(entities: Entity[]): EntityBatchOperator {
|
||||
return new EntityBatchOperator(entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取场景统计信息
|
||||
* @returns 统计信息
|
||||
*/
|
||||
public getStats(): {
|
||||
entityCount: number;
|
||||
systemCount: number;
|
||||
componentStats: Map<string, any>;
|
||||
queryStats: unknown;
|
||||
eventStats: Map<string, any>;
|
||||
} {
|
||||
return {
|
||||
entityCount: this.scene.entities.count,
|
||||
systemCount: this.scene.systems.length,
|
||||
componentStats: this.scene.componentStorageManager.getAllStats(),
|
||||
queryStats: this.querySystem.getStats(),
|
||||
eventStats: this.eventSystem.getStats() as Map<string, any>
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建ECS流式API实例
|
||||
* @param scene 场景
|
||||
* @param querySystem 查询系统
|
||||
* @param eventSystem 事件系统
|
||||
* @returns ECS流式API实例
|
||||
*/
|
||||
export function createECSAPI(
|
||||
scene: Scene,
|
||||
querySystem: QuerySystem,
|
||||
eventSystem: TypeSafeEventSystem
|
||||
): ECSFluentAPI {
|
||||
return new ECSFluentAPI(scene, querySystem, eventSystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局ECS流式API实例(需要在使用前初始化)
|
||||
*/
|
||||
export let ECS: ECSFluentAPI;
|
||||
|
||||
/**
|
||||
* 初始化全局ECS API
|
||||
* @param scene 场景
|
||||
* @param querySystem 查询系统
|
||||
* @param eventSystem 事件系统
|
||||
*/
|
||||
export function initializeECS(
|
||||
scene: Scene,
|
||||
querySystem: QuerySystem,
|
||||
eventSystem: TypeSafeEventSystem
|
||||
): void {
|
||||
ECS = createECSAPI(scene, querySystem, eventSystem);
|
||||
}
|
||||
98
packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts
Normal file
98
packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { Entity } from '../../Entity';
|
||||
import { Component } from '../../Component';
|
||||
import { ComponentType } from '../ComponentStorage';
|
||||
|
||||
/**
|
||||
* 实体批量操作器
|
||||
* 提供对多个实体的批量操作
|
||||
*/
|
||||
export class EntityBatchOperator {
|
||||
private entities: Entity[];
|
||||
|
||||
constructor(entities: Entity[]) {
|
||||
this.entities = entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加组件
|
||||
* @param component 组件实例
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public addComponent<T extends Component>(component: T): EntityBatchOperator {
|
||||
for (const entity of this.entities) {
|
||||
entity.addComponent(component);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量移除组件
|
||||
* @param componentType 组件类型
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public removeComponent<T extends Component>(componentType: ComponentType<T>): EntityBatchOperator {
|
||||
for (const entity of this.entities) {
|
||||
entity.removeComponentByType(componentType);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置活跃状态
|
||||
* @param active 是否活跃
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public setActive(active: boolean): EntityBatchOperator {
|
||||
for (const entity of this.entities) {
|
||||
entity.active = active;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置标签
|
||||
* @param tag 标签
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public setTag(tag: number): EntityBatchOperator {
|
||||
for (const entity of this.entities) {
|
||||
entity.tag = tag;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量执行操作
|
||||
* @param operation 操作函数
|
||||
* @returns 批量操作器
|
||||
*/
|
||||
public forEach(operation: (entity: Entity, index: number) => void): EntityBatchOperator {
|
||||
this.entities.forEach(operation);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤实体
|
||||
* @param predicate 过滤条件
|
||||
* @returns 新的批量操作器
|
||||
*/
|
||||
public filter(predicate: (entity: Entity) => boolean): EntityBatchOperator {
|
||||
return new EntityBatchOperator(this.entities.filter(predicate));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实体数组
|
||||
* @returns 实体数组
|
||||
*/
|
||||
public toArray(): Entity[] {
|
||||
return this.entities.slice();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实体数量
|
||||
* @returns 实体数量
|
||||
*/
|
||||
public count(): number {
|
||||
return this.entities.length;
|
||||
}
|
||||
}
|
||||
200
packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts
Normal file
200
packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts
Normal file
@@ -0,0 +1,200 @@
|
||||
import { Entity } from '../../Entity';
|
||||
import { Component } from '../../Component';
|
||||
import { Scene } from '../../Scene';
|
||||
import { ComponentType, ComponentStorageManager } from '../ComponentStorage';
|
||||
|
||||
/**
|
||||
* 实体构建器 - 提供流式API创建和配置实体
|
||||
*/
|
||||
export class EntityBuilder {
|
||||
private entity: Entity;
|
||||
private scene: Scene;
|
||||
private storageManager: ComponentStorageManager;
|
||||
|
||||
constructor(scene: Scene, storageManager: ComponentStorageManager) {
|
||||
this.scene = scene;
|
||||
this.storageManager = storageManager;
|
||||
this.entity = new Entity("", scene.identifierPool.checkOut());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实体名称
|
||||
* @param name 实体名称
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public named(name: string): EntityBuilder {
|
||||
this.entity.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实体标签
|
||||
* @param tag 标签
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public tagged(tag: number): EntityBuilder {
|
||||
this.entity.tag = tag;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加组件
|
||||
* @param component 组件实例
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public with<T extends Component>(component: T): EntityBuilder {
|
||||
this.entity.addComponent(component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加多个组件
|
||||
* @param components 组件数组
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withComponents(...components: Component[]): EntityBuilder {
|
||||
for (const component of components) {
|
||||
this.entity.addComponent(component);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件性添加组件
|
||||
* @param condition 条件
|
||||
* @param component 组件实例
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withIf<T extends Component>(condition: boolean, component: T): EntityBuilder {
|
||||
if (condition) {
|
||||
this.entity.addComponent(component);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用工厂函数创建并添加组件
|
||||
* @param factory 组件工厂函数
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withFactory<T extends Component>(factory: () => T): EntityBuilder {
|
||||
const component = factory();
|
||||
this.entity.addComponent(component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置组件属性
|
||||
* @param componentType 组件类型
|
||||
* @param configurator 配置函数
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public configure<T extends Component>(
|
||||
componentType: ComponentType<T>,
|
||||
configurator: (component: T) => void
|
||||
): EntityBuilder {
|
||||
const component = this.entity.getComponent(componentType);
|
||||
if (component) {
|
||||
configurator(component);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实体为启用状态
|
||||
* @param enabled 是否启用
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public enabled(enabled: boolean = true): EntityBuilder {
|
||||
this.entity.enabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实体为活跃状态
|
||||
* @param active 是否活跃
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public active(active: boolean = true): EntityBuilder {
|
||||
this.entity.active = active;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加子实体
|
||||
* @param childBuilder 子实体构建器
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withChild(childBuilder: EntityBuilder): EntityBuilder {
|
||||
const child = childBuilder.build();
|
||||
this.entity.addChild(child);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加子实体
|
||||
* @param childBuilders 子实体构建器数组
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withChildren(...childBuilders: EntityBuilder[]): EntityBuilder {
|
||||
for (const childBuilder of childBuilders) {
|
||||
const child = childBuilder.build();
|
||||
this.entity.addChild(child);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用工厂函数创建子实体
|
||||
* @param childFactory 子实体工厂函数
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withChildFactory(childFactory: (parent: Entity) => EntityBuilder): EntityBuilder {
|
||||
const childBuilder = childFactory(this.entity);
|
||||
const child = childBuilder.build();
|
||||
this.entity.addChild(child);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件性添加子实体
|
||||
* @param condition 条件
|
||||
* @param childBuilder 子实体构建器
|
||||
* @returns 实体构建器
|
||||
*/
|
||||
public withChildIf(condition: boolean, childBuilder: EntityBuilder): EntityBuilder {
|
||||
if (condition) {
|
||||
const child = childBuilder.build();
|
||||
this.entity.addChild(child);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建并返回实体
|
||||
* @returns 构建的实体
|
||||
*/
|
||||
public build(): Entity {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建实体并添加到场景
|
||||
* @returns 构建的实体
|
||||
*/
|
||||
public spawn(): Entity {
|
||||
this.scene.addEntity(this.entity);
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 克隆当前构建器
|
||||
* @returns 新的实体构建器
|
||||
*/
|
||||
public clone(): EntityBuilder {
|
||||
const newBuilder = new EntityBuilder(this.scene, this.storageManager);
|
||||
// 这里需要深度克隆实体,简化实现
|
||||
newBuilder.entity = this.entity; // 实际应该是深度克隆
|
||||
return newBuilder;
|
||||
}
|
||||
}
|
||||
90
packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts
Normal file
90
packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { Entity } from '../../Entity';
|
||||
import { Scene } from '../../Scene';
|
||||
import { EntitySystem } from '../../Systems/EntitySystem';
|
||||
import { EntityBuilder } from './EntityBuilder';
|
||||
|
||||
/**
|
||||
* 场景构建器 - 提供流式API创建和配置场景
|
||||
*/
|
||||
export class SceneBuilder {
|
||||
private scene: Scene;
|
||||
|
||||
constructor() {
|
||||
this.scene = new Scene();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置场景名称
|
||||
* @param name 场景名称
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public named(name: string): SceneBuilder {
|
||||
this.scene.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加实体
|
||||
* @param entity 实体
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withEntity(entity: Entity): SceneBuilder {
|
||||
this.scene.addEntity(entity);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用实体构建器添加实体
|
||||
* @param builderFn 实体构建器函数
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withEntityBuilder(builderFn: (builder: EntityBuilder) => EntityBuilder): SceneBuilder {
|
||||
const builder = new EntityBuilder(this.scene, this.scene.componentStorageManager);
|
||||
const configuredBuilder = builderFn(builder);
|
||||
const entity = configuredBuilder.build();
|
||||
this.scene.addEntity(entity);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加实体
|
||||
* @param entities 实体数组
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withEntities(...entities: Entity[]): SceneBuilder {
|
||||
for (const entity of entities) {
|
||||
this.scene.addEntity(entity);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加系统
|
||||
* @param system 系统实例
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withSystem(system: EntitySystem): SceneBuilder {
|
||||
this.scene.addSystem(system);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加系统
|
||||
* @param systems 系统数组
|
||||
* @returns 场景构建器
|
||||
*/
|
||||
public withSystems(...systems: EntitySystem[]): SceneBuilder {
|
||||
for (const system of systems) {
|
||||
this.scene.addSystem(system);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建并返回场景
|
||||
* @returns 构建的场景
|
||||
*/
|
||||
public build(): Scene {
|
||||
return this.scene;
|
||||
}
|
||||
}
|
||||
5
packages/core/src/ECS/Core/FluentAPI/index.ts
Normal file
5
packages/core/src/ECS/Core/FluentAPI/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export { EntityBuilder } from './EntityBuilder';
|
||||
export { SceneBuilder } from './SceneBuilder';
|
||||
export { ComponentBuilder } from './ComponentBuilder';
|
||||
export { EntityBatchOperator } from './EntityBatchOperator';
|
||||
export { ECSFluentAPI, createECSAPI, initializeECS, ECS } from './ECSFluentAPI';
|
||||
@@ -2,6 +2,7 @@ import { Entity } from '../Entity';
|
||||
import { Component } from '../Component';
|
||||
import { ComponentRegistry, ComponentType } from './ComponentStorage';
|
||||
import { IBigIntLike, BigIntFactory } from '../Utils/BigIntCompatibility';
|
||||
import { createLogger } from '../../Utils/Logger';
|
||||
|
||||
import { ComponentPoolManager } from './ComponentPool';
|
||||
import { ComponentIndexManager, IndexType } from './ComponentIndex';
|
||||
@@ -82,6 +83,7 @@ interface QueryCacheEntry {
|
||||
* ```
|
||||
*/
|
||||
export class QuerySystem {
|
||||
private _logger = createLogger('QuerySystem');
|
||||
private entities: Entity[] = [];
|
||||
private entityIndex: EntityIndex;
|
||||
private indexDirty = true;
|
||||
@@ -390,7 +392,7 @@ export class QuerySystem {
|
||||
* ```typescript
|
||||
* // 查询同时具有位置和速度组件的实体
|
||||
* const result = querySystem.queryAll(PositionComponent, VelocityComponent);
|
||||
* console.log(`找到 ${result.count} 个移动实体`);
|
||||
* logger.info(`找到 ${result.count} 个移动实体`);
|
||||
* ```
|
||||
*/
|
||||
public queryAll(...componentTypes: ComponentType[]): QueryResult {
|
||||
@@ -502,7 +504,7 @@ export class QuerySystem {
|
||||
* ```typescript
|
||||
* // 查询具有武器或护甲组件的实体
|
||||
* const result = querySystem.queryAny(WeaponComponent, ArmorComponent);
|
||||
* console.log(`找到 ${result.count} 个装备实体`);
|
||||
* logger.info(`找到 ${result.count} 个装备实体`);
|
||||
* ```
|
||||
*/
|
||||
public queryAny(...componentTypes: ComponentType[]): QueryResult {
|
||||
@@ -560,7 +562,7 @@ export class QuerySystem {
|
||||
* ```typescript
|
||||
* // 查询不具有AI和玩家控制组件的实体(如静态物体)
|
||||
* const result = querySystem.queryNone(AIComponent, PlayerControlComponent);
|
||||
* console.log(`找到 ${result.count} 个静态实体`);
|
||||
* logger.info(`找到 ${result.count} 个静态实体`);
|
||||
* ```
|
||||
*/
|
||||
public queryNone(...componentTypes: ComponentType[]): QueryResult {
|
||||
@@ -878,7 +880,7 @@ export class QuerySystem {
|
||||
mask = mask.or(bitMask);
|
||||
hasValidComponents = true;
|
||||
} catch (error) {
|
||||
console.warn(`组件类型 ${type.name} 未注册,跳过`);
|
||||
this._logger.warn(`组件类型 ${type.name} 未注册,跳过`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1054,6 +1056,7 @@ export class QuerySystem {
|
||||
* ```
|
||||
*/
|
||||
export class QueryBuilder {
|
||||
private _logger = createLogger('QueryBuilder');
|
||||
private conditions: QueryCondition[] = [];
|
||||
private querySystem: QuerySystem;
|
||||
|
||||
@@ -1148,7 +1151,7 @@ export class QueryBuilder {
|
||||
const bitMask = ComponentRegistry.getBitMask(type);
|
||||
mask = mask.or(bitMask);
|
||||
} catch (error) {
|
||||
console.warn(`组件类型 ${type.name} 未注册,跳过`);
|
||||
this._logger.warn(`组件类型 ${type.name} 未注册,跳过`);
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component } from '../Component';
|
||||
import { ComponentType } from './ComponentStorage';
|
||||
import { createLogger } from '../../Utils/Logger';
|
||||
|
||||
/**
|
||||
* 启用SoA优化装饰器
|
||||
@@ -113,6 +114,7 @@ export function DeepCopy(target: any, propertyKey: string | symbol): void {
|
||||
* 使用Structure of Arrays存储模式,在大规模批量操作时提供优异性能
|
||||
*/
|
||||
export class SoAStorage<T extends Component> {
|
||||
private static readonly _logger = createLogger('SoAStorage');
|
||||
private fields = new Map<string, Float32Array | Float64Array | Int32Array>();
|
||||
private stringFields = new Map<string, string[]>(); // 专门存储字符串
|
||||
private serializedFields = new Map<string, string[]>(); // 序列化存储Map/Set/Array
|
||||
@@ -276,7 +278,7 @@ export class SoAStorage<T extends Component> {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`SoA序列化字段 ${key} 失败:`, error);
|
||||
SoAStorage._logger.warn(`SoA序列化字段 ${key} 失败:`, error);
|
||||
return '{}';
|
||||
}
|
||||
}
|
||||
@@ -301,7 +303,7 @@ export class SoAStorage<T extends Component> {
|
||||
return parsed;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`SoA反序列化字段 ${key} 失败:`, error);
|
||||
SoAStorage._logger.warn(`SoA反序列化字段 ${key} 失败:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Component } from './Component';
|
||||
import { ComponentRegistry, ComponentType } from './Core/ComponentStorage';
|
||||
import { EventBus } from './Core/EventBus';
|
||||
import { IBigIntLike, BigIntFactory } from './Utils/BigIntCompatibility';
|
||||
import { createLogger } from '../Utils/Logger';
|
||||
|
||||
// Forward declaration to avoid circular dependency
|
||||
interface IScene {
|
||||
@@ -65,6 +66,11 @@ export class EntityComparer {
|
||||
* ```
|
||||
*/
|
||||
export class Entity {
|
||||
/**
|
||||
* Entity专用日志器
|
||||
*/
|
||||
private static _logger = createLogger('Entity');
|
||||
|
||||
/**
|
||||
* 实体比较器实例
|
||||
*/
|
||||
@@ -630,7 +636,7 @@ export class Entity {
|
||||
addedComponents.push(this.addComponent(component));
|
||||
} catch (error) {
|
||||
// 如果某个组件添加失败,继续添加其他组件
|
||||
console.warn(`添加组件失败 ${component.constructor.name}:`, error);
|
||||
Entity._logger.warn(`添加组件失败 ${component.constructor.name}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { EntitySystem } from '../Systems/EntitySystem';
|
||||
import { createLogger } from '../../Utils/Logger';
|
||||
|
||||
/**
|
||||
* 实体处理器列表管理器
|
||||
* 管理场景中的所有实体系统
|
||||
*/
|
||||
export class EntityProcessorList {
|
||||
private static readonly _logger = createLogger('EntityProcessorList');
|
||||
private _processors: EntitySystem[] = [];
|
||||
private _isDirty = false;
|
||||
|
||||
@@ -73,7 +75,7 @@ export class EntityProcessorList {
|
||||
try {
|
||||
processor.update();
|
||||
} catch (error) {
|
||||
console.error(`Error in processor ${processor.constructor.name}:`, error);
|
||||
EntityProcessorList._logger.error(`Error in processor ${processor.constructor.name}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user