wpilib-riolog
Version:
175 lines • 5.79 kB
JavaScript
'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