refresher input

master
Bel LaPointe 2023-03-24 11:46:55 -06:00
parent 37d02f0f52
commit e491cc5cbc
3 changed files with 91 additions and 0 deletions

View File

@ -7,4 +7,5 @@ func TestInput(t *testing.T) {
var _ Input = Keyboard{}
var _ Input = &Buffered{}
var _ Input = Remap{}
var _ Input = &Refresh{}
}

View File

@ -0,0 +1,46 @@
package input
import (
"context"
"log"
"os"
"os/signal"
)
type Refresh struct {
can context.CancelFunc
input Input
}
func NewRefreshCh(sig os.Signal) <-chan os.Signal {
c := make(chan os.Signal, 1)
signal.Notify(c, sig)
return c
}
func NewRefresh(newInput func() Input, ch <-chan os.Signal) *Refresh {
ctx, can := context.WithCancel(context.Background())
result := &Refresh{
can: can,
input: newInput(),
}
go func() {
select {
case <-ctx.Done():
return
case sig := <-ch:
log.Println("refreshing for", sig)
result.input = newInput()
}
}()
return result
}
func (r *Refresh) Read() []Button {
return r.input.Read()
}
func (r *Refresh) Close() {
r.can()
r.input.Close()
}

View File

@ -0,0 +1,44 @@
package input
import (
"os"
"syscall"
"testing"
"time"
)
func TestRefresh(t *testing.T) {
b := byte('a')
generator := func() Input {
b += byte(1)
return NewRandom(func() byte { return b })
}
ch := make(chan os.Signal, 1)
defer close(ch)
refresh := NewRefresh(generator, ch)
defer refresh.Close()
assertIts := func(t *testing.T, b byte) {
for i := 0; i < 10; i++ {
some := false
for j, button := range refresh.Read() {
some = true
if button.Char != b {
t.Error(i, j, b, button)
}
}
if !some {
t.Error("empty read")
}
}
}
t.Run("called once on init", func(t *testing.T) {
assertIts(t, byte('b'))
})
ch <- syscall.SIGUSR1
time.Sleep(time.Millisecond * 450)
t.Run("called once on signal", func(t *testing.T) {
assertIts(t, byte('c'))
})
}