Skip to content

Commit 109e751

Browse files
committed
Benchmark implementation to ensure it can keep up
1 parent 18a42a8 commit 109e751

File tree

3 files changed

+56
-21
lines changed

3 files changed

+56
-21
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ go:
77
- 1.10.x
88
- 1.11.x
99
- master
10+
scripts:
11+
- go test -race && go test -bench=.

dualshock.go

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ package dualshock
33
import (
44
"encoding/binary"
55
"io"
6-
"time"
76
)
87

98
// Controller describes the reference to the hardware device
109
type Controller struct {
1110
reader io.Reader
12-
queue chan State
11+
queue chan []byte
12+
errors chan error
1313
interrupt chan int
1414
}
1515

@@ -88,13 +88,13 @@ func transform(b []byte) State {
8888
TrackPad0: TrackPad{
8989
ID: int(b[35] & 0x7f),
9090
Active: (b[35] >> 7) == 0,
91-
X: int(((b[37] & 0x0f) << 8) | b[36]),
91+
X: int(((b[37] & 0x0f) << 4) | b[36]),
9292
Y: int(b[38]<<4 | ((b[37] & 0xf0) >> 4)),
9393
},
9494
TrackPad1: TrackPad{
9595
ID: int(b[39] & 0x7f),
9696
Active: (b[39] >> 7) == 0,
97-
X: int(((b[41] & 0x0f) << 8) | b[40]),
97+
X: int(((b[41] & 0x0f) << 4) | b[40]),
9898
Y: int(b[42]<<4 | ((b[41] & 0xf0) >> 4)),
9999
},
100100
LeftDPad: DPad{
@@ -127,43 +127,60 @@ func transform(b []byte) State {
127127
// New returns a new controller which transforms input from the device to a valid
128128
// controller state
129129
func New(reader io.Reader) *Controller {
130-
c := &Controller{reader, make(chan State), make(chan int, 2)}
130+
c := &Controller{
131+
reader,
132+
make(chan []byte),
133+
make(chan error),
134+
make(chan int),
135+
}
131136
go c.read()
132137
return c
133138
}
134139

135140
// read transforms data from the io.Reader and pushes it to the queue of
136141
// states
137142
func (c *Controller) read() {
143+
var b []byte
138144
for {
139145
select {
140146
case <-c.interrupt:
147+
close(c.errors)
148+
close(c.queue)
141149
return
142150
default:
143-
b := make([]byte, 64)
144-
c.reader.Read(b)
145-
c.queue <- transform(b)
146-
time.Sleep((1000 / 254) * time.Millisecond)
151+
b = make([]byte, 64)
152+
n, err := c.reader.Read(b)
153+
154+
if err != nil {
155+
c.errors <- err
156+
continue
157+
}
158+
159+
c.queue <- b[:n]
147160
}
148161
}
149162
}
150163

151164
// Listen for controller state changes
152-
func (c *Controller) Listen(handler func(State)) {
153-
for {
154-
select {
155-
case <-c.interrupt:
156-
return
157-
default:
158-
handler(<-c.queue)
165+
func (c *Controller) Listen(handle func(State)) {
166+
go func() {
167+
for {
168+
select {
169+
case <-c.interrupt:
170+
return
171+
default:
172+
handle(transform(<-c.queue))
173+
}
159174
}
160-
}
175+
}()
176+
}
177+
178+
// Errors returns a channel of reader errors
179+
func (c *Controller) Errors() <-chan error {
180+
return c.errors
161181
}
162182

163183
// Close the listener
164184
func (c *Controller) Close() {
165-
c.interrupt <- 1 // close reader
166-
c.interrupt <- 1 // close listener
167185
close(c.interrupt)
168-
close(c.queue)
169186
}

dualshock_test.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ func (f fakeDevice) Read(b []byte) (int, error) {
1515
129, 115, 70, 27, 130, 62, 97, 32, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0,
1616
128, 0, 0, 0, 128, 0, 0, 0, 0, 128, 0,
1717
})
18-
return 0, nil
18+
return 64, nil
1919
}
2020

2121
func TestDualshock(t *testing.T) {
2222
controller := dualshock.New(fakeDevice{})
2323

2424
result := make(chan dualshock.State, 1)
25+
defer close(result)
26+
2527
controller.Listen(func(state dualshock.State) {
2628
controller.Close()
2729
result <- state
@@ -31,3 +33,17 @@ func TestDualshock(t *testing.T) {
3133
t.Errorf("Invalid state L2 should be true; got %v", r.L2)
3234
}
3335
}
36+
37+
func BenchmarkDualshock(b *testing.B) {
38+
controller := dualshock.New(fakeDevice{})
39+
40+
result := make(chan dualshock.State, 1)
41+
42+
controller.Listen(func(state dualshock.State) {
43+
result <- state
44+
})
45+
46+
for n := 0; n < b.N; n++ {
47+
<-result
48+
}
49+
}

0 commit comments

Comments
 (0)