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