doc: 注释
This commit is contained in:
parent
1b8e2df145
commit
80583a526d
@ -73,7 +73,9 @@ const applicationState = {
|
||||
let mapCanvas; // 主渲染画布 DOM 元素
|
||||
let canvasCtx; // 2D 渲染上下文
|
||||
|
||||
// 保存当前动画帧 ID,组件卸载时用于停止 Canvas 渲染循环。
|
||||
let animationFrameId;
|
||||
// 地图请求版本号:当多个地图请求并发时,只允许最后一次请求更新画布。
|
||||
let mapLoadVersion = 0;
|
||||
|
||||
const init = () => {
|
||||
@ -352,24 +354,39 @@ const centerCanvasView = () => {
|
||||
inspectionStore.camera.centerY = (map.originY + map.maxY) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从机器人列表中选出地图数据来源。
|
||||
* 当前沿用原有规则:使用第一台已连接的机器人获取地图。
|
||||
*/
|
||||
const getConnectedRobot = (robotList = props.robotList) => {
|
||||
return robotList.find(item => item?.connectStatus == 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成地图来源的稳定标识。
|
||||
* 机器人轮询时位置等字段会不断变化,但机器人 ID 和地图名称不变,
|
||||
* 因此监听该标识可以避免位置更新触发底图重新加载。
|
||||
*/
|
||||
const getMapIdentity = (robotList = props.robotList) => {
|
||||
const robot = getConnectedRobot(robotList)
|
||||
return robot ? `${robot.id ?? ''}:${robot.robotMapName ?? ''}` : ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求并加载机器人当前使用的地图。
|
||||
* @param {Object} connectedRobot 用于提供地图的已连接机器人
|
||||
*/
|
||||
const loadSourceMap = async (connectedRobot = getConnectedRobot()) => {
|
||||
if (!connectedRobot) return;
|
||||
|
||||
// 记录本次请求版本。若等待响应期间又发起了新请求,则丢弃本次旧结果。
|
||||
const currentLoadVersion = ++mapLoadVersion;
|
||||
|
||||
const res = await getMapJson({
|
||||
robotId: connectedRobot.id,
|
||||
mapName: connectedRobot.robotMapName
|
||||
});
|
||||
// 防止较慢返回的旧地图覆盖用户刚切换的新地图。
|
||||
if (currentLoadVersion !== mapLoadVersion) return;
|
||||
if (res.code === 200) {
|
||||
try {
|
||||
@ -382,6 +399,10 @@ const loadSourceMap = async (connectedRobot = getConnectedRobot()) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 将接口返回的 "x,y,angle" 字符串转换为数值坐标。
|
||||
* 无位置或包含非法数值时返回 null,避免无效机器人进入绘制列表。
|
||||
*/
|
||||
const parseRobotPosition = (currentPosition) => {
|
||||
if (!currentPosition) return null
|
||||
const values = String(currentPosition).split(',').map(Number)
|
||||
@ -389,7 +410,15 @@ const parseRobotPosition = (currentPosition) => {
|
||||
return values
|
||||
}
|
||||
|
||||
/**
|
||||
* 将最新机器人列表同步到 Canvas 使用的机器人实例中。
|
||||
*
|
||||
* 已存在的机器人会复用原 MobileRobot 实例,仅修改位置和名称;新增机器人
|
||||
* 创建实例,接口中已移除或没有有效位置的机器人不会进入 nextRobots。
|
||||
* 该函数不会加载地图或重置相机,因此可安全用于高频轮询。
|
||||
*/
|
||||
const syncRobots = (robotList) => {
|
||||
// 用 ID 建立索引,避免为每台机器人遍历整个旧列表。
|
||||
const previousRobots = new Map(applicationState.robots.map(robot => [robot.id, robot]));
|
||||
const nextRobots = [];
|
||||
|
||||
@ -400,6 +429,7 @@ const syncRobots = (robotList) => {
|
||||
const [x, y, angle] = position
|
||||
const robot = previousRobots.get(item.id)
|
||||
if (robot) {
|
||||
// 保留原实例和颜色,只更新轮询产生的动态信息。
|
||||
robot.name = item.robotName
|
||||
robot.x = x
|
||||
robot.y = y
|
||||
@ -408,6 +438,7 @@ const syncRobots = (robotList) => {
|
||||
return
|
||||
}
|
||||
|
||||
// 列表中首次出现的机器人需要创建绘制实例并分配颜色。
|
||||
nextRobots.push(new MobileRobot(
|
||||
item.id,
|
||||
item.robotName,
|
||||
@ -418,6 +449,7 @@ const syncRobots = (robotList) => {
|
||||
))
|
||||
})
|
||||
|
||||
// 整体替换绘制列表,同时自然移除本轮接口中不存在的机器人。
|
||||
applicationState.robots = nextRobots
|
||||
}
|
||||
|
||||
@ -451,6 +483,7 @@ defineExpose({
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', resizeCanvasToContainer)
|
||||
// 停止渲染循环,并使仍在进行中的地图请求全部失效。
|
||||
cancelAnimationFrame(animationFrameId)
|
||||
mapLoadVersion += 1
|
||||
canvasCtx = null
|
||||
|
||||
Loading…
Reference in New Issue
Block a user