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.
130 lines
3.3 KiB
130 lines
3.3 KiB
// 工具类代理管理器
|
|
import LCCScript from '@/core/script/LCCScript.ts'
|
|
|
|
export default class ToolProxyManager {
|
|
// 存储所有活跃的 MessageChannel 端口
|
|
private activePorts = new WeakMap<Worker, MessagePort>()
|
|
|
|
/**
|
|
* 为 Worker 创建工具代理
|
|
*/
|
|
createToolProxyForWorker(worker: Worker): MessagePort {
|
|
// 创建 MessageChannel 用于通信
|
|
const channel = new MessageChannel()
|
|
|
|
// 存储 port2 用于后续通信
|
|
this.activePorts.set(worker, channel.port2)
|
|
|
|
// 设置 port2 的消息监听器
|
|
channel.port2.onmessage = (event) => {
|
|
this.handleWorkerCall(worker, event)
|
|
}
|
|
|
|
channel.port2.start()
|
|
|
|
// 返回 port1 供 Worker 使用
|
|
return channel.port1
|
|
}
|
|
|
|
/**
|
|
* 处理来自 Worker 的调用请求
|
|
*/
|
|
handleWorkerCall(worker: Worker, event: MessageEvent): void {
|
|
const { data } = event
|
|
if (data?.type !== 'call') return
|
|
|
|
const { tool, method, callId, args } = data
|
|
const port = this.activePorts.get(worker)
|
|
if (!port) {
|
|
console.error(`[ToolProxy] 找不到 worker 的端口`, worker)
|
|
return
|
|
}
|
|
|
|
// 获取主线程中的工具实例
|
|
const toolInstance = (window as any)[tool]
|
|
if (!toolInstance) {
|
|
console.error(`[ToolProxy] 工具未找到: ${tool}`)
|
|
port.postMessage({
|
|
type: 'error',
|
|
tool,
|
|
method,
|
|
callId,
|
|
error: {
|
|
name: 'ToolNotFound',
|
|
message: `${tool} is not available`
|
|
}
|
|
})
|
|
return
|
|
}
|
|
|
|
if (typeof toolInstance[method] !== 'function') {
|
|
console.error(`[ToolProxy] 方法未找到: ${tool}.${method}`)
|
|
port.postMessage({
|
|
type: 'error', tool, method, callId,
|
|
error: {
|
|
name: 'MethodNotFound',
|
|
message: `${tool}.${method} is not a function`
|
|
}
|
|
})
|
|
return
|
|
}
|
|
|
|
try {
|
|
// 执行工具方法
|
|
let result
|
|
if (toolInstance instanceof LCCScript && method === 'log') {
|
|
// 特殊处理 LCCScript 的 log 方法
|
|
result = toolInstance[method]('Script-' + worker['name'], ...args)
|
|
} else {
|
|
result = toolInstance[method](...args)
|
|
}
|
|
|
|
// 处理异步函数
|
|
if (result instanceof Promise) {
|
|
result.then(
|
|
resolved => {
|
|
port.postMessage({
|
|
type: 'result', tool, method, callId, result: resolved
|
|
})
|
|
},
|
|
error => {
|
|
port.postMessage({
|
|
type: 'error', tool, method, callId,
|
|
error: {
|
|
name: error.name || 'PromiseRejection',
|
|
message: error.message,
|
|
stack: error.stack
|
|
}
|
|
})
|
|
}
|
|
)
|
|
}
|
|
// 处理同步函数
|
|
else {
|
|
port.postMessage({ type: 'result', tool, method, callId, result })
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error(`[ToolProxy] 执行错误: ${tool}.${method}`, error)
|
|
port.postMessage({
|
|
type: 'error', tool, method, callId,
|
|
error: {
|
|
name: error.name || 'ExecutionError',
|
|
message: error.message,
|
|
stack: error.stack
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 清理 Worker 资源
|
|
*/
|
|
cleanupWorker(worker: Worker) {
|
|
const port = this.activePorts.get(worker)
|
|
if (port) {
|
|
port.close()
|
|
this.activePorts.delete(worker)
|
|
}
|
|
}
|
|
}
|
|
|