refactor(core): 移除@Inject参数装饰器,统一使用@InjectProperty (#229)
* refactor(core): 移除@Inject参数装饰器,统一使用@InjectProperty * refactor(core): 移除@Inject参数装饰器,统一使用@InjectProperty
This commit is contained in:
@@ -213,6 +213,7 @@ export class Core {
|
||||
);
|
||||
|
||||
this._debugManager = this._serviceContainer.resolve(DebugManager);
|
||||
this._debugManager.onInitialize();
|
||||
}
|
||||
|
||||
this.initialize();
|
||||
@@ -488,6 +489,7 @@ export class Core {
|
||||
);
|
||||
|
||||
this._instance._debugManager = this._instance._serviceContainer.resolve(DebugManager);
|
||||
this._instance._debugManager.onInitialize();
|
||||
}
|
||||
|
||||
// 更新Core配置
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 依赖注入装饰器
|
||||
*
|
||||
* 提供 @Injectable、@Inject 和 @Updatable 装饰器,用于标记可注入的类和依赖注入点
|
||||
* 提供 @Injectable、@InjectProperty 和 @Updatable 装饰器,用于标记可注入的类和依赖注入点
|
||||
*/
|
||||
|
||||
import type { ServiceContainer } from '../ServiceContainer';
|
||||
@@ -13,7 +13,6 @@ import type { IService, ServiceType } from '../ServiceContainer';
|
||||
type Constructor = abstract new (...args: unknown[]) => unknown;
|
||||
|
||||
const injectableMetadata = new WeakMap<Constructor, InjectableMetadata>();
|
||||
const injectMetadata = new WeakMap<Constructor, Map<number, ServiceType<IService> | string | symbol>>();
|
||||
const updatableMetadata = new WeakMap<Constructor, UpdatableMetadata>();
|
||||
|
||||
/**
|
||||
@@ -67,10 +66,11 @@ export interface UpdatableMetadata {
|
||||
*
|
||||
* @Injectable()
|
||||
* class PhysicsSystem extends EntitySystem {
|
||||
* constructor(
|
||||
* @Inject(TimeService) private timeService: TimeService
|
||||
* ) {
|
||||
* super();
|
||||
* @InjectProperty(TimeService)
|
||||
* private timeService!: TimeService;
|
||||
*
|
||||
* constructor() {
|
||||
* super(Matcher.empty());
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
@@ -135,27 +135,6 @@ export function Updatable(priority: number = 0): ClassDecorator {
|
||||
} as ClassDecorator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Inject() 装饰器
|
||||
*
|
||||
* 标记构造函数参数需要注入的服务类型
|
||||
*
|
||||
* @param serviceType 服务类型标识符
|
||||
*/
|
||||
export function Inject(serviceType: ServiceType<IService> | string | symbol): ParameterDecorator {
|
||||
return function (target: object, _propertyKey: string | symbol | undefined, parameterIndex: number) {
|
||||
// 获取或创建注入元数据
|
||||
let params = injectMetadata.get(target as Constructor);
|
||||
if (!params) {
|
||||
params = new Map();
|
||||
injectMetadata.set(target as Constructor, params);
|
||||
}
|
||||
|
||||
// 记录参数索引和服务类型的映射
|
||||
params.set(parameterIndex, serviceType);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @InjectProperty() 装饰器
|
||||
*
|
||||
@@ -164,6 +143,27 @@ export function Inject(serviceType: ServiceType<IService> | string | symbol): Pa
|
||||
* 注入时机:在构造函数执行后、onInitialize() 调用前完成
|
||||
*
|
||||
* @param serviceType 服务类型
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* @Injectable()
|
||||
* class PhysicsSystem extends EntitySystem {
|
||||
* @InjectProperty(TimeService)
|
||||
* private timeService!: TimeService;
|
||||
*
|
||||
* @InjectProperty(CollisionService)
|
||||
* private collision!: CollisionService;
|
||||
*
|
||||
* constructor() {
|
||||
* super(Matcher.empty());
|
||||
* }
|
||||
*
|
||||
* public onInitialize(): void {
|
||||
* // 此时属性已注入完成,可以安全使用
|
||||
* console.log(this.timeService.getDeltaTime());
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export function InjectProperty(serviceType: ServiceType<IService>): PropertyDecorator {
|
||||
return function (target: object, propertyKey: string | symbol) {
|
||||
@@ -207,13 +207,14 @@ export function getInjectableMetadata(target: Constructor): InjectableMetadata |
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取构造函数参数的注入元数据
|
||||
* 获取属性注入元数据
|
||||
*
|
||||
* @param target 目标类
|
||||
* @returns 参数索引到服务类型的映射
|
||||
* @returns 属性名到服务类型的映射
|
||||
*/
|
||||
export function getInjectMetadata(target: Constructor): Map<number, ServiceType<IService> | string | symbol> {
|
||||
return injectMetadata.get(target) || new Map();
|
||||
export function getPropertyInjectMetadata(target: Constructor): Map<string | symbol, ServiceType<IService>> {
|
||||
const metadata = injectableMetadata.get(target);
|
||||
return metadata?.properties || new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,38 +233,13 @@ export function createInstance<T>(
|
||||
constructor: new (...args: any[]) => T,
|
||||
container: ServiceContainer
|
||||
): T {
|
||||
// 获取参数注入元数据
|
||||
const injectParams = getInjectMetadata(constructor as Constructor);
|
||||
// 创建实例(无参数注入)
|
||||
const instance = new constructor();
|
||||
|
||||
// 解析依赖
|
||||
const dependencies: unknown[] = [];
|
||||
// 注入属性依赖
|
||||
injectProperties(instance as object, container);
|
||||
|
||||
// 获取构造函数参数数量
|
||||
const paramCount = constructor.length;
|
||||
|
||||
for (let i = 0; i < paramCount; i++) {
|
||||
const serviceType = injectParams.get(i);
|
||||
|
||||
if (serviceType) {
|
||||
// 如果有显式的@Inject标记,使用标记的类型
|
||||
if (typeof serviceType === 'string' || typeof serviceType === 'symbol') {
|
||||
// 字符串或Symbol类型的服务标识
|
||||
throw new Error(
|
||||
'String and Symbol service identifiers are not yet supported in constructor injection. ' +
|
||||
`Please use class types for ${constructor.name} parameter ${i}`
|
||||
);
|
||||
} else {
|
||||
// 类类型
|
||||
dependencies.push(container.resolve(serviceType as ServiceType<IService>));
|
||||
}
|
||||
} else {
|
||||
// 没有@Inject标记,传入undefined
|
||||
dependencies.push(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
// 创建实例
|
||||
return new constructor(...dependencies);
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
|
||||
export {
|
||||
Injectable,
|
||||
Inject,
|
||||
InjectProperty,
|
||||
Updatable,
|
||||
isInjectable,
|
||||
getInjectableMetadata,
|
||||
getInjectMetadata,
|
||||
getPropertyInjectMetadata,
|
||||
isUpdatable,
|
||||
getUpdatableMetadata,
|
||||
createInstance,
|
||||
|
||||
@@ -70,11 +70,14 @@ export interface SystemMetadata {
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // 配置更新顺序
|
||||
* // 配置更新顺序和依赖注入
|
||||
* @Injectable()
|
||||
* @ECSSystem('Physics', { updateOrder: 10 })
|
||||
* class PhysicsSystem extends EntitySystem {
|
||||
* constructor(@Inject(CollisionSystem) private collision: CollisionSystem) {
|
||||
* @InjectProperty(CollisionSystem)
|
||||
* private collision!: CollisionSystem;
|
||||
*
|
||||
* constructor() {
|
||||
* super(Matcher.empty().all(Transform, RigidBody));
|
||||
* }
|
||||
* }
|
||||
|
||||
@@ -612,7 +612,7 @@ export class Scene implements IScene {
|
||||
* 在场景中添加一个EntitySystem处理器
|
||||
*
|
||||
* 支持两种使用方式:
|
||||
* 1. 传入类型(推荐):自动使用DI创建实例,支持@Injectable和@Inject装饰器
|
||||
* 1. 传入类型(推荐):自动使用DI创建实例,支持@Injectable和@InjectProperty装饰器
|
||||
* 2. 传入实例:直接使用提供的实例
|
||||
*
|
||||
* @param systemTypeOrInstance 系统类型或系统实例
|
||||
@@ -623,7 +623,10 @@ export class Scene implements IScene {
|
||||
* // 方式1:传入类型,自动DI(推荐)
|
||||
* @Injectable()
|
||||
* class PhysicsSystem extends EntitySystem {
|
||||
* constructor(@Inject(CollisionSystem) private collision: CollisionSystem) {
|
||||
* @InjectProperty(CollisionSystem)
|
||||
* private collision!: CollisionSystem;
|
||||
*
|
||||
* constructor() {
|
||||
* super(Matcher.empty().all(Transform));
|
||||
* }
|
||||
* }
|
||||
@@ -718,7 +721,10 @@ export class Scene implements IScene {
|
||||
* @Injectable()
|
||||
* @ECSSystem('Physics', { updateOrder: 10 })
|
||||
* class PhysicsSystem extends EntitySystem implements IService {
|
||||
* constructor(@Inject(CollisionSystem) private collision: CollisionSystem) {
|
||||
* @InjectProperty(CollisionSystem)
|
||||
* private collision!: CollisionSystem;
|
||||
*
|
||||
* constructor() {
|
||||
* super(Matcher.empty().all(Transform, RigidBody));
|
||||
* }
|
||||
* dispose() {}
|
||||
@@ -779,7 +785,7 @@ export class Scene implements IScene {
|
||||
/**
|
||||
* 获取指定类型的EntitySystem处理器
|
||||
*
|
||||
* @deprecated 推荐使用依赖注入代替此方法。使用 `scene.services.resolve(SystemType)` 或在System构造函数中使用 `@Inject(SystemType)` 装饰器。
|
||||
* @deprecated 推荐使用依赖注入代替此方法。使用 `scene.services.resolve(SystemType)` 或使用 `@InjectProperty(SystemType)` 装饰器。
|
||||
*
|
||||
* @param type 处理器类型
|
||||
* @returns 处理器实例,如果未找到则返回null
|
||||
@@ -788,8 +794,11 @@ export class Scene implements IScene {
|
||||
* ```typescript
|
||||
* @Injectable()
|
||||
* class MySystem extends EntitySystem {
|
||||
* constructor(@Inject(PhysicsSystem) private physics: PhysicsSystem) {
|
||||
* super();
|
||||
* @InjectProperty(PhysicsSystem)
|
||||
* private physics!: PhysicsSystem;
|
||||
*
|
||||
* constructor() {
|
||||
* super(Matcher.empty());
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
|
||||
@@ -13,7 +13,7 @@ import type { IService } from '../../Core/ServiceContainer';
|
||||
import type { IUpdatable } from '../../Types/IUpdatable';
|
||||
import { SceneManager } from '../../ECS/SceneManager';
|
||||
import { PerformanceMonitor } from '../PerformanceMonitor';
|
||||
import { Injectable, Inject, Updatable } from '../../Core/DI/Decorators';
|
||||
import { Injectable, InjectProperty, Updatable } from '../../Core/DI/Decorators';
|
||||
import { DebugConfigService } from './DebugConfigService';
|
||||
|
||||
/**
|
||||
@@ -24,19 +24,26 @@ import { DebugConfigService } from './DebugConfigService';
|
||||
@Injectable()
|
||||
@Updatable()
|
||||
export class DebugManager implements IService, IUpdatable {
|
||||
private config: IECSDebugConfig;
|
||||
private webSocketManager: WebSocketManager;
|
||||
private entityCollector: EntityDataCollector;
|
||||
private systemCollector: SystemDataCollector;
|
||||
private performanceCollector: PerformanceDataCollector;
|
||||
private componentCollector: ComponentDataCollector;
|
||||
private sceneCollector: SceneDataCollector;
|
||||
private sceneManager: SceneManager;
|
||||
private performanceMonitor: PerformanceMonitor;
|
||||
private config!: IECSDebugConfig;
|
||||
private webSocketManager!: WebSocketManager;
|
||||
private entityCollector!: EntityDataCollector;
|
||||
private systemCollector!: SystemDataCollector;
|
||||
private performanceCollector!: PerformanceDataCollector;
|
||||
private componentCollector!: ComponentDataCollector;
|
||||
private sceneCollector!: SceneDataCollector;
|
||||
|
||||
@InjectProperty(SceneManager)
|
||||
private sceneManager!: SceneManager;
|
||||
|
||||
@InjectProperty(PerformanceMonitor)
|
||||
private performanceMonitor!: PerformanceMonitor;
|
||||
|
||||
@InjectProperty(DebugConfigService)
|
||||
private configService!: DebugConfigService;
|
||||
|
||||
private frameCounter: number = 0;
|
||||
private lastSendTime: number = 0;
|
||||
private sendInterval: number;
|
||||
private sendInterval: number = 0;
|
||||
private isRunning: boolean = false;
|
||||
private originalConsole = {
|
||||
log: console.log.bind(console),
|
||||
@@ -46,14 +53,8 @@ export class DebugManager implements IService, IUpdatable {
|
||||
error: console.error.bind(console)
|
||||
};
|
||||
|
||||
constructor(
|
||||
@Inject(SceneManager) sceneManager: SceneManager,
|
||||
@Inject(PerformanceMonitor) performanceMonitor: PerformanceMonitor,
|
||||
@Inject(DebugConfigService) configService: DebugConfigService
|
||||
) {
|
||||
this.config = configService.getConfig();
|
||||
this.sceneManager = sceneManager;
|
||||
this.performanceMonitor = performanceMonitor;
|
||||
public onInitialize(): void {
|
||||
this.config = this.configService.getConfig();
|
||||
|
||||
// 初始化数据收集器
|
||||
this.entityCollector = new EntityDataCollector();
|
||||
|
||||
@@ -19,12 +19,14 @@ export * from './Plugins';
|
||||
// 依赖注入
|
||||
export {
|
||||
Injectable,
|
||||
Inject,
|
||||
InjectProperty,
|
||||
Updatable,
|
||||
registerInjectable,
|
||||
createInstance,
|
||||
injectProperties,
|
||||
isUpdatable,
|
||||
getUpdatableMetadata
|
||||
getUpdatableMetadata,
|
||||
getPropertyInjectMetadata
|
||||
} from './Core/DI';
|
||||
export type { InjectableMetadata, UpdatableMetadata } from './Core/DI';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user