Skip to content

Commit

Permalink
Fixes ButtonStatus not firing events.
Browse files Browse the repository at this point in the history
ButtonStatus was overwriting the "old state" of the button board
every time it got a chunk of serial data, whether an update packet
was complete or not. Oops. Turns out you never detect any events
that way.

Also adds a couple specs and does a little refactoring.
  • Loading branch information
mildmojo committed Sep 23, 2017
1 parent 3d15ca1 commit 2a756fd
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 14 deletions.
4 changes: 3 additions & 1 deletion lib/bitfield.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class Bitfield {
this.buffer = new Buffer(buffer.length);
buffer.copy(this.buffer);
} else if (isNumeric(buffer)) {
this.buffer = new Buffer(byteIndex(Math.floor(Number(buffer) - 1)) + 1);
let bitCount = Math.floor(Number(buffer));
let lastBitIdx = bitCount - 1;
this.buffer = new Buffer(byteIndex(lastBitIdx) + 1);
} else {
throw new Error('Bitfield constructor accepts a Buffer or an integer bitfield width');
}
Expand Down
11 changes: 5 additions & 6 deletions lib/buttonStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ const EventEmitter = require('events').EventEmitter;
const Bitfield = require('./bitfield');

class ButtonStatus extends EventEmitter {
constructor(mapping) {
constructor(mapping, packetByteLength = 8) {
super();
this.mapping = mapping;
this.state = new Bitfield(new Buffer(8));
this.oldState = new Bitfield(new Buffer(8));
this.state = new Bitfield(new Buffer(packetByteLength));
this.oldState = new Bitfield(new Buffer(packetByteLength));
this.dataQueue = new Buffer(0);
}

Expand All @@ -23,11 +23,10 @@ class ButtonStatus extends EventEmitter {
let seqCount = dataQueue.filter(byte => byte & 1).length;
if (seqCount === 0) return;

// Move current state to old state.
state.copyTo(oldState);

// Process each buffered sequence.
for (let seqNum = 0; seqNum < seqCount; seqNum++) {
// Move current state to old state.
state.copyTo(oldState);
state.copyFrom(dataQueue);
dataQueue = dataQueue.slice(state.length);
this._triggerEvents()
Expand Down
26 changes: 22 additions & 4 deletions test/bitfield_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,22 @@ describe('Bitfield', () => {
bfSrc = bfSrc.setAt(0, 0);
assert.notDeepEqual(bfDest.buffer, bfSrc.buffer);
});

it('should copy from a shorter bitfield', () => {
let bfSrc = Bitfield.fromBits([1,0,1]);
let bfDest = new Bitfield(Buffer.from([0x00, 0x00]));

bfDest.copyFrom(bfSrc);
assert.deepEqual(bfDest.toString(), "10100000000000");
})

it('should copy from a longer bitfield', () => {
let bfSrc = new Bitfield(Buffer.from([0x0E, 0xFE]));
let bfDest = new Bitfield(7);

bfDest.copyFrom(bfSrc);
assert.deepEqual(bfDest.toString(), "1110000");
});
});

describe('copyTo()', () => {
Expand Down Expand Up @@ -160,10 +176,12 @@ describe('Bitfield', () => {
let bf1 = Bitfield.fromBits([1,0,1]);
let bf2 = Bitfield.fromBits([1,1,0]);
let changeIdx = 1;
for (let {index, value} of bf1.xor(bf2)) {
assert.equal(index, changeIdx++)
assert.equal(value, bf1.at(index));
}
let changes = [...bf1.xor(bf2)];
assert.equal(changes.length, 2);
assert.equal(changes[0].index, 1);
assert.equal(changes[0].value, 0);
assert.equal(changes[1].index, 2);
assert.equal(changes[1].value, 1);
});
});
});
23 changes: 20 additions & 3 deletions test/buttonStatus_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('buttonStatus', () => {
let buttonStatus = null;

beforeEach(() => {
buttonStatus = new ButtonStatus([0,1,2]);
buttonStatus = new ButtonStatus([0,1,2,3,4,5,6,7]);
});

describe('update()', () => {
Expand All @@ -30,6 +30,23 @@ describe('buttonStatus', () => {
buttonStatus.update(Buffer.from([0x07]));
});

it('should fire buttonDown event when updating with partial packets', done => {
let buttonsDown = [];
let packetBytes = [0x02, 0x00, 0x01];

buttonStatus.on('buttonDown', button => {
assert.equal(button, 0);
done();
});

function update(bytes) {
buttonStatus.update(Buffer.from([bytes.shift()]));
if (bytes.length > 0) setImmediate(() => update(bytes), 100);
}

update(packetBytes);
});

it('should fire buttonUp event', done => {
let buttonsUp = [];

Expand All @@ -51,8 +68,8 @@ describe('buttonStatus', () => {
let json = buttonStatus.toJSON();
assert.ok('length' in json);
assert.ok('buttons' in json);
assert.equal(json.length, 3);
assert.deepEqual(json.buttons, {0:0, 1:0, 2:0});
assert.equal(json.length, 8);
assert.deepEqual(json.buttons, {0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0});
});
});
})

0 comments on commit 2a756fd

Please sign in to comment.