rover over

This commit is contained in:
legop3
2026-07-12 01:36:30 -04:00
parent 09ce66e7a4
commit 76318e6b36
7 changed files with 26 additions and 15 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -78,7 +78,7 @@
<script defer src="https://analytics.otter.land/script.js" data-website-id="82dd56a5-db44-4279-bd1e-a4d9fee39af7" data-domains="rover.otter.land"></script>
<script defer src="https://analytics.otter.land/recorder.js" data-website-id="82dd56a5-db44-4279-bd1e-a4d9fee39af7" data-domains="rover.otter.land" data-sample-rate="0.15" data-mask-level="moderate" data-max-duration="300000"></script>
<title>Roomba Rover</title>
<script type="module" crossorigin src="/assets/index-YgdVe0Du.js"></script>
<script type="module" crossorigin src="/assets/index-CSIsAzyE.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-17XZRVBQ.css">
</head>
<body>
+19 -8
View File
@@ -632,6 +632,24 @@ function buildDockRequiredPayload(socket, leave) {
};
}
function releaseRoverOwnershipForPtz(socket) {
/*
PTZ operation must remove the browser from every rover-control state, not
only the roverManager driver set. The normal assignment UI is backed by
assignmentService, while low-level control membership is tracked inside
roverManager. In healthy flows those two agree, but reconnects, admin paths,
or earlier cleanup can leave only one side populated. Releasing the union
keeps PTZ from looking like a second simultaneous rover assignment.
*/
if (!socket?.id) return;
const roverIds = new Set(roverManager.getRoversForSocket(socket.id));
const assignedRoverId = assignmentService.getAssignedRover?.(socket.id);
if (assignedRoverId) roverIds.add(assignedRoverId);
roverIds.forEach((roverId) => {
assignmentService.forceRelease(roverId, socket.id);
});
}
function revokeOperator(reason = 'release') {
if (!state.operatorSocketId) return;
const previous = state.operatorSocketId;
@@ -646,14 +664,7 @@ function revokeOperator(reason = 'release') {
function activateOperator(socket) {
revokeOperator('handoff');
removeFromQueue(socket.id);
/*
PTZ operation is mutually exclusive with rover ownership. Releasing through
assignmentService preserves the existing queue/control cleanup rules instead
of directly mutating rover manager state.
*/
roverManager.getRoversForSocket(socket.id).forEach((roverId) => {
assignmentService.forceRelease(roverId, socket.id);
});
releaseRoverOwnershipForPtz(socket);
state.operatorSocketId = socket.id;
state.deadline = Date.now() + getTurnDurationMs();
turnTimer = setTimeout(handleTurnDeadline, getTurnDurationMs());