1
+ let EventEmitter = require ( 'events' )
2
+ let util = require ( 'util' )
3
+
4
+ let _ = require ( 'lodash' )
5
+
1
6
let { JsPrototype, JsDevkit } = require ( './nativeBinding' )
2
7
3
- class Plinth {
8
+ class Plinth extends EventEmitter {
4
9
constructor ( model = 'devkit' ) {
10
+ super ( )
11
+
5
12
if ( model == 'prototype' ) {
6
13
this . plinth = new JsPrototype ( )
7
14
}
@@ -21,15 +28,22 @@ class Plinth {
21
28
}
22
29
}
23
30
24
- class Well {
31
+ class Well extends EventEmitter {
25
32
constructor ( id , plinth ) {
33
+ super ( )
34
+
26
35
this . id = id
27
36
this . plinth = plinth
28
37
this . maxMemory = 4096 // bytes. basically 4kb
29
38
this . dimensions = {
30
39
x : 128 ,
31
40
y : 296 ,
32
41
}
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 )
33
47
}
34
48
35
49
// display an image on the e-paper display of the wyldcard present in this well
@@ -69,25 +83,52 @@ class Well {
69
83
// register a callback to be called when Switch A (the top button) for this well is pressed
70
84
onAButtonPress = function ( cb ) {
71
85
validateCallback ( cb )
86
+ cb = this . _wrapCallbackToEmitEvents ( cb , 'a' )
72
87
this . plinth . setSwitchCallback ( this . id , 'a' , cb )
73
88
}
74
89
75
90
// register a callback to be called when Switch B (the middle button) for this well is pressed
76
91
onBButtonPress = function ( cb ) {
77
92
validateCallback ( cb )
93
+ cb = this . _wrapCallbackToEmitEvents ( cb , 'b' )
78
94
this . plinth . setSwitchCallback ( this . id , 'b' , cb )
79
95
}
80
96
81
97
// register a callback to be called when Switch C (the bottom button) for this well is pressed
82
98
onCButtonPress = function ( cb ) {
83
99
validateCallback ( cb )
100
+ cb = this . _wrapCallbackToEmitEvents ( cb , 'c' )
84
101
this . plinth . setSwitchCallback ( this . id , 'c' , cb )
85
102
}
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
+ }
86
127
}
87
128
88
129
function validateCallback ( cb ) {
89
130
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' )
91
132
}
92
133
}
93
134
0 commit comments