支持wx/browser的worker(由于wx限制默认不开启worker)

This commit is contained in:
YHH
2025-09-29 13:21:08 +08:00
parent be11060674
commit 62bc6b547e
10 changed files with 1545 additions and 31 deletions

View File

@@ -4,6 +4,8 @@ import { Matcher } from '../Utils/Matcher';
import { Time } from '../../Utils/Time';
import { createLogger } from '../../Utils/Logger';
import type { IComponent } from '../../Types';
import { PlatformManager } from '../../Platform/PlatformManager';
import type { IPlatformAdapter, PlatformWorker } from '../../Platform/IPlatformAdapter';
/**
* Worker处理函数类型
@@ -191,14 +193,18 @@ export abstract class WorkerEntitySystem<TEntityData = any> extends EntitySystem
systemConfig?: any;
entitiesPerWorker?: number;
};
private workerPool: WebWorkerPool | null = null;
private workerPool: PlatformWorkerPool | null = null;
private isProcessing = false;
protected sharedBuffer: SharedArrayBuffer | null = null;
protected sharedFloatArray: Float32Array | null = null;
private platformAdapter: IPlatformAdapter;
constructor(matcher?: Matcher, config: WorkerSystemConfig = {}) {
super(matcher);
// 获取平台适配器
this.platformAdapter = PlatformManager.getInstance().getAdapter();
// 验证和调整 worker 数量,确保不超过系统最大值
const requestedWorkerCount = config.workerCount ?? this.getMaxSystemWorkerCount();
const maxSystemWorkerCount = this.getMaxSystemWorkerCount();
@@ -233,25 +239,22 @@ export abstract class WorkerEntitySystem<TEntityData = any> extends EntitySystem
* 检查是否支持Worker
*/
private isWorkerSupported(): boolean {
return typeof Worker !== 'undefined' && typeof Blob !== 'undefined';
return this.platformAdapter.isWorkerSupported();
}
/**
* 检查是否支持SharedArrayBuffer
*/
private isSharedArrayBufferSupported(): boolean {
return typeof SharedArrayBuffer !== 'undefined' && self.crossOriginIsolated;
return this.platformAdapter.isSharedArrayBufferSupported();
}
/**
* 获取系统支持的最大Worker数量
*/
private getMaxSystemWorkerCount(): number {
if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) {
// 使用全部CPU核心数作为最大限制
return navigator.hardwareConcurrency;
}
return 4; // 降级默认值
const platformConfig = this.platformAdapter.getPlatformConfig();
return platformConfig.maxWorkerCount;
}
/**
@@ -267,7 +270,7 @@ export abstract class WorkerEntitySystem<TEntityData = any> extends EntitySystem
try {
// 检查是否支持SharedArrayBuffer
if (!this.isSharedArrayBufferSupported()) {
this.logger.warn(`${this.systemName}: 不支持SharedArrayBuffer降级到单Worker模式以保证数据处理完整性`);
this.logger.warn(`${this.systemName}: 平台不支持SharedArrayBuffer降级到单Worker模式以保证数据处理完整性`);
this.config.useSharedArrayBuffer = false;
// 降级到单Worker模式确保所有实体在同一个Worker中处理维持实体间交互的完整性
this.config.workerCount = 1;
@@ -277,8 +280,10 @@ export abstract class WorkerEntitySystem<TEntityData = any> extends EntitySystem
// 使用配置的实体数据大小和最大实体数量
// 预分配缓冲区maxEntities * entityDataSize * 4字节
const bufferSize = this.config.maxEntities * this.config.entityDataSize * 4;
this.sharedBuffer = new SharedArrayBuffer(bufferSize);
this.sharedFloatArray = new Float32Array(this.sharedBuffer);
this.sharedBuffer = this.platformAdapter.createSharedArrayBuffer(bufferSize);
if (this.sharedBuffer) {
this.sharedFloatArray = new Float32Array(this.sharedBuffer);
}
this.logger.info(`${this.systemName}: SharedArrayBuffer初始化成功 (${bufferSize} 字节)`);
} catch (error) {
@@ -296,9 +301,26 @@ export abstract class WorkerEntitySystem<TEntityData = any> extends EntitySystem
private initializeWorkerPool(): void {
try {
const script = this.createWorkerScript();
this.workerPool = new WebWorkerPool(
this.config.workerCount,
script,
// 在WorkerEntitySystem中处理平台相关逻辑
const workers: PlatformWorker[] = [];
const platformConfig = this.platformAdapter.getPlatformConfig();
const fullScript = (platformConfig.workerScriptPrefix || '') + script;
for (let i = 0; i < this.config.workerCount; i++) {
try {
const worker = this.platformAdapter.createWorker(fullScript, {
name: `WorkerEntitySystem-${i}`
});
workers.push(worker);
} catch (error) {
this.logger.error(`创建Worker ${i} 失败:`, error);
throw error;
}
}
this.workerPool = new PlatformWorkerPool(
workers,
this.sharedBuffer // 传递SharedArrayBuffer给Worker池
);
} catch (error) {
@@ -832,10 +854,10 @@ export abstract class WorkerEntitySystem<TEntityData = any> extends EntitySystem
}
/**
* Web Worker池管理器
* 平台适配的Worker池管理器
*/
class WebWorkerPool {
private workers: Worker[] = [];
class PlatformWorkerPool {
private workers: PlatformWorker[] = [];
private taskQueue: Array<{
id: string;
data: any;
@@ -845,18 +867,22 @@ class WebWorkerPool {
private busyWorkers = new Set<number>();
private taskCounter = 0;
private sharedBuffer: SharedArrayBuffer | null = null;
private readonly logger = createLogger('PlatformWorkerPool');
constructor(workerCount: number, script: string, sharedBuffer?: SharedArrayBuffer | null) {
this.sharedBuffer = sharedBuffer || null;
constructor(
workers: PlatformWorker[],
sharedBuffer: SharedArrayBuffer | null = null
) {
this.sharedBuffer = sharedBuffer;
this.workers = workers;
const blob = new Blob([script], { type: 'application/javascript' });
const scriptURL = URL.createObjectURL(blob);
// 为每个Worker设置消息处理器
for (let i = 0; i < workers.length; i++) {
const worker = workers[i];
for (let i = 0; i < workerCount; i++) {
const worker = new Worker(scriptURL);
worker.onmessage = (e) => this.handleWorkerMessage(i, e.data);
worker.onerror = (error) => this.handleWorkerError(i, error);
// 设置消息处理器
worker.onMessage((event) => this.handleWorkerMessage(i, event.data));
worker.onError((error) => this.handleWorkerError(i, error));
// 如果有SharedArrayBuffer发送给Worker
if (sharedBuffer) {
@@ -865,11 +891,7 @@ class WebWorkerPool {
sharedBuffer: sharedBuffer
});
}
this.workers.push(worker);
}
URL.revokeObjectURL(scriptURL);
}
/**