UNPKG

wpilib-riolog

Version:
175 lines 5.79 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const events_1 = require("events"); const message_1 = require("./message"); const promisecond_1 = require("./promisecond"); const rioconnector_1 = require("./rioconnector"); const maxFrameSize = 100000; class DataStore { constructor() { this.buf = new Buffer(65535); this.count = 0; this.frameSize = maxFrameSize; } } class RioConsole extends events_1.EventEmitter { constructor() { super(...arguments); this.discard = false; this.connected = false; this.autoReconnect = true; this.cleanup = false; this.condition = new promisecond_1.PromiseCondition(); this.dataStore = new DataStore(); this.teamNumber = 0; } stop() { this.cleanup = true; this.closeSocket(); } getAutoReconnect() { return this.autoReconnect; } setAutoReconnect(value) { this.autoReconnect = value; if (value === true) { this.condition.set(); } } startListening() { const asyncFunction = async () => { while (!this.cleanup) { while (!this.autoReconnect) { if (this.cleanup) { return; } await this.condition.wait(); this.condition.reset(); } await this.runFunction(this.teamNumber); } console.log('finished loop'); }; this.promise = asyncFunction(); } closeSocket() { if (this.closeFunc !== undefined) { this.closeFunc(); } } disconnect() { this.closeSocket(); } setTeamNumber(teamNumber) { this.teamNumber = teamNumber; } async dispose() { this.stop(); this.removeAllListeners(); await this.promise; } async connect(teamNumber) { const socket = await rioconnector_1.connectToRobot(1741, teamNumber, 2000); if (socket === undefined) { return undefined; } socket.setNoDelay(true); socket.setKeepAlive(true, 500); return socket; } handleBuffer(data) { while (data.length > 0) { if (this.dataStore.frameSize === maxFrameSize) { if (this.dataStore.count < 2) { const toCopy = Math.min(2 - this.dataStore.count, data.length); data.copy(this.dataStore.buf, this.dataStore.count, 0, toCopy); this.dataStore.count += toCopy; data = data.slice(toCopy); if (this.dataStore.count < 2) { return; } } // tslint:disable-next-line:no-bitwise this.dataStore.frameSize = (this.dataStore.buf[0] << 8) | this.dataStore.buf[1]; } { let need = this.dataStore.frameSize - (this.dataStore.count - 2); const toCopy = Math.min(need, data.length); data.copy(this.dataStore.buf, this.dataStore.count, 0, toCopy); this.dataStore.count += toCopy; data = data.slice(toCopy); need -= toCopy; if (need === 0) { this.handleData(this.dataStore.buf); this.dataStore.count = 0; this.dataStore.frameSize = maxFrameSize; } } } } handleData(data) { if (this.discard) { return; } let count = 0; let len = 0; do { len = data.readUInt16BE(count); count += 2; } while (len === 0); const tag = data.readUInt8(count); count++; const outputBuffer = data.slice(3, len + 2); if (tag === 11) { // error or warning. const m = new message_1.ErrorMessage(outputBuffer); this.emit('message', m); } else if (tag === 12) { const m = new message_1.PrintMessage(outputBuffer); this.emit('message', m); } } async runFunction(teamNumber) { const socket = await this.connect(teamNumber); if (socket === undefined) { console.log('bad socket'); return; } this.connected = true; this.emit('connectionChanged', true); console.log('succesfully connected'); socket.on('data', (data) => { this.handleBuffer(data); }); if (this.cleanup) { socket.end(); socket.destroy(); socket.removeAllListeners(); return; } await new Promise((resolve, _) => { this.closeFunc = () => { socket.end(); socket.destroy(); socket.removeAllListeners(); resolve(); console.log('closed locally'); }; socket.on('close', () => { socket.removeAllListeners(); resolve(); console.log('closed remotely (close)'); }); socket.on('end', () => { socket.removeAllListeners(); resolve(); console.log('closed remotely (end)'); }); }); this.connected = false; this.emit('connectionChanged', false); } } exports.RioConsole = RioConsole; //# sourceMappingURL=rioconsole.js.map