better flow + handle unclosed connection (#921)
* better flow + handle unclosed connection * more checks
This commit is contained in:
		@@ -65,9 +65,12 @@ class WebSerialPackageIO implements pxt.HF2.PacketIO {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async readSerialAsync() {
 | 
					    async readSerialAsync() {
 | 
				
			||||||
 | 
					        if (this._reader) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this._reader = this.port.readable.getReader();
 | 
					        this._reader = this.port.readable.getReader();
 | 
				
			||||||
        let buffer: Uint8Array;
 | 
					        let buffer: Uint8Array;
 | 
				
			||||||
        while (!!this._reader) {
 | 
					        const reader = this._reader;
 | 
				
			||||||
 | 
					        while (reader === this._reader) { // will change if we recycle the connection
 | 
				
			||||||
            const { done, value } = await this._reader.read()
 | 
					            const { done, value } = await this._reader.read()
 | 
				
			||||||
            if (!buffer) buffer = value;
 | 
					            if (!buffer) buffer = value;
 | 
				
			||||||
            else { // concat
 | 
					            else { // concat
 | 
				
			||||||
@@ -112,8 +115,18 @@ class WebSerialPackageIO implements pxt.HF2.PacketIO {
 | 
				
			|||||||
        throw new Error(lf("error on brick ({0})", msg))
 | 
					        throw new Error(lf("error on brick ({0})", msg))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private close() {
 | 
				
			||||||
 | 
					        if (this.port.readable) {// it's open
 | 
				
			||||||
 | 
					            this.port.close();
 | 
				
			||||||
 | 
					            this._reader = undefined;
 | 
				
			||||||
 | 
					            this._writer = undefined;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async reconnectAsync(): Promise<void> {
 | 
					    async reconnectAsync(): Promise<void> {
 | 
				
			||||||
        if (!this._reader) {
 | 
					        if (!this.port.readable) {
 | 
				
			||||||
 | 
					            this._reader = undefined;
 | 
				
			||||||
 | 
					            this._writer = undefined;
 | 
				
			||||||
            await this.port.open(this.options);
 | 
					            await this.port.open(this.options);
 | 
				
			||||||
            this.readSerialAsync();
 | 
					            this.readSerialAsync();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -121,9 +134,7 @@ class WebSerialPackageIO implements pxt.HF2.PacketIO {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async disconnectAsync(): Promise<void> {
 | 
					    async disconnectAsync(): Promise<void> {
 | 
				
			||||||
        this.port.close();
 | 
					        this.close();
 | 
				
			||||||
        this._reader = undefined;
 | 
					 | 
				
			||||||
        this._writer = undefined;
 | 
					 | 
				
			||||||
        return Promise.resolve();
 | 
					        return Promise.resolve();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -157,7 +168,7 @@ export function initAsync(): Promise<void> {
 | 
				
			|||||||
            useHID = true;
 | 
					            useHID = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(WebSerialPackageIO.isSupported())
 | 
					    if (WebSerialPackageIO.isSupported())
 | 
				
			||||||
        pxt.tickEvent("bluetooth.supported");
 | 
					        pxt.tickEvent("bluetooth.supported");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Promise.resolve();
 | 
					    return Promise.resolve();
 | 
				
			||||||
@@ -171,6 +182,8 @@ export function enableWebSerial() {
 | 
				
			|||||||
    initPromise = undefined;
 | 
					    initPromise = undefined;
 | 
				
			||||||
    useWebSerial = WebSerialPackageIO.isSupported();
 | 
					    useWebSerial = WebSerialPackageIO.isSupported();
 | 
				
			||||||
    useHID = useWebSerial;
 | 
					    useHID = useWebSerial;
 | 
				
			||||||
 | 
					    if (useWebSerial)
 | 
				
			||||||
 | 
					        initHidAsync().done();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let initPromise: Promise<Ev3Wrapper>
 | 
					let initPromise: Promise<Ev3Wrapper>
 | 
				
			||||||
@@ -185,7 +198,7 @@ function initHidAsync() { // needs to run within a click handler
 | 
				
			|||||||
                useHID = false;
 | 
					                useHID = false;
 | 
				
			||||||
                useWebSerial = false;
 | 
					                useWebSerial = false;
 | 
				
			||||||
                // cleanup
 | 
					                // cleanup
 | 
				
			||||||
                let p = ev3  ? ev3.disconnectAsync().catch(e => {}) : Promise.resolve();
 | 
					                let p = ev3 ? ev3.disconnectAsync().catch(e => { }) : Promise.resolve();
 | 
				
			||||||
                return p.then(() => Promise.reject(err))
 | 
					                return p.then(() => Promise.reject(err))
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,6 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
 | 
				
			|||||||
                    className: "bluetooth focused",
 | 
					                    className: "bluetooth focused",
 | 
				
			||||||
                    onclick: () => {
 | 
					                    onclick: () => {
 | 
				
			||||||
                        pxt.tickEvent("bluetooth.enable");
 | 
					                        pxt.tickEvent("bluetooth.enable");
 | 
				
			||||||
                        enableWebSerial();
 | 
					 | 
				
			||||||
                        confirmAsync({
 | 
					                        confirmAsync({
 | 
				
			||||||
                            header: lf("Bluetooth enabled"),
 | 
					                            header: lf("Bluetooth enabled"),
 | 
				
			||||||
                            hasCloseIcon: true,
 | 
					                            hasCloseIcon: true,
 | 
				
			||||||
@@ -93,7 +92,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
 | 
				
			|||||||
                            }],
 | 
					                            }],
 | 
				
			||||||
                            htmlBody: `
 | 
					                            htmlBody: `
 | 
				
			||||||
<p>
 | 
					<p>
 | 
				
			||||||
${lf("Please download again to send your code to the EV3 over Bluetooth.")}
 | 
					${lf("Download again to send your code to the EV3 over Bluetooth. Make sure to stop your program!")}
 | 
				
			||||||
</p>
 | 
					</p>
 | 
				
			||||||
<p>
 | 
					<p>
 | 
				
			||||||
${lf("You will be prompted to select a serial port.")}
 | 
					${lf("You will be prompted to select a serial port.")}
 | 
				
			||||||
@@ -101,6 +100,8 @@ ${lf("On Windows, look for 'Standard Serial over Bluetooth link'.")}
 | 
				
			|||||||
${lf("If you have paired multiple EV3, you might have to try out multiple ports until you find the correct one.")}
 | 
					${lf("If you have paired multiple EV3, you might have to try out multiple ports until you find the correct one.")}
 | 
				
			||||||
</p>
 | 
					</p>
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					                        }).then(() => {
 | 
				
			||||||
 | 
					                            enableWebSerial();
 | 
				
			||||||
                        })
 | 
					                        })
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } : undefined, downloadAgain ? {
 | 
					                } : undefined, downloadAgain ? {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -310,7 +310,7 @@ void      cUiUpdatePower(void)
 | 
				
			|||||||
                // TODO? for now assume touch
 | 
					                // TODO? for now assume touch
 | 
				
			||||||
                sensorInfo.devType = DAL.DEVICE_TYPE_TOUCH
 | 
					                sensorInfo.devType = DAL.DEVICE_TYPE_TOUCH
 | 
				
			||||||
            } else if (newConn == DAL.CONN_NONE || newConn == 0) {
 | 
					            } else if (newConn == DAL.CONN_NONE || newConn == 0) {
 | 
				
			||||||
                control.dmesg(`disconnect at port ${sensorInfo.port}`)
 | 
					                //control.dmesg(`disconnect at port ${sensorInfo.port}`)
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                control.dmesg(`unknown connection type: ${newConn} at ${sensorInfo.port}`)
 | 
					                control.dmesg(`unknown connection type: ${newConn} at ${sensorInfo.port}`)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -328,7 +328,7 @@ void      cUiUpdatePower(void)
 | 
				
			|||||||
        if (numChanged == 0 && nonActivated == 0)
 | 
					        if (numChanged == 0 && nonActivated == 0)
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        control.dmesg(`updating sensor status`)
 | 
					        //control.dmesg(`updating sensor status`)
 | 
				
			||||||
        nonActivated = 0;
 | 
					        nonActivated = 0;
 | 
				
			||||||
        for (const sensorInfo of sensorInfos) {
 | 
					        for (const sensorInfo of sensorInfos) {
 | 
				
			||||||
            if (sensorInfo.devType == DAL.DEVICE_TYPE_IIC_UNKNOWN) {
 | 
					            if (sensorInfo.devType == DAL.DEVICE_TYPE_IIC_UNKNOWN) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user