You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
2.4 KiB
71 lines
2.4 KiB
/** System 接口:按 priority 排序,由 SystemRegistry 统一调度 tick(无业务依赖) */
|
|
export interface ISystem {
|
|
/** 调度优先级(越小越先 tick) */
|
|
readonly priority: number;
|
|
/** 是否启用(false 跳过 tick) */
|
|
enabled: boolean;
|
|
/** 每帧更新 */
|
|
tick(dt: number): void;
|
|
}
|
|
|
|
/** System 构造器类型(不强制构造参数,由具体 system 自行声明依赖) */
|
|
export type ISystemCtor<T extends ISystem> = new (...args: any[]) => T;
|
|
|
|
/** System 注册与调度表 */
|
|
export class SystemRegistry {
|
|
private readonly _systems: ISystem[] = [];
|
|
private _sorted: ISystem[] | null = null;
|
|
|
|
/** 注册 system */
|
|
register<T extends ISystem>(system: T): T {
|
|
this._systems.push(system);
|
|
this._sorted = null;
|
|
return system;
|
|
}
|
|
|
|
/** 按类型取已注册 system */
|
|
get<T extends ISystem>(ctor: ISystemCtor<T>): T | undefined {
|
|
return this._systems.find((s) => s instanceof ctor) as T | undefined;
|
|
}
|
|
|
|
/** 按 priority 升序依次 tick(enabled=false 跳过)。单个 system 抛错不打断后续(含出怪) */
|
|
tick(dt: number): void {
|
|
if (!this._sorted) {
|
|
this._sorted = [...this._systems].sort((a, b) => a.priority - b.priority);
|
|
}
|
|
for (const s of this._sorted) {
|
|
this._tickOne(s, dt);
|
|
}
|
|
}
|
|
|
|
/** 按 slice 轮询 system:非当前 slice 的系统本帧不 tick,dt 按 slice 补偿 */
|
|
tickSlice(dt: number, sliceIndex: number, sliceCount: number): void {
|
|
if (sliceCount <= 1) {
|
|
this.tick(dt);
|
|
return;
|
|
}
|
|
if (!this._sorted) {
|
|
this._sorted = [...this._systems].sort((a, b) => a.priority - b.priority);
|
|
}
|
|
const compensated = dt * sliceCount;
|
|
for (let i = 0; i < this._sorted.length; i++) {
|
|
if (i % sliceCount !== sliceIndex) continue;
|
|
this._tickOne(this._sorted[i], compensated);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 单系统 tick。异常只打日志,避免技能/Buff 抛错吞掉同帧后面的 WaveSpawner。
|
|
* @param system 系统
|
|
* @param dt 本拍步长(秒)
|
|
*/
|
|
private _tickOne(system: ISystem, dt: number): void {
|
|
if (!system.enabled) return;
|
|
try {
|
|
system.tick(dt);
|
|
} catch (err) {
|
|
const name = system.constructor?.name ?? 'system';
|
|
console.error('[SystemRegistry] tick', name, err);
|
|
}
|
|
}
|
|
}
|
|
|