8000 Stream works, disconnect broken · arduino/ArduinoCore-mbed@815151d · GitHub
[go: up one dir, main page]

Skip to content

Commit 815151d

Browse files
committed
Stream works, disconnect broken
1 parent e2e949b commit 815151d

File tree

1 file changed

+67
-49
lines changed

1 file changed

+67
-49
lines changed

libraries/Camera/extras/WebSerialCamera/serialConnectionHandler.js

Lines changed: 67 additions & 49 deletions
< 8000 td data-grid-cell-id="diff-bf28ead0c7931c8586c19e4939bdb9b9bd96968c7f6444e58609b3d8b0856ee1-150-165-2" data-line-anchor="diff-bf28ead0c7931c8586c19e4939bdb9b9bd96968c7f6444e58609b3d8b0856ee1L150" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-deletionLine-bgColor, var(--diffBlob-deletion-bgColor-line));padding-right:24px" tabindex="-1" valign="top" class="focusable-grid-cell diff-text-cell left-side-diff-cell border-right left-side">-
const { value, done } = await reader.read();
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
11
const ArduinoUSBVendorId = 0x2341;
22
const UserActionAbortError = 8;
33

4+
class BytesWaitTransformer {
5+
constructor(waitBytes) {
6+
this.waitBytes = waitBytes;
7+
this.buffer = new Uint8Array(0);
8+
this.controller = undefined;
9+
}
10+
11+
async transform(chunk, controller) {
12+
this.controller = controller;
13+
14+
// Concatenate incoming chunk with existing buffer
15+
this.buffer = new Uint8Array([...this.buffer, ...chunk]);
16+
17+
while (this.buffer.length >= this.waitBytes) {
18+
// Extract the required number of bytes
19+
const bytesToProcess = this.buffer.slice(0, this.waitBytes);
20+
21+
// Remove processed bytes from the buffer
22+
this.buffer = this.buffer.slice(this.waitBytes);
23+
24+
// Notify the controller that bytes have been processed
25+
controller.enqueue(bytesToProcess);
26+
}
27+
}
28+
29+
flush(controller) {
30+
if (this.buffer.length > 0) {
31+
// Handle remaining bytes (if any) when the stream is closed
32+
const remainingBytes = this.buffer.slice();
33+
console.log("Remaining bytes:", remainingBytes);
34+
35+
// Notify the controller that remaining bytes have been processed
36+
controller.enqueue(remainingBytes);
37+
}
38+
}
39+
}
40+
441
/**
542
* Handles the connection between the browser and the Arduino board via Web Serial.
643
*/
@@ -120,61 +157,42 @@ class SerialConnectionHandler {
120157
* If the timeout is reached, the reader will be canceled and the read lock will be released.
121158
*/
122159
async readBytes(numBytes, timeout = null) {
123-
if (this.currentPort.readable.locked) {
160+
if(!this.currentPort) return null;
161+
if(this.currentPort.readable.locked) {
124162
console.log('🔒 Stream is already locked. Ignoring request...');
125163
return null;
126164
}
127165

128-
const bytesRead = new Uint8Array(numBytes);
129-
let bytesReadIdx = 0;
130-
let keepReading = true;
131-
132-
// As long as the errors are non-fatal, a new ReadableStream is created automatically and hence port.readable is non-null.
133-
// If a fatal error occurs, such as the serial device being removed, then port.readable becomes null.
134-
135-
while (this.currentPort?.readable && keepReading) {
136-
const reader = this.currentPort.readable.getReader();
137-
this.currentReader = reader;
138-
let timeoutID = null;
139-
// let count = 0;
140-
141-
try {
142-
while (bytesReadIdx < numBytes) {
143-
if (timeout) {
144-
timeoutID = setTimeout(() => {
145-
console.log('⌛️ Timeout occurred while reading.');
146-
if (this.currentPort?.readable) reader?.cancel();
147-
}, timeout);
148-
}
149-
150
151-
if (timeoutID) clearTimeout(timeoutID);
152-
153-
if (value) {
154-
for (const byte of value) {
155-
bytesRead[bytesReadIdx++] = byte;
156-
if (bytesReadIdx >= numBytes) break;
157-
}
158-
// count += value.byteLength;
159-
// console.log(`Read ${value.byteLength} (Total: ${count}) out of ${numBytes} bytes.}`);
160-
}
161-
162-
if (done) {
163-
console.log('🚫 Reader has been canceled');
164-
break;
165-
}
166-
}
167-
168-
} catch (error) {
169-
console.error('💣 Error occurred while reading: ' + error.message);
170-
} finally {
171-
keepReading = false;
172-
// console.log('🔓 Releasing reader lock...');
173-
reader?.releaseLock();
174-
this.currentReader = null;
166+
const transformer = new BytesWaitTransformer(numBytes);
167+
const transformStream = new TransformStream(transformer);
168+
const pipedStream = this.currentPort.readable.pipeThrough(transformStream);
169+
const reader = pipedStream.getReader();
170+
this.currentReader = reader;
171+
let timeoutID = null;
172+
173+
try {
174+
if (timeout) {
175+
timeoutID = setTimeout(() => {
176+
console.log('⌛️ Timeout occurred while reading.');
177+
if (this.currentPort?.readable) reader?.cancel();
178+
}, timeout);
179+
}
180+
const { value, done } = await reader.read();
181+
if (timeoutID) clearTimeout(timeoutID);
182+
183+
if (done) {
184+
console.log('🚫 Reader has been canceled');
185+
return null;
175186
}
187+
return value;
188+
} catch (error) {
189+
console.error('💣 Error occurred while reading: ' + error.message);
190+
} finally {
191+
// console.log('🔓 Releasing reader lock...');
192+
await reader?.cancel(); // Discards any enqueued data
193+
reader?.releaseLock();
194+
this.currentReader = null;
176195
}
177-
return bytesRead;
178196
}
179197

180198
async sendData(byteArray) {

0 commit comments

Comments
 (0)
0