Skip to content

Commit ae03aa7

Browse files
committed
fix slight bugs, add event emitting for button presses and chorded button presses
1 parent e846fb3 commit ae03aa7

File tree

2 files changed

+69
-15
lines changed

2 files changed

+69
-15
lines changed

napi-rust-drivers/demo.js

+25-12
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,31 @@ async function main() {
6262
console.log('erased well', well.id)
6363
}
6464

65-
// plinth.wells.forEach((well, i) => {
66-
// well.onAButtonPress(getData(well))
67-
// well.onBButtonPress(getData(well))
68-
// well.onCButtonPress(getData(well))
69-
// })
70-
71-
erase(plinth.wells[0])
72-
console.log(plinth.wells[0].getData())
73-
plinth.wells[0].storeData({ hello: 'chukwudi'})
74-
console.log(plinth.wells[0].getData())
75-
plinth.wells[0].storeData({ hello: 'chukwudi', ohyeah: 'coolaid'})
76-
console.log(plinth.wells[0].getData())
65+
let logCallbackPress = function(well, buttonId) {
66+
return async () => {
67+
console.log('logging button press by callback: well', well.id, buttonId)
68+
}
69+
}
70+
71+
let logEventPress = function(well) {
72+
return (e) => {
73+
console.log('logging button press by event: well', e.well, e.button)
74+
}
75+
}
76+
77+
let logEventChordedPress = function(well) {
78+
return (e) => {
79+
console.log('logging chorded button press by event: well', e.well, e.buttons)
80+
}
81+
}
82+
83+
plinth.wells.forEach((well, i) => {
84+
well.onAButtonPress(logCallbackPress(well, 'a'))
85+
well.onBButtonPress(logCallbackPress(well, 'b'))
86+
well.onCButtonPress(logCallbackPress(well, 'c'))
87+
well.on('buttonPress', logEventPress(well))
88+
well.on('chordedButtonPress', logEventChordedPress(well))
89+
})
7790
}
7891

7992
main()

napi-rust-drivers/plinth.js

+44-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1+
let EventEmitter = require('events')
2+
let util = require('util')
3+
4+
let _ = require('lodash')
5+
16
let { JsPrototype, JsDevkit } = require('./nativeBinding')
27

3-
class Plinth {
8+
class Plinth extends EventEmitter {
49
constructor(model = 'devkit') {
10+
super()
11+
512
if (model == 'prototype') {
613
this.plinth = new JsPrototype()
714
}
@@ -21,15 +28,22 @@ class Plinth {
2128
}
2229
}
2330

24-
class Well {
31+
class Well extends EventEmitter {
2532
constructor(id, plinth) {
33+
super()
34+
2635
this.id = id
2736
this.plinth = plinth
2837
this.maxMemory = 4096 // bytes. basically 4kb
2938
this.dimensions = {
3039
x: 128,
3140
y: 296,
3241
}
42+
43+
this.buttonPressBuffer = new Map() // for detecting chorded button presses
44+
this.chordTimeout = 35 // amount of time in milliseconds between button presses which will count as being pressed at the same time to form a chord
45+
this.endOfChordTimer = setTimeout(()=>{}, 1)
46+
this.on('buttonPress', this._emitChordedButtonPress)
3347
}
3448

3549
// display an image on the e-paper display of the wyldcard present in this well
@@ -69,25 +83,52 @@ class Well {
6983
// register a callback to be called when Switch A (the top button) for this well is pressed
7084
onAButtonPress = function(cb) {
7185
validateCallback(cb)
86+
cb = this._wrapCallbackToEmitEvents(cb, 'a')
7287
this.plinth.setSwitchCallback(this.id, 'a', cb)
7388
}
7489

7590
// register a callback to be called when Switch B (the middle button) for this well is pressed
7691
onBButtonPress = function(cb) {
7792
validateCallback(cb)
93+
cb = this._wrapCallbackToEmitEvents(cb, 'b')
7894
this.plinth.setSwitchCallback(this.id, 'b', cb)
7995
}
8096

8197
// register a callback to be called when Switch C (the bottom button) for this well is pressed
8298
onCButtonPress = function(cb) {
8399
validateCallback(cb)
100+
cb = this._wrapCallbackToEmitEvents(cb, 'c')
84101
this.plinth.setSwitchCallback(this.id, 'c', cb)
85102
}
103+
104+
_wrapCallbackToEmitEvents = function(cb, buttonId) {
105+
let well = this
106+
107+
return async () => {
108+
well.emit('buttonPress', {well: well.id, button: buttonId, ts: Date.now()})
109+
cb()
110+
}
111+
}
112+
113+
_emitChordedButtonPress = function(buttonPressEvent) {
114+
let well = this
115+
clearTimeout(well.endOfChordTimer)
116+
let chordTimeout = well.chordTimeout
117+
well.buttonPressBuffer.set(buttonPressEvent.button, buttonPressEvent.ts)
118+
119+
let recentPresses = _.filter(Array.from(this.buttonPressBuffer.entries()), ([button, ts]) => ts > buttonPressEvent.ts - chordTimeout)
120+
recentPresses = recentPresses.map(([button, ts]) => button)
121+
122+
well.endOfChordTimer = setTimeout(() => {
123+
well.emit('chordedButtonPress', { well: well.id, buttons: recentPresses })
124+
well.buttonPressBuffer = new Map()
125+
}, chordTimeout)
126+
}
86127
}
87128

88129
function validateCallback(cb) {
89130
if (!util.types.isAsyncFunction(cb)) {
90-
throw new error('callbacks passed to `onXButtonPress()` handlers must be async functions')
131+
throw new Error('callbacks passed to `onXButtonPress()` handlers must be async functions')
91132
}
92133
}
93134

0 commit comments

Comments
 (0)