Browse Source

CL2 demo

master
修宁 5 months ago
parent
commit
e02622c90f
  1. 2
      src/core/manager/EnvManager.ts
  2. 5
      src/core/script/LCCScript.ts
  3. 245
      src/core/script/ModelManager.ts
  4. 19
      src/types/LCC.d.ts

2
src/core/manager/EnvManager.ts

@ -128,7 +128,7 @@ export default class EnvManager {
return return
} }
const invRes = await LCC.loadInv() const invRes = await LCC.queryInv({})
if (!invRes.success) { if (!invRes.success) {
return return
} }

5
src/core/script/LCCScript.ts

@ -57,8 +57,9 @@ export default class LCCScript implements LCC {
} }
// 从后台读取所有库存 // 从后台读取所有库存
async loadInv(): Promise<ServerResponse<InvVo[]>> { async queryInv(option: InvQueryCondition = {}): Promise<ServerResponse<InvVo[]>> {
return Request.request.post('/api/workbench/InvController@loadInv', { return Request.request.post('/api/workbench/InvController@queryInv', {
...option,
projectUUID: worldModel.state.project_uuid, projectUUID: worldModel.state.project_uuid,
catalogCode: worldModel.state.catalogCode, catalogCode: worldModel.state.catalogCode,
envId: worldModel.state.runState.currentEnvId envId: worldModel.state.runState.currentEnvId

245
src/core/script/ModelManager.ts

@ -195,249 +195,4 @@ this.viewport.stateManager.update(({ getEntity, putEntity, addEntity }) => {
system.showInfoDialog(content) system.showInfoDialog(content)
} }
} }
// 脚本与 Worker 的映射,用于快速查找
private scriptWorkers = new WeakMap<CustomScript, Worker>()
private toolProxyManager = new ToolProxyManager()
/**
* 线
*/
async runScript(script: CustomScript) {
// 检查脚本是否已在运行
if (script.isRunning) {
console.warn(`脚本 "${script.name}" 已在运行中`)
return
}
try {
// 创建 Blob URL 作为 Worker 执行内容
const jsCode = await compileTypeScript(script.content)
const wrappedContent = `
// Worker 端工具代理
// 创建代理对象
const createToolProxy = (port) => {
return new Proxy({}, {
get(_, toolName) {
return new Proxy({}, {
get(_, methodName) {
return (...args) => {
return new Promise((resolve, reject) => {
const callId = Math.random().toString(36).substr(2, 10);
// 发送调用请求
port.postMessage({
type: 'call',
tool: toolName,
method: methodName,
callId,
args
});
// 监听响应
const responseHandler = (event) => {
const { data } = event;
if (data.callId === callId) {
console.log('[Worker] 收到响应: ' + toolName + '.' + methodName, data.type);
port.removeEventListener('message', responseHandler);
if (data.type === 'result') {
resolve(data.result);
} else if (data.type === 'error') {
const err = new Error(data.error.message);
err.name = data.error.name;
err.stack = data.error.stack;
reject(err);
}
}
};
port.addEventListener('message', responseHandler);
});
};
}
});
}
});
};
// 创建代理对象
const tools = new Proxy({}, toolProxyHandler);
self.onmessage = function(__initMessage) {
if (__initMessage.data.type === 'init') {
// 设置通信端口
self.port = __initMessage.data.port;
self.port.onmessage = function(event) {
const { type, callId, result, error } = event.data;
if (!self.pendingCalls || !self.pendingCalls[callId]) return;
const { resolve, reject } = self.pendingCalls[callId];
delete self.pendingCalls[callId];
if (type === 'result') {
resolve(result);
} else if (type === 'error') {
const err = new Error(error.message);
err.name = error.name;
err.stack = error.stack;
reject(err);
}
};
self.port.start();
// 解构代理工具
const { LCC, RCS } = tools;
try {
(async function() {
// ---------------------custom script start---------------------[
${jsCode}
// ]---------------------custom script end---------------------
})().then(() => {
self.postMessage({ type: 'completed' })
}).catch(error => {
// 捕获异步错误
self.postMessage({
type: 'error',
error: {
name: error.name,
message: error.message,
stack: error.stack
}
})
})
} catch (error) {
// 捕获脚本错误
self.postMessage({
type: 'error',
error: {
name: error.name,
message: error.message,
stack: error.stack
}
})
} finally {
// 确保关闭 worker
self.close()
}
}
}
`
// console.log(wrappedContent)
const blob = new Blob([wrappedContent], { type: 'application/javascript' })
const blobUrl = URL.createObjectURL(blob)
const worker = new Worker(blobUrl)
// 创建代理并初始化 Worker
const port = this.toolProxyManager.createToolProxyForWorker(worker)
// 存储 Worker 引用并更新状态
this.scriptWorkers.set(script, worker)
script.worker = markRaw(worker)
script.isRunning = true
URL.revokeObjectURL(blobUrl) // 清理不再需要的 Blob URL
// 设置 Worker 事件监听器
worker.onmessage = (e) => this.handleWorkerMessage(script, e)
worker.onerror = (e) => this.handleWorkerError(script, e)
worker.onmessageerror = (e) => this.handleMessageError(script, e)
console.log(`[ScriptRunner] 创建 Worker 并启动脚本 "${script.name}"`)
worker.postMessage({
type: 'init',
port: port
}, [port])
console.log(`[ScriptRunner] 初始化消息已发送给 Worker`)
} catch (error) {
console.error(`启动脚本 "${script.name}" 失败:`, error)
script.isRunning = false
}
}
/**
*
*/
stopScript(script: CustomScript) {
this.cleanupScript(script, '手动停止')
}
/**
* Worker
*/
private handleWorkerMessage(script: CustomScript, event: MessageEvent): void {
const { data } = event
if (data?.type === 'call') {
// 处理来自 Worker 的工具调用请求
this.toolProxyManager.handleWorkerCall(script.worker, event)
return
}
if (data?.type === 'completed') {
// 脚本自然完成
console.log(`脚本 "${script.name}" 执行完成`)
this.cleanupScript(script, '执行完成')
return
}
if (data?.type === 'error') {
// 脚本内部错误
const error = new Error(data.error.message)
error.name = data.error.name
error.stack = data.error.stack
console.error(`[${script.name}] 执行错误:`, error)
this.cleanupScript(script, '执行错误')
return
}
// 常规消息处理
console.log(`[${script.name}] 收到消息:`, data)
debugger
}
/**
* Worker
*/
private handleWorkerError(script: CustomScript, event: ErrorEvent): void {
console.error(`[${script.name}] 发生错误:`, event.message, `@${event.filename}:${event.lineno}`)
this.cleanupScript(script, '运行时错误')
}
/**
*
*/
private handleMessageError(script: CustomScript, event: MessageEvent): void {
console.error(`[${script.name}] 消息解析错误:`, event)
this.cleanupScript(script, '消息错误')
}
/**
*
*/
private cleanupScript(script: CustomScript, reason: string): void {
if (!script.isRunning || !script.worker) return
try {
// 清理代理管理器中的资源
this.toolProxyManager.cleanupWorker(script.worker)
// 终止 Worker
script.worker.terminate()
this.scriptWorkers.delete(script)
script.worker = undefined
script.isRunning = false
console.log(`脚本 "${script.name}" 已停止 (原因: ${reason})`)
} catch (error) {
console.error(`清理脚本 "${script.name}" 资源失败:`, error)
}
}
} }

19
src/types/LCC.d.ts

@ -16,7 +16,7 @@ declare interface LCC {
/** /**
* , Model * , Model
*/ */
loadInv(): Promise<ServerResponse<InvVo[]>> queryInv(option: InvQueryCondition = {}): Promise<ServerResponse<InvVo[]>>
/** /**
* *
@ -102,6 +102,18 @@ type InvUpdateFn = (type: BackendTopicType, topic: string, body: InvUpdateVo) =>
type StopSubscribe = () => void type StopSubscribe = () => void
interface InvQueryCondition {
lpn?: string
locCode?: string
wayPoint?: string
wayDirection?: LLCDirection
catalogCode?: string
rack?: string
bay?: number
level?: number
cell?: number
}
interface ServerAuthorizationConfigVo { interface ServerAuthorizationConfigVo {
/** /**
* *
@ -270,6 +282,11 @@ interface InvVo {
bay: number bay: number
level: number level: number
cell: number cell: number
way_point: string
loc_direction: LLCDirection
catalog_code: string
is_lock: boolean
is_frozen: boolean
} }
interface ExecutorVo { interface ExecutorVo {

Loading…
Cancel
Save