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() {
 | 
			
		||||
        if (this._reader) return;
 | 
			
		||||
 | 
			
		||||
        this._reader = this.port.readable.getReader();
 | 
			
		||||
        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()
 | 
			
		||||
            if (!buffer) buffer = value;
 | 
			
		||||
            else { // concat
 | 
			
		||||
@@ -112,8 +115,18 @@ class WebSerialPackageIO implements pxt.HF2.PacketIO {
 | 
			
		||||
        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> {
 | 
			
		||||
        if (!this._reader) {
 | 
			
		||||
        if (!this.port.readable) {
 | 
			
		||||
            this._reader = undefined;
 | 
			
		||||
            this._writer = undefined;
 | 
			
		||||
            await this.port.open(this.options);
 | 
			
		||||
            this.readSerialAsync();
 | 
			
		||||
        }
 | 
			
		||||
@@ -121,9 +134,7 @@ class WebSerialPackageIO implements pxt.HF2.PacketIO {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async disconnectAsync(): Promise<void> {
 | 
			
		||||
        this.port.close();
 | 
			
		||||
        this._reader = undefined;
 | 
			
		||||
        this._writer = undefined;
 | 
			
		||||
        this.close();
 | 
			
		||||
        return Promise.resolve();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -157,7 +168,7 @@ export function initAsync(): Promise<void> {
 | 
			
		||||
            useHID = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(WebSerialPackageIO.isSupported())
 | 
			
		||||
    if (WebSerialPackageIO.isSupported())
 | 
			
		||||
        pxt.tickEvent("bluetooth.supported");
 | 
			
		||||
 | 
			
		||||
    return Promise.resolve();
 | 
			
		||||
@@ -171,6 +182,8 @@ export function enableWebSerial() {
 | 
			
		||||
    initPromise = undefined;
 | 
			
		||||
    useWebSerial = WebSerialPackageIO.isSupported();
 | 
			
		||||
    useHID = useWebSerial;
 | 
			
		||||
    if (useWebSerial)
 | 
			
		||||
        initHidAsync().done();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let initPromise: Promise<Ev3Wrapper>
 | 
			
		||||
@@ -185,7 +198,7 @@ function initHidAsync() { // needs to run within a click handler
 | 
			
		||||
                useHID = false;
 | 
			
		||||
                useWebSerial = false;
 | 
			
		||||
                // 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))
 | 
			
		||||
            })
 | 
			
		||||
    } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,6 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
 | 
			
		||||
                    className: "bluetooth focused",
 | 
			
		||||
                    onclick: () => {
 | 
			
		||||
                        pxt.tickEvent("bluetooth.enable");
 | 
			
		||||
                        enableWebSerial();
 | 
			
		||||
                        confirmAsync({
 | 
			
		||||
                            header: lf("Bluetooth enabled"),
 | 
			
		||||
                            hasCloseIcon: true,
 | 
			
		||||
@@ -93,7 +92,7 @@ pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): P
 | 
			
		||||
                            }],
 | 
			
		||||
                            htmlBody: `
 | 
			
		||||
<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>
 | 
			
		||||
${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.")}
 | 
			
		||||
</p>
 | 
			
		||||
`
 | 
			
		||||
                        }).then(() => {
 | 
			
		||||
                            enableWebSerial();
 | 
			
		||||
                        })
 | 
			
		||||
                    }
 | 
			
		||||
                } : undefined, downloadAgain ? {
 | 
			
		||||
 
 | 
			
		||||
@@ -310,7 +310,7 @@ void      cUiUpdatePower(void)
 | 
			
		||||
                // TODO? for now assume touch
 | 
			
		||||
                sensorInfo.devType = DAL.DEVICE_TYPE_TOUCH
 | 
			
		||||
            } else if (newConn == DAL.CONN_NONE || newConn == 0) {
 | 
			
		||||
                control.dmesg(`disconnect at port ${sensorInfo.port}`)
 | 
			
		||||
                //control.dmesg(`disconnect at port ${sensorInfo.port}`)
 | 
			
		||||
            } else {
 | 
			
		||||
                control.dmesg(`unknown connection type: ${newConn} at ${sensorInfo.port}`)
 | 
			
		||||
            }
 | 
			
		||||
@@ -328,7 +328,7 @@ void      cUiUpdatePower(void)
 | 
			
		||||
        if (numChanged == 0 && nonActivated == 0)
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        control.dmesg(`updating sensor status`)
 | 
			
		||||
        //control.dmesg(`updating sensor status`)
 | 
			
		||||
        nonActivated = 0;
 | 
			
		||||
        for (const sensorInfo of sensorInfos) {
 | 
			
		||||
            if (sensorInfo.devType == DAL.DEVICE_TYPE_IIC_UNKNOWN) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user