feat: sync mixly root files and common folder
This commit is contained in:
201
mixly/common/modules/mixly-modules/web-socket/ampy-fs.js
Normal file
201
mixly/common/modules/mixly-modules/web-socket/ampy-fs.js
Normal file
@@ -0,0 +1,201 @@
|
||||
goog.loadJs('web', () => {
|
||||
|
||||
goog.require('path');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.FS');
|
||||
goog.require('Mixly.Debug');
|
||||
goog.require('Mixly.MJson');
|
||||
goog.require('Mixly.WebSocket.Ampy');
|
||||
goog.provide('Mixly.WebSocket.AmpyFS');
|
||||
|
||||
const {
|
||||
Env,
|
||||
FS,
|
||||
Debug,
|
||||
MJson,
|
||||
WebSocket
|
||||
} = Mixly;
|
||||
|
||||
const { Ampy } = WebSocket;
|
||||
|
||||
|
||||
class AmpyFS extends FS {
|
||||
#ampy_ = null;
|
||||
#port_ = '';
|
||||
#baud_ = 115200;
|
||||
#decoder_ = new TextDecoder('utf8');
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#ampy_ = new Ampy();
|
||||
}
|
||||
|
||||
async rename(oldPath, newPath) {
|
||||
let stdout = '', error = null;
|
||||
try {
|
||||
stdout = await this.#ampy_.rename(this.#port_, this.#baud_, oldPath, newPath);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
Debug.error(error);
|
||||
}
|
||||
return [error, stdout];
|
||||
}
|
||||
|
||||
async createFile(filePath) {
|
||||
let stdout = '', error = null;
|
||||
try {
|
||||
stdout = await this.#ampy_.mkfile(this.#port_, this.#baud_, filePath);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
Debug.error(error);
|
||||
}
|
||||
return [error, stdout];
|
||||
}
|
||||
|
||||
async readFile(filePath) {
|
||||
let stdout = '', error = null;
|
||||
try {
|
||||
stdout = await this.#ampy_.get(this.#port_, this.#baud_, filePath);
|
||||
stdout = this.#decoder_.decode(this.#ampy_.unhexlify(stdout));
|
||||
} catch (e) {
|
||||
error = e;
|
||||
Debug.error(error);
|
||||
}
|
||||
return [error, stdout];
|
||||
}
|
||||
|
||||
async writeFile(filePath, data) {
|
||||
let stdout = '', error = null;
|
||||
try {
|
||||
stdout = await this.#ampy_.put(this.#port_, this.#baud_, filePath, data);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
Debug.error(error);
|
||||
}
|
||||
return [error, stdout];
|
||||
}
|
||||
|
||||
async isFile(filePath) {
|
||||
/*const [error, stdout] = await this.readDirectory(filePath);
|
||||
if (error) {
|
||||
return true;
|
||||
}
|
||||
return false;*/
|
||||
let error = null;
|
||||
if (path.extname(filePath)) {
|
||||
return [error, true];
|
||||
} else {
|
||||
return [error, false];
|
||||
}
|
||||
}
|
||||
|
||||
async renameFile(oldFilePath, newFilePath) {
|
||||
return this.rename(oldFilePath, newFilePath);
|
||||
}
|
||||
|
||||
// async moveFile(oldFilePath, newFilePath) {}
|
||||
|
||||
// async copyFile(oldFilePath, newFilePath) {}
|
||||
|
||||
async deleteFile(filePath) {
|
||||
let stdout = '', error = null;
|
||||
try {
|
||||
stdout = await this.#ampy_.rm(this.#port_, this.#baud_, filePath);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
Debug.error(error);
|
||||
}
|
||||
return [error, stdout];
|
||||
}
|
||||
|
||||
async createDirectory(folderPath) {
|
||||
let stdout = '', error = null;
|
||||
try {
|
||||
stdout = await this.#ampy_.mkdir(this.#port_, this.#baud_, folderPath);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
Debug.error(error);
|
||||
}
|
||||
return [error, stdout];
|
||||
}
|
||||
|
||||
async readDirectory(folderPath) {
|
||||
let stdout = [], error = null;
|
||||
try {
|
||||
const output = await this.#ampy_.ls(this.#port_, this.#baud_, folderPath);
|
||||
const dirs = Array.from(new Set(output.split('\r\n')));
|
||||
for (let i in dirs) {
|
||||
if (!dirs[i]) {
|
||||
continue;
|
||||
}
|
||||
stdout.push(MJson.parse(dirs[i].replaceAll('\'', '"')));
|
||||
}
|
||||
} catch (e) {
|
||||
error = e;
|
||||
Debug.error(error);
|
||||
}
|
||||
return [error, stdout];
|
||||
}
|
||||
|
||||
async isDirectory(folderPath) {
|
||||
/*const [error, stdout] = await this.readDirectory(folderPath);
|
||||
if (error) {
|
||||
return false;
|
||||
}
|
||||
return true;*/
|
||||
let error = null;
|
||||
if (path.extname(folderPath)) {
|
||||
return [error, false];
|
||||
} else {
|
||||
return [error, true];
|
||||
}
|
||||
}
|
||||
|
||||
async isDirectoryEmpty(folderPath) {
|
||||
/*const [error, stdout] = await this.readDirectory(folderPath);
|
||||
let isEmpty = false;
|
||||
if (error || !stdout.length) {
|
||||
isEmpty = true;
|
||||
}*/
|
||||
return [null, false];
|
||||
}
|
||||
|
||||
async renameDirectory(oldFolderPath, newFolderPath) {
|
||||
return this.rename(oldFolderPath, newFolderPath);
|
||||
}
|
||||
|
||||
// async moveDirectory(oldFolderPath, newFolderPath) {}
|
||||
|
||||
// async copyDirectory(oldFolderPath, newFolderPath) {}
|
||||
|
||||
async deleteDirectory(folderPath) {
|
||||
let stdout = '', error = null;
|
||||
try {
|
||||
stdout = await this.#ampy_.rmdir(this.#port_, this.#baud_, folderPath);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
Debug.error(error);
|
||||
}
|
||||
return [error, stdout];
|
||||
}
|
||||
|
||||
setPortName(port) {
|
||||
this.#port_ = port;
|
||||
}
|
||||
|
||||
getPortName() {
|
||||
return this.#port_;
|
||||
}
|
||||
|
||||
setBaudRate(baud) {
|
||||
this.#baud_ = baud;
|
||||
}
|
||||
|
||||
getBaudRate() {
|
||||
return this.#baud_;
|
||||
}
|
||||
}
|
||||
|
||||
WebSocket.AmpyFS = AmpyFS;
|
||||
|
||||
});
|
||||
108
mixly/common/modules/mixly-modules/web-socket/ampy.js
Normal file
108
mixly/common/modules/mixly-modules/web-socket/ampy.js
Normal file
@@ -0,0 +1,108 @@
|
||||
goog.loadJs('web', () => {
|
||||
|
||||
goog.require('path');
|
||||
goog.require('Mustache');
|
||||
goog.require('Mixly.Ampy');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.Serial');
|
||||
goog.require('Mixly.WebSocket');
|
||||
goog.provide('Mixly.WebSocket.Ampy');
|
||||
|
||||
const {
|
||||
Ampy,
|
||||
Env,
|
||||
Serial,
|
||||
WebSocket
|
||||
} = Mixly;
|
||||
|
||||
|
||||
class AmpyExt extends Ampy {
|
||||
static {
|
||||
this.mixlySocket = null;
|
||||
this.socket = null;
|
||||
|
||||
this.getSocket = function () {
|
||||
return this.socket;
|
||||
}
|
||||
|
||||
this.getMixlySocket = function () {
|
||||
return this.mixlySocket;
|
||||
}
|
||||
|
||||
this.init = function (mixlySocket) {
|
||||
this.mixlySocket = mixlySocket;
|
||||
this.socket = mixlySocket.getSocket();
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async ls(port, baud, folderPath) {
|
||||
return this.exec('ampy.ls', port, baud, folderPath);
|
||||
}
|
||||
|
||||
async get(port, baud, filePath) {
|
||||
return this.exec('ampy.get', port, baud, filePath);
|
||||
}
|
||||
|
||||
async mkdir(port, baud, folderPath) {
|
||||
return this.exec('ampy.mkdir', port, baud, folderPath);
|
||||
}
|
||||
|
||||
async mkfile(port, baud, filePath) {
|
||||
return this.exec('ampy.mkfile', port, baud, filePath);
|
||||
}
|
||||
|
||||
async isdir(port, baud, folderPath) {
|
||||
return this.exec('ampy.isdir', port, baud, folderPath);
|
||||
}
|
||||
|
||||
async isfile(port, baud, filePath) {
|
||||
return this.exec('ampy.isfile', port, baud, filePath);
|
||||
}
|
||||
|
||||
async put(port, baud, filePath, data) {
|
||||
return this.exec('ampy.put', port, baud, filePath, data);
|
||||
}
|
||||
|
||||
async rm(port, baud, filePath) {
|
||||
return this.exec('ampy.rm', port, baud, filePath);
|
||||
}
|
||||
|
||||
async rmdir(port, baud, folderPath) {
|
||||
return this.exec('ampy.rmdir', port, baud, folderPath);
|
||||
}
|
||||
|
||||
async rename(port, baud, oldPath, newPath) {
|
||||
return this.exec('ampy.rename', port, baud, oldPath, newPath);
|
||||
}
|
||||
|
||||
async run(port, baud, filePath) {
|
||||
return this.exec('ampy.run', port, baud, filePath);
|
||||
}
|
||||
|
||||
async exec(eventType, port, ...args) {
|
||||
const portsName = Serial.getCurrentPortsName();
|
||||
if (!portsName.includes(port)) {
|
||||
throw new Error('无可用串口');
|
||||
return;
|
||||
}
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarSerial = mainStatusBarTabs.getStatusBarById(port);
|
||||
if (statusBarSerial) {
|
||||
await statusBarSerial.close();
|
||||
}
|
||||
const mixlySocket = AmpyExt.getMixlySocket();
|
||||
const output = await mixlySocket.emitAsync(eventType, port, ...args);
|
||||
if (output[0]) {
|
||||
throw new Error(output[0]);
|
||||
}
|
||||
return output[1];
|
||||
}
|
||||
}
|
||||
|
||||
WebSocket.Ampy = AmpyExt;
|
||||
|
||||
});
|
||||
275
mixly/common/modules/mixly-modules/web-socket/arduino-shell.js
Normal file
275
mixly/common/modules/mixly-modules/web-socket/arduino-shell.js
Normal file
@@ -0,0 +1,275 @@
|
||||
goog.loadJs('web', () => {
|
||||
|
||||
goog.require('layui');
|
||||
goog.require('dayjs.duration');
|
||||
goog.require('Mixly.Boards');
|
||||
goog.require('Mixly.Debug');
|
||||
goog.require('Mixly.LayerExt');
|
||||
goog.require('Mixly.Msg');
|
||||
goog.require('Mixly.Workspace');
|
||||
goog.require('Mixly.LayerProgress');
|
||||
goog.require('Mixly.WebSocket.Serial');
|
||||
goog.provide('Mixly.WebSocket.ArduShell');
|
||||
|
||||
const {
|
||||
Boards,
|
||||
Debug,
|
||||
LayerExt,
|
||||
Msg,
|
||||
Workspace,
|
||||
LayerProgress,
|
||||
WebSocket
|
||||
} = Mixly;
|
||||
|
||||
const { Serial } = WebSocket;
|
||||
|
||||
const { layer } = layui;
|
||||
|
||||
|
||||
class WebSocketArduShell {
|
||||
static {
|
||||
this.mixlySocket = null;
|
||||
this.socket = null;
|
||||
this.shell = null;
|
||||
|
||||
this.getSocket = function () {
|
||||
return this.socket;
|
||||
}
|
||||
|
||||
this.getMixlySocket = function () {
|
||||
return this.mixlySocket;
|
||||
}
|
||||
|
||||
this.init = function (mixlySocket) {
|
||||
this.mixlySocket = mixlySocket;
|
||||
this.socket = mixlySocket.getSocket();
|
||||
this.shell = new WebSocketArduShell();
|
||||
const socket = this.socket;
|
||||
|
||||
socket.on('arduino.dataEvent', (data) => {
|
||||
if (data.length > 1000) {
|
||||
return;
|
||||
}
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
statusBarTerminal.addValue(data);
|
||||
});
|
||||
|
||||
socket.on('arduino.errorEvent', (data) => {
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
try {
|
||||
data = unescape(data.replace(/(_E[0-9A-F]{1}_[0-9A-F]{2}_[0-9A-F]{2})+/gm, '%$1'));
|
||||
data = unescape(data.replace(/\\(u[0-9a-fA-F]{4})/gm, '%$1'));
|
||||
} catch (error) {
|
||||
Debug.error(error);
|
||||
}
|
||||
statusBarTerminal.addValue(data);
|
||||
});
|
||||
}
|
||||
|
||||
this.initCompile = function () {
|
||||
if (!this.mixlySocket.isConnected()) {
|
||||
layer.msg(Msg.Lang['websocket.offline'], { time: 1000 });
|
||||
return;
|
||||
}
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
mainStatusBarTabs.changeTo('output');
|
||||
mainStatusBarTabs.show();
|
||||
const mainWorkspace = Workspace.getMain();
|
||||
const editor = mainWorkspace.getEditorsManager().getActive();
|
||||
const code = editor.getCode();
|
||||
statusBarTerminal.setValue(`${Msg.Lang['shell.compiling']}...\n`);
|
||||
this.shell.compile(code)
|
||||
.then((info) => {
|
||||
this.endCallback(info.code, info.time);
|
||||
})
|
||||
.catch((error) => {
|
||||
Debug.error(error);
|
||||
statusBarTerminal.addValue(`\n==${Msg.Lang['shell.compileFailed']}==\n`);
|
||||
});
|
||||
}
|
||||
|
||||
this.initUpload = function () {
|
||||
if (!this.mixlySocket.isConnected()) {
|
||||
layer.msg(Msg.Lang['websocket.offline'], { time: 1000 });
|
||||
return;
|
||||
}
|
||||
const port = Serial.getSelectedPortName();
|
||||
if (!port) {
|
||||
layer.msg(Msg.Lang['statusbar.serial.noDevice'], {
|
||||
time: 1000
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
mainStatusBarTabs.changeTo('output');
|
||||
mainStatusBarTabs.show();
|
||||
statusBarTerminal.setValue(`${Msg.Lang['shell.uploading']}...\n`);
|
||||
const mainWorkspace = Workspace.getMain();
|
||||
const editor = mainWorkspace.getEditorsManager().getActive();
|
||||
const code = editor.getCode();
|
||||
const statusBarSerial = mainStatusBarTabs.getStatusBarById(port);
|
||||
const closePromise = statusBarSerial ? statusBarSerial.close() : Promise.resolve();
|
||||
closePromise
|
||||
.then(() => {
|
||||
return this.shell.upload(port, code)
|
||||
})
|
||||
.then((info) => {
|
||||
this.endCallback(info.code, info.time);
|
||||
if (info.code || !Serial.portIsLegal(port)) {
|
||||
return;
|
||||
}
|
||||
mainStatusBarTabs.add('serial', port);
|
||||
mainStatusBarTabs.changeTo(port);
|
||||
const statusBarSerial = mainStatusBarTabs.getStatusBarById(port);
|
||||
statusBarSerial.open()
|
||||
.then(() => {
|
||||
const baudRates = code.match(/(?<=Serial.begin[\s]*\([\s]*)[0-9]*(?=[\s]*\))/g);
|
||||
if (!baudRates?.length) {
|
||||
return statusBarSerial.setBaudRate(9600);
|
||||
} else {
|
||||
return statusBarSerial.setBaudRate(baudRates[0] - 0);
|
||||
}
|
||||
})
|
||||
.catch(Debug.error);
|
||||
})
|
||||
.catch((error) => {
|
||||
Debug.error(error);
|
||||
statusBarTerminal.addValue(`\n==${Msg.Lang['shell.uploadFailed']}==\n`);
|
||||
});
|
||||
}
|
||||
|
||||
this.endCallback = function (code, time) {
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
mainStatusBarTabs.changeTo('output');
|
||||
let message = '';
|
||||
if (code) {
|
||||
message = (this.shell.isCompiling() ? Msg.Lang['shell.compileFailed'] : Msg.Lang['shell.uploadFailed']);
|
||||
statusBarTerminal.addValue(`\n==${message}==\n`);
|
||||
} else {
|
||||
message = (this.shell.isCompiling() ? Msg.Lang['shell.compileSucc'] : Msg.Lang['shell.uploadSucc']);
|
||||
statusBarTerminal.addValue(`\n==${message}(${Msg.Lang['shell.timeCost']} ${
|
||||
dayjs.duration(time).format('HH:mm:ss.SSS')
|
||||
})==\n`);
|
||||
}
|
||||
layer.msg(message, { time: 1000 });
|
||||
}
|
||||
}
|
||||
|
||||
#running_ = false;
|
||||
#upload_ = false;
|
||||
#killing_ = false;
|
||||
#layer_ = null;
|
||||
|
||||
constructor() {
|
||||
this.#layer_ = new LayerProgress({
|
||||
width: 200,
|
||||
cancelValue: Msg.Lang['nav.btn.stop'],
|
||||
skin: 'layui-anim layui-anim-scale',
|
||||
cancel: () => {
|
||||
if (this.#killing_) {
|
||||
return false;
|
||||
}
|
||||
this.#layer_.title(`${Msg.Lang['shell.aborting']}...`);
|
||||
this.#killing_ = true;
|
||||
this.kill().catch(Debug.error);
|
||||
return false;
|
||||
},
|
||||
cancelDisplay: false
|
||||
});
|
||||
}
|
||||
|
||||
async compile(code) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
this.#running_ = true;
|
||||
this.#upload_ = false;
|
||||
this.#killing_ = false;
|
||||
this.showProgress();
|
||||
const key = Boards.getSelectedBoardCommandParam();
|
||||
const config = { key, code };
|
||||
const mixlySocket = WebSocketArduShell.getMixlySocket();
|
||||
mixlySocket.emit('arduino.compile', config, (response) => {
|
||||
this.hideProgress();
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async upload(port, code) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
this.#running_ = true;
|
||||
this.#upload_ = true;
|
||||
this.#killing_ = false;
|
||||
this.showProgress();
|
||||
const key = Boards.getSelectedBoardCommandParam();
|
||||
const config = { key, code, port };
|
||||
const mixlySocket = WebSocketArduShell.getMixlySocket();
|
||||
mixlySocket.emit('arduino.upload', config, (response) => {
|
||||
this.hideProgress();
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async kill() {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const mixlySocket = WebSocketArduShell.getMixlySocket();
|
||||
mixlySocket.emit('arduino.kill', (response) => {
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
showProgress() {
|
||||
const message = this.isCompiling() ? Msg.Lang['shell.compiling'] : Msg.Lang['shell.uploading'];
|
||||
this.#layer_.title(`${message}...`);
|
||||
this.#layer_.show();
|
||||
}
|
||||
|
||||
hideProgress() {
|
||||
this.#layer_.hide();
|
||||
}
|
||||
|
||||
isUploading() {
|
||||
return this.#running_ && this.#upload_;
|
||||
}
|
||||
|
||||
isCompiling() {
|
||||
return this.#running_ && !this.#upload_;
|
||||
}
|
||||
}
|
||||
|
||||
WebSocket.ArduShell = WebSocketArduShell;
|
||||
|
||||
});
|
||||
350
mixly/common/modules/mixly-modules/web-socket/burn-upload.js
Normal file
350
mixly/common/modules/mixly-modules/web-socket/burn-upload.js
Normal file
@@ -0,0 +1,350 @@
|
||||
goog.loadJs('web', () => {
|
||||
|
||||
goog.require('path');
|
||||
goog.require('layui');
|
||||
goog.require('dayjs.duration');
|
||||
goog.require('Mixly.Debug');
|
||||
goog.require('Mixly.LayerExt');
|
||||
goog.require('Mixly.Msg');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.Config');
|
||||
goog.require('Mixly.Workspace');
|
||||
goog.require('Mixly.MString');
|
||||
goog.require('Mixly.LayerProgress');
|
||||
goog.require('Mixly.WebSocket.Serial');
|
||||
goog.provide('Mixly.WebSocket.BU');
|
||||
|
||||
const {
|
||||
Debug,
|
||||
LayerExt,
|
||||
Config,
|
||||
Msg,
|
||||
Env,
|
||||
Workspace,
|
||||
MString,
|
||||
LayerProgress,
|
||||
WebSocket
|
||||
} = Mixly;
|
||||
|
||||
const { SELECTED_BOARD } = Config;
|
||||
|
||||
const { Serial } = WebSocket;
|
||||
|
||||
const { layer } = layui;
|
||||
|
||||
|
||||
class WebSocketBU {
|
||||
static {
|
||||
this.mixlySocket = null;
|
||||
this.socket = null;
|
||||
this.shell = null;
|
||||
|
||||
this.getSocket = function () {
|
||||
return this.socket;
|
||||
}
|
||||
|
||||
this.getMixlySocket = function () {
|
||||
return this.mixlySocket;
|
||||
}
|
||||
|
||||
this.init = function (mixlySocket) {
|
||||
this.mixlySocket = mixlySocket;
|
||||
this.socket = mixlySocket.getSocket();
|
||||
this.shell = new WebSocketBU();
|
||||
const socket = this.socket;
|
||||
|
||||
socket.on('micropython.dataEvent', (data) => {
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
statusBarTerminal.addValue(data);
|
||||
});
|
||||
|
||||
socket.on('micropython.errorEvent', (data) => {
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
statusBarTerminal.addValue(data);
|
||||
});
|
||||
}
|
||||
|
||||
this.initBurn = function () {
|
||||
if (!this.mixlySocket.isConnected()) {
|
||||
layer.msg(Msg.Lang['websocket.offline'], { time: 1000 });
|
||||
return;
|
||||
}
|
||||
const port = Serial.getSelectedPortName();
|
||||
if (!port) {
|
||||
layer.msg(Msg.Lang['statusbar.serial.noDevice'], {
|
||||
time: 1000
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
mainStatusBarTabs.changeTo('output');
|
||||
mainStatusBarTabs.show();
|
||||
statusBarTerminal.setValue(`${Msg.Lang['shell.burning']}...\n`);
|
||||
const statusBarSerial = mainStatusBarTabs.getStatusBarById(port);
|
||||
const closePromise = statusBarSerial ? statusBarSerial.close() : Promise.resolve();
|
||||
closePromise
|
||||
.then(() => {
|
||||
return this.shell.burn(port);
|
||||
})
|
||||
.then((info) => {
|
||||
this.endCallback(info.code, info.time);
|
||||
})
|
||||
.catch((error) => {
|
||||
Debug.error(error);
|
||||
statusBarTerminal.addValue(`\n==${Msg.Lang['shell.burnFailed']}==\n`);
|
||||
});
|
||||
}
|
||||
|
||||
this.initUpload = function () {
|
||||
if (!this.mixlySocket.isConnected()) {
|
||||
layer.msg(Msg.Lang['websocket.offline'], { time: 1000 });
|
||||
return;
|
||||
}
|
||||
const port = Serial.getSelectedPortName();
|
||||
if (!port) {
|
||||
layer.msg(Msg.Lang['statusbar.serial.noDevice'], {
|
||||
time: 1000
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
mainStatusBarTabs.changeTo('output');
|
||||
mainStatusBarTabs.show();
|
||||
statusBarTerminal.setValue(`${Msg.Lang['shell.uploading']}...\n`);
|
||||
const mainWorkspace = Workspace.getMain();
|
||||
const editor = mainWorkspace.getEditorsManager().getActive();
|
||||
const code = editor.getCode();
|
||||
const statusBarSerial = mainStatusBarTabs.getStatusBarById(port);
|
||||
const closePromise = statusBarSerial ? statusBarSerial.close() : Promise.resolve();
|
||||
closePromise
|
||||
.then(() => {
|
||||
return this.shell.upload(port, code)
|
||||
})
|
||||
.then((info) => {
|
||||
this.endCallback(info.code, info.time);
|
||||
if (info.code || !Serial.portIsLegal(port)) {
|
||||
return;
|
||||
}
|
||||
mainStatusBarTabs.add('serial', port);
|
||||
mainStatusBarTabs.changeTo(port);
|
||||
const statusBarSerial = mainStatusBarTabs.getStatusBarById(port);
|
||||
statusBarSerial.open()
|
||||
.then(() => {
|
||||
return statusBarSerial.setBaudRate(115200);
|
||||
})
|
||||
.catch(Debug.error);
|
||||
})
|
||||
.catch((error) => {
|
||||
Debug.error(error);
|
||||
statusBarTerminal.addValue(`\n==${Msg.Lang['shell.uploadFailed']}==\n`);
|
||||
});
|
||||
}
|
||||
|
||||
this.endCallback = function (code, time) {
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||
mainStatusBarTabs.changeTo('output');
|
||||
let message = '';
|
||||
if (code) {
|
||||
message = (this.shell.isBurning() ? Msg.Lang['shell.burnFailed'] : Msg.Lang['shell.uploadFailed']);
|
||||
statusBarTerminal.addValue(`\n==${message}==\n`);
|
||||
} else {
|
||||
message = (this.shell.isBurning() ? Msg.Lang['shell.burnSucc'] : Msg.Lang['shell.uploadSucc']);
|
||||
statusBarTerminal.addValue(`\n==${message}(${Msg.Lang['shell.timeCost']} ${
|
||||
dayjs.duration(time).format('HH:mm:ss.SSS')
|
||||
})==\n`);
|
||||
}
|
||||
layer.msg(message, { time: 1000 });
|
||||
}
|
||||
}
|
||||
|
||||
#running_ = false;
|
||||
#upload_ = false;
|
||||
#killing_ = false;
|
||||
#layer_ = null;
|
||||
|
||||
constructor() {
|
||||
this.#layer_ = new LayerProgress({
|
||||
width: 200,
|
||||
cancelValue: Msg.Lang['nav.btn.stop'],
|
||||
skin: 'layui-anim layui-anim-scale',
|
||||
cancel: () => {
|
||||
if (this.#killing_) {
|
||||
return false;
|
||||
}
|
||||
this.#layer_.title(`${Msg.Lang['shell.aborting']}...`);
|
||||
this.#killing_ = true;
|
||||
this.kill().catch(Debug.error);
|
||||
return false;
|
||||
},
|
||||
cancelDisplay: false
|
||||
});
|
||||
}
|
||||
|
||||
async burn(port) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
this.#running_ = true;
|
||||
this.#upload_ = false;
|
||||
this.#killing_ = false;
|
||||
this.showProgress();
|
||||
const config = {
|
||||
boardDirPath: `.${Env.boardDirPath}`,
|
||||
port,
|
||||
command: SELECTED_BOARD.burn.command
|
||||
};
|
||||
const mixlySocket = WebSocketBU.getMixlySocket();
|
||||
mixlySocket.emit('micropython.burn', config, (response) => {
|
||||
this.hideProgress();
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async upload(port, code) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
this.#running_ = true;
|
||||
this.#upload_ = true;
|
||||
this.#killing_ = false;
|
||||
this.showProgress();
|
||||
const importsMap = this.getImportModules(code);
|
||||
let libraries = {};
|
||||
for (let key in importsMap) {
|
||||
const filename = importsMap[key]['__name__'];
|
||||
const data = goog.readFileSync(importsMap[key]['__path__']);
|
||||
libraries[filename] = data;
|
||||
}
|
||||
const config = {
|
||||
boardDirPath: `.${Env.boardDirPath}`,
|
||||
command: SELECTED_BOARD.upload.command,
|
||||
filePath: SELECTED_BOARD.upload.filePath,
|
||||
port, code, libraries
|
||||
};
|
||||
|
||||
const mixlySocket = WebSocketBU.getMixlySocket();
|
||||
mixlySocket.emit('micropython.upload', config, (response) => {
|
||||
this.hideProgress();
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getImportModulesName(code) {
|
||||
// 正则表达式: 匹配 import 或 from 导入语句
|
||||
const importRegex = /(?:import\s+([a-zA-Z0-9_]+)|from\s+([a-zA-Z0-9_]+)\s+import)/g;
|
||||
|
||||
let imports = [];
|
||||
let match;
|
||||
while ((match = importRegex.exec(code)) !== null) {
|
||||
if (match[1]) {
|
||||
imports.push(match[1]); // 'import module'
|
||||
}
|
||||
if (match[2]) {
|
||||
imports.push(match[2]); // 'from module import ...'
|
||||
}
|
||||
}
|
||||
return imports;
|
||||
}
|
||||
|
||||
getImportModules(code) {
|
||||
let importsMap = {};
|
||||
const libPath = SELECTED_BOARD.upload.libPath;
|
||||
for (let i = libPath.length - 1; i >= 0; i--) {
|
||||
const dirname = MString.tpl(libPath[i], { indexPath: Env.boardDirPath });
|
||||
const map = goog.readJsonSync(path.join(dirname, 'map.json'));
|
||||
if (!(map && map instanceof Object)) {
|
||||
continue;
|
||||
}
|
||||
for (let key in map) {
|
||||
importsMap[key] = structuredClone(map[key]);
|
||||
importsMap[key]['__path__'] = path.join(dirname, map[key]['__name__']);
|
||||
}
|
||||
}
|
||||
|
||||
let usedMap = {};
|
||||
let currentImports = this.getImportModulesName(code);
|
||||
while (currentImports.length) {
|
||||
let temp = [];
|
||||
for (let moduleName of currentImports) {
|
||||
let moduleInfo = importsMap[moduleName];
|
||||
if (!moduleInfo) {
|
||||
continue;
|
||||
}
|
||||
usedMap[moduleName] = moduleInfo;
|
||||
const moduleImports = moduleInfo['__require__'];
|
||||
if (!moduleImports) {
|
||||
continue;
|
||||
}
|
||||
for (let name of moduleImports) {
|
||||
if (usedMap[name] || !importsMap[name] || temp.includes(name)) {
|
||||
continue;
|
||||
}
|
||||
temp.push(name);
|
||||
}
|
||||
}
|
||||
currentImports = temp;
|
||||
}
|
||||
return usedMap;
|
||||
}
|
||||
|
||||
async kill() {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const mixlySocket = WebSocketBU.getMixlySocket();
|
||||
mixlySocket.emit('micropython.kill', (response) => {
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
showProgress() {
|
||||
const message = this.isBurning() ? Msg.Lang['shell.burning'] : Msg.Lang['shell.uploading'];
|
||||
this.#layer_.title(`${message}...`);
|
||||
this.#layer_.show();
|
||||
}
|
||||
|
||||
hideProgress() {
|
||||
this.#layer_.hide();
|
||||
}
|
||||
|
||||
isUploading() {
|
||||
return this.#running_ && this.#upload_;
|
||||
}
|
||||
|
||||
isBurning() {
|
||||
return this.#running_ && !this.#upload_;
|
||||
}
|
||||
}
|
||||
|
||||
WebSocket.BU = WebSocketBU;
|
||||
|
||||
});
|
||||
11
mixly/common/modules/mixly-modules/web-socket/file.js
Normal file
11
mixly/common/modules/mixly-modules/web-socket/file.js
Normal file
@@ -0,0 +1,11 @@
|
||||
goog.loadJs('web', () => {
|
||||
|
||||
goog.require('Mixly.Web.File');
|
||||
goog.provide('Mixly.WebSocket.File');
|
||||
|
||||
|
||||
const { Web, WebSocket } = Mixly;
|
||||
|
||||
WebSocket.File = Web.File;
|
||||
|
||||
});
|
||||
101
mixly/common/modules/mixly-modules/web-socket/loader.js
Normal file
101
mixly/common/modules/mixly-modules/web-socket/loader.js
Normal file
@@ -0,0 +1,101 @@
|
||||
goog.loadJs('web', () => {
|
||||
|
||||
goog.require('Mixly.Debug');
|
||||
goog.require('Mixly.Config');
|
||||
goog.require('Mixly.StatusBarsManager');
|
||||
goog.require('Mixly.Socket');
|
||||
goog.require('Mixly.WebSocket.Serial');
|
||||
goog.require('Mixly.WebSocket.ArduShell');
|
||||
goog.require('Mixly.WebSocket.BU');
|
||||
goog.require('Mixly.WebSocket.Ampy');
|
||||
goog.provide('Mixly.WebSocket.Loader');
|
||||
|
||||
const {
|
||||
Debug,
|
||||
Config,
|
||||
StatusBarsManager,
|
||||
Socket,
|
||||
WebSocket
|
||||
} = Mixly;
|
||||
|
||||
const {
|
||||
Loader,
|
||||
Serial,
|
||||
ArduShell,
|
||||
BU,
|
||||
Ampy
|
||||
} = WebSocket;
|
||||
|
||||
const { SOFTWARE } = Config;
|
||||
|
||||
|
||||
Loader.init = function () {
|
||||
let url = '';
|
||||
if (SOFTWARE.webSocket?.url) {
|
||||
const info = new window.URL(SOFTWARE.webSocket.url);
|
||||
if (window.location.protocol === 'http:') {
|
||||
info.protocol = 'ws:';
|
||||
}
|
||||
if (info.hostname === 'default') {
|
||||
info.hostname = window.location.hostname;
|
||||
}
|
||||
url = info.origin;
|
||||
} else {
|
||||
url = `wss://${window.location.host}`;
|
||||
}
|
||||
const mixlySocket = new Socket(`${url}/all`, {
|
||||
path: '/mixly-socket/',
|
||||
reconnection: true,
|
||||
reconnectionDelayMax: 10000,
|
||||
transports: ['websocket'],
|
||||
protocols: ['my-protocol-v1']
|
||||
});
|
||||
|
||||
const socket = mixlySocket.getSocket();
|
||||
|
||||
socket.on('connect', () => {
|
||||
Serial.getPorts()
|
||||
.then((ports) => {
|
||||
let portsName = [];
|
||||
for (let port of ports) {
|
||||
portsName.push(port.name);
|
||||
}
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
let keys = mainStatusBarTabs.keys();
|
||||
const statusBarType = StatusBarsManager.typesRegistry.getItem('serial');
|
||||
for (let key of keys) {
|
||||
const statusBar = mainStatusBarTabs.getStatusBarById(key);
|
||||
if (!(statusBar instanceof statusBarType)) {
|
||||
continue;
|
||||
}
|
||||
const portName = statusBar.getPortName();
|
||||
if (!portsName.includes(portName)) {
|
||||
continue;
|
||||
}
|
||||
socket.emit('serial.create', portName);
|
||||
}
|
||||
Serial.renderSelectBox(ports);
|
||||
})
|
||||
.catch(Debug.error);
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
const { mainStatusBarTabs } = Mixly;
|
||||
let keys = mainStatusBarTabs.keys();
|
||||
const statusBarType = StatusBarsManager.typesRegistry.getItem('serial');
|
||||
for (let key of keys) {
|
||||
const statusBar = mainStatusBarTabs.getStatusBarById(key);
|
||||
if (statusBar instanceof statusBarType) {
|
||||
statusBar.close().catch(Debug.error);
|
||||
}
|
||||
}
|
||||
Serial.refreshPorts();
|
||||
});
|
||||
|
||||
Serial.init(mixlySocket);
|
||||
ArduShell.init(mixlySocket);
|
||||
BU.init(mixlySocket);
|
||||
Ampy.init(mixlySocket);
|
||||
}
|
||||
|
||||
});
|
||||
360
mixly/common/modules/mixly-modules/web-socket/serial.js
Normal file
360
mixly/common/modules/mixly-modules/web-socket/serial.js
Normal file
@@ -0,0 +1,360 @@
|
||||
goog.loadJs('web', () => {
|
||||
|
||||
goog.require('Mixly.Serial');
|
||||
goog.require('Mixly.Env');
|
||||
goog.require('Mixly.Msg');
|
||||
goog.require('Mixly.Debug');
|
||||
goog.require('Mixly.Registry');
|
||||
goog.require('Mixly.WebSocket');
|
||||
goog.provide('Mixly.WebSocket.Serial');
|
||||
|
||||
|
||||
const {
|
||||
Serial,
|
||||
Env,
|
||||
Msg,
|
||||
Debug,
|
||||
Registry,
|
||||
WebSocket
|
||||
} = Mixly;
|
||||
|
||||
|
||||
class WebSocketSerial extends Serial {
|
||||
static {
|
||||
this.eventRegistry = new Registry();
|
||||
this.mixlySocket = null;
|
||||
this.socket = null;
|
||||
|
||||
this.getConfig = function () {
|
||||
return Serial.getConfig();
|
||||
}
|
||||
|
||||
this.getSelectedPortName = function () {
|
||||
return Serial.getSelectedPortName();
|
||||
}
|
||||
|
||||
this.getCurrentPortsName = function () {
|
||||
return Serial.getCurrentPortsName();
|
||||
}
|
||||
|
||||
this.renderSelectBox = function (ports) {
|
||||
return Serial.renderSelectBox(ports);
|
||||
}
|
||||
|
||||
this.getPorts = async function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.socket.connected) {
|
||||
this.socket.emit('serial.getPorts', (response) => {
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.refreshPorts = function () {
|
||||
this.getPorts()
|
||||
.then((ports) => {
|
||||
Serial.renderSelectBox(ports);
|
||||
})
|
||||
.catch(Debug.error);
|
||||
}
|
||||
|
||||
this.init = function (mixlySocket) {
|
||||
this.mixlySocket = mixlySocket;
|
||||
this.socket = mixlySocket.getSocket();
|
||||
const socket = this.socket;
|
||||
|
||||
socket.on('serial.attachEvent', () => {
|
||||
this.refreshPorts();
|
||||
});
|
||||
|
||||
socket.on('serial.detachEvent', () => {
|
||||
this.refreshPorts();
|
||||
});
|
||||
|
||||
socket.on('serial.bufferEvent', (port, buffer) => {
|
||||
const eventName = `${port}-buffer`;
|
||||
if (!this.eventRegistry.hasKey(eventName)) {
|
||||
return;
|
||||
}
|
||||
const event = this.eventRegistry.getItem(eventName);
|
||||
event(buffer);
|
||||
});
|
||||
|
||||
socket.on('serial.stringEvent', (port, str) => {
|
||||
const eventName = `${port}-string`;
|
||||
if (!this.eventRegistry.hasKey(eventName)) {
|
||||
return;
|
||||
}
|
||||
const event = this.eventRegistry.getItem(eventName);
|
||||
event(str);
|
||||
});
|
||||
|
||||
socket.on('serial.errorEvent', (port, error) => {
|
||||
const eventName = `${port}-error`;
|
||||
if (!this.eventRegistry.hasKey(eventName)) {
|
||||
return;
|
||||
}
|
||||
const event = this.eventRegistry.getItem(eventName);
|
||||
event(error);
|
||||
});
|
||||
|
||||
socket.on('serial.openEvent', (port) => {
|
||||
const eventName = `${port}-open`;
|
||||
if (!this.eventRegistry.hasKey(eventName)) {
|
||||
return;
|
||||
}
|
||||
const event = this.eventRegistry.getItem(eventName);
|
||||
event();
|
||||
});
|
||||
|
||||
socket.on('serial.closeEvent', (port, code) => {
|
||||
const eventName = `${port}-close`;
|
||||
if (!this.eventRegistry.hasKey(eventName)) {
|
||||
return;
|
||||
}
|
||||
const event = this.eventRegistry.getItem(eventName);
|
||||
event(code);
|
||||
});
|
||||
}
|
||||
|
||||
this.getSocket = function () {
|
||||
return this.socket;
|
||||
}
|
||||
|
||||
this.getMixlySocket = function () {
|
||||
return this.mixlySocket;
|
||||
}
|
||||
|
||||
this.getEventRegistry = function () {
|
||||
return this.eventRegistry;
|
||||
}
|
||||
}
|
||||
|
||||
constructor(port) {
|
||||
super(port);
|
||||
this.#addEventsListener_();
|
||||
const socket = WebSocketSerial.getSocket();
|
||||
if (socket.connected) {
|
||||
socket.emit('serial.create', port);
|
||||
}
|
||||
}
|
||||
|
||||
#addEventsListener_() {
|
||||
const port = this.getPortName();
|
||||
const eventRegistry = WebSocketSerial.getEventRegistry();
|
||||
eventRegistry.register(`${port}-buffer`, (buffer) => {
|
||||
this.onBuffer(buffer);
|
||||
});
|
||||
eventRegistry.register(`${port}-string`, (str) => {
|
||||
this.onString(str);
|
||||
});
|
||||
eventRegistry.register(`${port}-error`, (error) => {
|
||||
this.onError(error);
|
||||
this.onClose(1);
|
||||
});
|
||||
eventRegistry.register(`${port}-open`, () => {
|
||||
this.onOpen();
|
||||
});
|
||||
eventRegistry.register(`${port}-close`, (code) => {
|
||||
this.onClose(code);
|
||||
});
|
||||
}
|
||||
|
||||
async open(baud) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const portsName = Serial.getCurrentPortsName();
|
||||
const currentPort = this.getPortName();
|
||||
if (!portsName.includes(currentPort)) {
|
||||
reject('无可用串口');
|
||||
return;
|
||||
}
|
||||
if (this.isOpened()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
baud = baud ?? this.getBaudRate();
|
||||
const mixlySocket = WebSocketSerial.getMixlySocket();
|
||||
mixlySocket.emit('serial.open', currentPort, baud, (response) => {
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
this.onError(error);
|
||||
reject(error);
|
||||
} else {
|
||||
super.open(baud);
|
||||
this.setBaudRate(baud);
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async close() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isOpened()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
super.close();
|
||||
const mixlySocket = WebSocketSerial.getMixlySocket();
|
||||
mixlySocket.emit('serial.close', this.getPortName(), (response) => {
|
||||
if (response.error) {
|
||||
this.onClose(1);
|
||||
resolve(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async setBaudRate(baud) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isOpened()
|
||||
|| this.getRawBaudRate() === baud
|
||||
|| !this.baudRateIsLegal(baud)) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const mixlySocket = WebSocketSerial.getMixlySocket();
|
||||
mixlySocket.emit('serial.setBaudRate', this.getPortName(), baud, (response) => {
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error,] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
super.setBaudRate(baud);
|
||||
this.setDTRAndRTS(this.getDTR(), this.getRTS()).finally(resolve);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async send(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isOpened()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const mixlySocket = WebSocketSerial.getMixlySocket();
|
||||
mixlySocket.emit('serial.send', this.getPortName(), data, (response) => {
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async sendString(str) {
|
||||
return this.send(str);
|
||||
}
|
||||
|
||||
async sendBuffer(buffer) {
|
||||
return this.send(buffer);
|
||||
}
|
||||
|
||||
async setDTRAndRTS(dtr, rts) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isOpened()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const mixlySocket = WebSocketSerial.getMixlySocket();
|
||||
mixlySocket.emit('serial.setDTRAndRTS', this.getPortName(), dtr, rts, (response) => {
|
||||
if (response.error) {
|
||||
reject(response.error);
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
super.setDTRAndRTS(dtr, rts);
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async setDTR(dtr) {
|
||||
return this.setDTRAndRTS(dtr, this.getRTS());
|
||||
}
|
||||
|
||||
async setRTS(rts) {
|
||||
return this.setDTRAndRTS(this.getDTR(), rts);
|
||||
}
|
||||
|
||||
onBuffer(buffer) {
|
||||
super.onBuffer(buffer);
|
||||
for (let i = 0; i < buffer.length; i++) {
|
||||
super.onByte(buffer[i]);
|
||||
}
|
||||
const string = this.decodeBuffer(buffer);
|
||||
if (!string) {
|
||||
return;
|
||||
}
|
||||
for (let char of string) {
|
||||
super.onChar(char);
|
||||
}
|
||||
}
|
||||
|
||||
async #awaitDispose_() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const mixlySocket = WebSocketSerial.getMixlySocket();
|
||||
mixlySocket.emit('serial.dispose', this.getPortName(), (response) => {
|
||||
if (response.error) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const [error, result] = response;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async dispose() {
|
||||
const port = this.getPortName();
|
||||
const eventRegistry = WebSocketSerial.getEventRegistry();
|
||||
eventRegistry.unregister(`${port}-buffer`);
|
||||
eventRegistry.unregister(`${port}-string`);
|
||||
eventRegistry.unregister(`${port}-error`);
|
||||
eventRegistry.unregister(`${port}-open`);
|
||||
eventRegistry.unregister(`${port}-close`);
|
||||
await super.dispose();
|
||||
await this.#awaitDispose_();
|
||||
}
|
||||
}
|
||||
|
||||
WebSocket.Serial = WebSocketSerial;
|
||||
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
goog.loadJs('web', () => {
|
||||
|
||||
goog.require('Mixly');
|
||||
goog.provide('Mixly.WebSocket');
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user