依赖注入引入DI容器
This commit is contained in:
@@ -39,34 +39,72 @@ export function ECSComponent(typeName: string) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* System元数据配置
|
||||
*/
|
||||
export interface SystemMetadata {
|
||||
/**
|
||||
* 更新顺序(数值越小越先执行,默认0)
|
||||
*/
|
||||
updateOrder?: number;
|
||||
|
||||
/**
|
||||
* 是否默认启用(默认true)
|
||||
*/
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统类型装饰器
|
||||
* 用于为系统类指定固定的类型名称,避免在代码混淆后失效
|
||||
*
|
||||
*
|
||||
* @param typeName 系统类型名称
|
||||
* @param metadata 系统元数据配置
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 基本使用
|
||||
* @ECSSystem('Movement')
|
||||
* class MovementSystem extends EntitySystem {
|
||||
* protected process(entities: Entity[]): void {
|
||||
* // 系统逻辑
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // 配置更新顺序
|
||||
* @Injectable()
|
||||
* @ECSSystem('Physics', { updateOrder: 10 })
|
||||
* class PhysicsSystem extends EntitySystem {
|
||||
* constructor(@Inject(CollisionSystem) private collision: CollisionSystem) {
|
||||
* super(Matcher.of(Transform, RigidBody));
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export function ECSSystem(typeName: string) {
|
||||
export function ECSSystem(typeName: string, metadata?: SystemMetadata) {
|
||||
return function <T extends new (...args: any[]) => EntitySystem>(target: T): T {
|
||||
if (!typeName || typeof typeName !== 'string') {
|
||||
throw new Error('ECSSystem装饰器必须提供有效的类型名称');
|
||||
}
|
||||
|
||||
|
||||
// 在构造函数上存储类型名称
|
||||
(target as any)[SYSTEM_TYPE_NAME] = typeName;
|
||||
|
||||
|
||||
// 存储元数据
|
||||
if (metadata) {
|
||||
(target as any).__systemMetadata__ = metadata;
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取System的元数据
|
||||
*/
|
||||
export function getSystemMetadata(systemType: new (...args: any[]) => EntitySystem): SystemMetadata | undefined {
|
||||
return (systemType as any).__systemMetadata__;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组件类型的名称,优先使用装饰器指定的名称
|
||||
*
|
||||
|
||||
@@ -5,6 +5,9 @@ export {
|
||||
getSystemTypeName,
|
||||
getComponentInstanceTypeName,
|
||||
getSystemInstanceTypeName,
|
||||
getSystemMetadata,
|
||||
COMPONENT_TYPE_NAME,
|
||||
SYSTEM_TYPE_NAME
|
||||
} from './TypeDecorators';
|
||||
} from './TypeDecorators';
|
||||
|
||||
export type { SystemMetadata } from './TypeDecorators';
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Entity } from './Entity';
|
||||
import { EntityList } from './Utils/EntityList';
|
||||
import { EntityProcessorList } from './Utils/EntityProcessorList';
|
||||
import { IdentifierPool } from './Utils/IdentifierPool';
|
||||
import { EntitySystem } from './Systems/EntitySystem';
|
||||
import { ComponentStorageManager } from './Core/ComponentStorage';
|
||||
@@ -41,12 +40,7 @@ export interface IScene {
|
||||
* 场景中的实体集合
|
||||
*/
|
||||
readonly entities: EntityList;
|
||||
|
||||
/**
|
||||
* 实体系统处理器集合
|
||||
*/
|
||||
readonly entityProcessors: EntityProcessorList;
|
||||
|
||||
|
||||
/**
|
||||
* 标识符池
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Entity } from './Entity';
|
||||
import { EntityList } from './Utils/EntityList';
|
||||
import { EntityProcessorList } from './Utils/EntityProcessorList';
|
||||
import { IdentifierPool } from './Utils/IdentifierPool';
|
||||
import { EntitySystem } from './Systems/EntitySystem';
|
||||
import { ComponentStorageManager, ComponentRegistry } from './Core/ComponentStorage';
|
||||
@@ -8,13 +7,17 @@ import { QuerySystem } from './Core/QuerySystem';
|
||||
import { TypeSafeEventSystem } from './Core/EventSystem';
|
||||
import { EventBus } from './Core/EventBus';
|
||||
import { IScene, ISceneConfig } from './IScene';
|
||||
import { getComponentInstanceTypeName, getSystemInstanceTypeName } from './Decorators';
|
||||
import { getComponentInstanceTypeName, getSystemInstanceTypeName, getSystemMetadata } from "./Decorators";
|
||||
import { TypedQueryBuilder } from './Core/Query/TypedQuery';
|
||||
import { SceneSerializer, SceneSerializationOptions, SceneDeserializationOptions } from './Serialization/SceneSerializer';
|
||||
import { IncrementalSerializer, IncrementalSnapshot, IncrementalSerializationOptions } from './Serialization/IncrementalSerializer';
|
||||
import { ComponentPoolManager } from './Core/ComponentPool';
|
||||
import { PerformanceMonitor } from '../Utils/PerformanceMonitor';
|
||||
import { Core } from '../Core';
|
||||
import { ServiceContainer, type ServiceType } from '../Core/ServiceContainer';
|
||||
import { createInstance, isInjectable } from '../Core/DI';
|
||||
import { isUpdatable, getUpdatableMetadata } from '../Core/DI/Decorators';
|
||||
import { createLogger } from '../Utils/Logger';
|
||||
|
||||
/**
|
||||
* 游戏场景默认实现类
|
||||
@@ -44,12 +47,6 @@ export class Scene implements IScene {
|
||||
*/
|
||||
public readonly entities: EntityList;
|
||||
|
||||
/**
|
||||
* 实体系统处理器集合
|
||||
*
|
||||
* 管理场景内所有实体系统的执行。
|
||||
*/
|
||||
public readonly entityProcessors: EntityProcessorList;
|
||||
|
||||
/**
|
||||
* 实体ID池
|
||||
@@ -74,36 +71,102 @@ export class Scene implements IScene {
|
||||
|
||||
/**
|
||||
* 事件系统
|
||||
*
|
||||
*
|
||||
* 类型安全的事件系统。
|
||||
*/
|
||||
public readonly eventSystem: TypeSafeEventSystem;
|
||||
|
||||
|
||||
/**
|
||||
* 服务容器
|
||||
*
|
||||
* 场景级别的依赖注入容器,用于管理EntitySystem和其他服务的生命周期。
|
||||
* 每个Scene拥有独立的服务容器,实现场景间的隔离。
|
||||
*/
|
||||
private readonly _services: ServiceContainer;
|
||||
|
||||
/**
|
||||
* 日志记录器
|
||||
*/
|
||||
private readonly logger: ReturnType<typeof createLogger>;
|
||||
|
||||
/**
|
||||
* 场景是否已开始运行
|
||||
*/
|
||||
private _didSceneBegin: boolean = false;
|
||||
|
||||
/**
|
||||
* 获取系统列表(兼容性属性)
|
||||
* 获取场景中所有已注册的EntitySystem
|
||||
*
|
||||
* 按updateOrder排序。
|
||||
*
|
||||
* @returns 系统列表
|
||||
*/
|
||||
public get systems(): EntitySystem[] {
|
||||
return this.entityProcessors.processors;
|
||||
// 从ServiceContainer获取所有EntitySystem实例
|
||||
const services = this._services.getAll();
|
||||
const systems: EntitySystem[] = [];
|
||||
|
||||
for (const service of services) {
|
||||
if (service instanceof EntitySystem) {
|
||||
systems.push(service);
|
||||
}
|
||||
}
|
||||
|
||||
// 按updateOrder排序
|
||||
systems.sort((a, b) => a.updateOrder - b.updateOrder);
|
||||
|
||||
return systems;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过类型获取System实例
|
||||
*
|
||||
* @param systemType System类型
|
||||
* @returns System实例,如果未找到则返回null
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const physics = scene.getSystem(PhysicsSystem);
|
||||
* if (physics) {
|
||||
* physics.doSomething();
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
public getSystem<T extends EntitySystem>(systemType: ServiceType<T>): T | null {
|
||||
return this._services.tryResolve(systemType) as T | null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取场景的服务容器
|
||||
*
|
||||
* 用于注册和解析场景级别的服务(如EntitySystem)。
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 注册服务
|
||||
* scene.services.registerSingleton(PhysicsSystem);
|
||||
*
|
||||
* // 解析服务
|
||||
* const physics = scene.services.resolve(PhysicsSystem);
|
||||
* ```
|
||||
*/
|
||||
public get services(): ServiceContainer {
|
||||
return this._services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建场景实例
|
||||
*/
|
||||
constructor(config?: ISceneConfig) {
|
||||
this.entities = new EntityList(this);
|
||||
this.entityProcessors = new EntityProcessorList();
|
||||
this.identifierPool = new IdentifierPool();
|
||||
this.componentStorageManager = new ComponentStorageManager();
|
||||
this.querySystem = new QuerySystem();
|
||||
this.eventSystem = new TypeSafeEventSystem();
|
||||
this._services = new ServiceContainer();
|
||||
this.logger = createLogger('Scene');
|
||||
|
||||
// 应用配置
|
||||
if (config?.name) {
|
||||
this.name = config.name;
|
||||
}
|
||||
@@ -111,7 +174,7 @@ export class Scene implements IScene {
|
||||
if (!Entity.eventBus) {
|
||||
Entity.eventBus = new EventBus(false);
|
||||
}
|
||||
|
||||
|
||||
if (Entity.eventBus) {
|
||||
Entity.eventBus.onComponentAdded((data: unknown) => {
|
||||
this.eventSystem.emitSync('component:added', data);
|
||||
@@ -149,10 +212,6 @@ export class Scene implements IScene {
|
||||
* 这个方法会启动场景。它将启动实体处理器等,并调用onStart方法。
|
||||
*/
|
||||
public begin() {
|
||||
// 启动实体处理器
|
||||
if (this.entityProcessors != null)
|
||||
this.entityProcessors.begin();
|
||||
|
||||
// 标记场景已开始运行并调用onStart方法
|
||||
this._didSceneBegin = true;
|
||||
this.onStart();
|
||||
@@ -176,9 +235,8 @@ export class Scene implements IScene {
|
||||
// 清空组件存储
|
||||
this.componentStorageManager.clear();
|
||||
|
||||
// 结束实体处理器
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.end();
|
||||
// 清空服务容器(会调用所有服务的dispose方法,包括所有EntitySystem)
|
||||
this._services.clear();
|
||||
|
||||
// 调用卸载方法
|
||||
this.unload();
|
||||
@@ -192,11 +250,28 @@ export class Scene implements IScene {
|
||||
|
||||
this.entities.updateLists();
|
||||
|
||||
if (this.entityProcessors != null)
|
||||
this.entityProcessors.update();
|
||||
// 更新所有EntitySystem
|
||||
const systems = this.systems;
|
||||
for (const system of systems) {
|
||||
if (system.enabled) {
|
||||
try {
|
||||
system.update();
|
||||
} catch (error) {
|
||||
this.logger.error(`Error in system ${system.constructor.name}.update():`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.entityProcessors != null)
|
||||
this.entityProcessors.lateUpdate();
|
||||
// LateUpdate
|
||||
for (const system of systems) {
|
||||
if (system.enabled) {
|
||||
try {
|
||||
system.lateUpdate();
|
||||
} catch (error) {
|
||||
this.logger.error(`Error in system ${system.constructor.name}.lateUpdate():`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,7 +291,7 @@ export class Scene implements IScene {
|
||||
* 当实体或组件发生变化时调用
|
||||
*/
|
||||
public clearSystemEntityCaches(): void {
|
||||
for (const system of this.entityProcessors.processors) {
|
||||
for (const system of this.systems) {
|
||||
system.clearEntityCache();
|
||||
}
|
||||
}
|
||||
@@ -419,23 +494,121 @@ export class Scene implements IScene {
|
||||
|
||||
/**
|
||||
* 在场景中添加一个EntitySystem处理器
|
||||
* @param processor 处理器
|
||||
*
|
||||
* 支持两种使用方式:
|
||||
* 1. 传入类型(推荐):自动使用DI创建实例,支持@Injectable和@Inject装饰器
|
||||
* 2. 传入实例:直接使用提供的实例
|
||||
*
|
||||
* @param systemTypeOrInstance 系统类型或系统实例
|
||||
* @returns 添加的处理器实例
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 方式1:传入类型,自动DI(推荐)
|
||||
* @Injectable()
|
||||
* class PhysicsSystem extends EntitySystem {
|
||||
* constructor(@Inject(CollisionSystem) private collision: CollisionSystem) {
|
||||
* super(Matcher.of(Transform));
|
||||
* }
|
||||
* }
|
||||
* scene.addEntityProcessor(PhysicsSystem);
|
||||
*
|
||||
* // 方式2:传入实例
|
||||
* const system = new MySystem();
|
||||
* scene.addEntityProcessor(system);
|
||||
* ```
|
||||
*/
|
||||
public addEntityProcessor(processor: EntitySystem) {
|
||||
if (this.entityProcessors.processors.includes(processor)) {
|
||||
return processor;
|
||||
public addEntityProcessor<T extends EntitySystem>(
|
||||
systemTypeOrInstance: ServiceType<T> | T
|
||||
): T {
|
||||
let system: T;
|
||||
let constructor: any;
|
||||
|
||||
if (typeof systemTypeOrInstance === 'function') {
|
||||
constructor = systemTypeOrInstance;
|
||||
|
||||
if (this._services.isRegistered(constructor)) {
|
||||
return this._services.resolve(constructor) as T;
|
||||
}
|
||||
|
||||
if (isInjectable(constructor)) {
|
||||
system = createInstance(constructor, this._services) as T;
|
||||
} else {
|
||||
system = new (constructor as any)() as T;
|
||||
}
|
||||
} else {
|
||||
system = systemTypeOrInstance;
|
||||
constructor = system.constructor;
|
||||
|
||||
if (this._services.isRegistered(constructor)) {
|
||||
return system;
|
||||
}
|
||||
}
|
||||
|
||||
processor.scene = this;
|
||||
system.scene = this;
|
||||
|
||||
// 从Core获取PerformanceMonitor并注入到System
|
||||
const perfMonitor = Core.services.resolve(PerformanceMonitor);
|
||||
processor.setPerformanceMonitor(perfMonitor);
|
||||
system.setPerformanceMonitor(perfMonitor);
|
||||
|
||||
this.entityProcessors.add(processor);
|
||||
processor.initialize();
|
||||
processor.setUpdateOrder(this.entityProcessors.count - 1);
|
||||
return processor;
|
||||
const metadata = getSystemMetadata(constructor);
|
||||
if (metadata?.updateOrder !== undefined) {
|
||||
system.setUpdateOrder(metadata.updateOrder);
|
||||
}
|
||||
if (metadata?.enabled !== undefined) {
|
||||
system.enabled = metadata.enabled;
|
||||
}
|
||||
|
||||
this._services.registerInstance(constructor, system);
|
||||
|
||||
system.initialize();
|
||||
|
||||
return system;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量注册EntitySystem到场景(使用DI)
|
||||
*
|
||||
* 自动按照依赖顺序注册多个System。
|
||||
* 所有System必须使用@Injectable装饰器标记。
|
||||
*
|
||||
* @param systemTypes System类型数组
|
||||
* @returns 注册的System实例数组
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* @Injectable()
|
||||
* @ECSSystem('Collision', { updateOrder: 5 })
|
||||
* class CollisionSystem extends EntitySystem implements IService {
|
||||
* constructor() { super(Matcher.of(Collider)); }
|
||||
* dispose() {}
|
||||
* }
|
||||
*
|
||||
* @Injectable()
|
||||
* @ECSSystem('Physics', { updateOrder: 10 })
|
||||
* class PhysicsSystem extends EntitySystem implements IService {
|
||||
* constructor(@Inject(CollisionSystem) private collision: CollisionSystem) {
|
||||
* super(Matcher.of(Transform, RigidBody));
|
||||
* }
|
||||
* dispose() {}
|
||||
* }
|
||||
*
|
||||
* // 批量注册(自动解析依赖顺序)
|
||||
* scene.registerSystems([
|
||||
* CollisionSystem,
|
||||
* PhysicsSystem, // 自动注入CollisionSystem
|
||||
* RenderSystem
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
public registerSystems(systemTypes: Array<ServiceType<EntitySystem>>): EntitySystem[] {
|
||||
const registeredSystems: EntitySystem[] = [];
|
||||
|
||||
for (const systemType of systemTypes) {
|
||||
const system = this.addEntityProcessor(systemType);
|
||||
registeredSystems.push(system);
|
||||
}
|
||||
|
||||
return registeredSystems;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -450,8 +623,13 @@ export class Scene implements IScene {
|
||||
* 从场景中删除EntitySystem处理器
|
||||
* @param processor 要删除的处理器
|
||||
*/
|
||||
public removeEntityProcessor(processor: EntitySystem) {
|
||||
this.entityProcessors.remove(processor);
|
||||
public removeEntityProcessor(processor: EntitySystem): void {
|
||||
const constructor = processor.constructor as any;
|
||||
|
||||
// 从ServiceContainer移除
|
||||
this._services.unregister(constructor);
|
||||
|
||||
// 重置System状态
|
||||
processor.reset();
|
||||
}
|
||||
|
||||
@@ -465,10 +643,24 @@ export class Scene implements IScene {
|
||||
|
||||
/**
|
||||
* 获取指定类型的EntitySystem处理器
|
||||
*
|
||||
* @deprecated 推荐使用依赖注入代替此方法。使用 `scene.services.resolve(SystemType)` 或在System构造函数中使用 `@Inject(SystemType)` 装饰器。
|
||||
*
|
||||
* @param type 处理器类型
|
||||
* @returns 处理器实例,如果未找到则返回null
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* @Injectable()
|
||||
* class MySystem extends EntitySystem {
|
||||
* constructor(@Inject(PhysicsSystem) private physics: PhysicsSystem) {
|
||||
* super();
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
public getEntityProcessor<T extends EntitySystem>(type: new (...args: unknown[]) => T): T | null {
|
||||
return this.entityProcessors.getProcessor(type);
|
||||
return this._services.tryResolve(type as any) as T | null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,7 +673,7 @@ export class Scene implements IScene {
|
||||
} {
|
||||
return {
|
||||
entityCount: this.entities.count,
|
||||
processorCount: this.entityProcessors.count,
|
||||
processorCount: this.systems.length,
|
||||
componentStorageStats: this.componentStorageManager.getAllStats()
|
||||
};
|
||||
}
|
||||
@@ -508,10 +700,11 @@ export class Scene implements IScene {
|
||||
}>;
|
||||
componentStats: Map<string, any>;
|
||||
} {
|
||||
const systems = this.systems;
|
||||
return {
|
||||
name: this.name || this.constructor.name,
|
||||
entityCount: this.entities.count,
|
||||
processorCount: this.entityProcessors.count,
|
||||
processorCount: systems.length,
|
||||
isRunning: this._didSceneBegin,
|
||||
entities: this.entities.buffer.map(entity => ({
|
||||
name: entity.name,
|
||||
@@ -519,7 +712,7 @@ export class Scene implements IScene {
|
||||
componentCount: entity.components.length,
|
||||
componentTypes: entity.components.map(c => getComponentInstanceTypeName(c))
|
||||
})),
|
||||
processors: this.entityProcessors.processors.map(processor => ({
|
||||
processors: systems.map(processor => ({
|
||||
name: getSystemInstanceTypeName(processor),
|
||||
updateOrder: processor.updateOrder,
|
||||
entityCount: (processor as any)._entities?.length || 0
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getSystemInstanceTypeName } from '../Decorators';
|
||||
import { createLogger } from '../../Utils/Logger';
|
||||
import type { EventListenerConfig, TypeSafeEventSystem, EventHandler } from '../Core/EventSystem';
|
||||
import type { ComponentConstructor, ComponentInstance } from '../../Types/TypeHelpers';
|
||||
import type { IService } from '../../Core/ServiceContainer';
|
||||
|
||||
/**
|
||||
* 事件监听器记录
|
||||
@@ -65,7 +66,7 @@ interface EventListenerRecord {
|
||||
*/
|
||||
export abstract class EntitySystem<
|
||||
TComponents extends readonly ComponentConstructor[] = []
|
||||
> implements ISystemBase {
|
||||
> implements ISystemBase, IService {
|
||||
private _updateOrder: number;
|
||||
private _enabled: boolean;
|
||||
private _performanceMonitor: PerformanceMonitor | null;
|
||||
@@ -222,9 +223,6 @@ export abstract class EntitySystem<
|
||||
*/
|
||||
public setUpdateOrder(order: number): void {
|
||||
this._updateOrder = order;
|
||||
if (this.scene && this.scene.entityProcessors) {
|
||||
this.scene.entityProcessors.setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -725,15 +723,43 @@ export abstract class EntitySystem<
|
||||
|
||||
/**
|
||||
* 当实体从系统中移除时调用
|
||||
*
|
||||
*
|
||||
* 子类可以重写此方法来处理实体移除事件。
|
||||
*
|
||||
*
|
||||
* @param entity 被移除的实体
|
||||
*/
|
||||
protected onRemoved(entity: Entity): void {
|
||||
// 子类可以重写此方法
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放系统资源
|
||||
*
|
||||
* 实现IService接口要求的dispose方法。
|
||||
* 当系统从Scene中移除或Scene销毁时调用。
|
||||
*
|
||||
* 默认行为:
|
||||
* - 移除所有事件监听器
|
||||
* - 清空所有缓存
|
||||
* - 重置初始化状态
|
||||
*
|
||||
* 子类可以重写此方法来清理自定义资源,但应该调用super.dispose()。
|
||||
*/
|
||||
public dispose(): void {
|
||||
// 移除所有事件监听器
|
||||
this.cleanupManualEventListeners();
|
||||
|
||||
// 清空所有缓存
|
||||
this._entityCache.clearAll();
|
||||
this._entityIdMap = null;
|
||||
|
||||
// 重置状态
|
||||
this._initialized = false;
|
||||
this._scene = null;
|
||||
|
||||
this.logger.debug(`System ${this._systemName} disposed`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加事件监听器
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user