refresh neither leaks wraps, allows 2 of the same at once, nor closes raws

master
bel 2023-03-25 10:50:39 -06:00
parent 97cc3ae151
commit ae1e32391c
18 changed files with 94 additions and 64 deletions

View File

@ -9,6 +9,7 @@ import (
type Parser interface {
Read() []Button
Close()
CloseWrap() raw.Raw
}
func New(ctx context.Context, src raw.Raw) Parser {

View File

@ -23,6 +23,8 @@ func NewPlaintext(src raw.Raw) Plaintext {
func (p Plaintext) Close() { p.src.Close() }
func (p Plaintext) CloseWrap() raw.Raw { return p.src }
func (p Plaintext) Read() []Button {
b := p.src.Read()
buttons := make([]Button, 0, len(b))

View File

@ -22,8 +22,6 @@ func TestPlaintext(t *testing.T) {
type constSrc string
func (c constSrc) Refresh() {}
func (c constSrc) Close() {}
func (c constSrc) Read() []byte {

View File

@ -52,6 +52,11 @@ func NewV01(ctx context.Context, src raw.Raw) V01 {
}
}
func (v01 V01) CloseWrap() raw.Raw {
v01.can()
return v01.src
}
func (v01 V01) Close() {
v01.can()
v01.src.Close()

View File

@ -15,7 +15,6 @@ type Input interface {
func New(ctx context.Context) Input {
src := raw.New(ctx)
return wrap.New(ctx, func() button.Parser {
src.Refresh()
return button.New(ctx, src)
})
}

View File

@ -3,6 +3,7 @@ package input_test
import (
"context"
"mayhem-party/src/device/input"
"mayhem-party/src/device/input/wrap"
"os"
"path"
"testing"
@ -30,10 +31,10 @@ func TestNewRemapped(t *testing.T) {
t.Fatal(err)
}
os.Setenv("WRAP_REMAP_FILE", remap)
wrap.FlagRemapFile = remap
os.Setenv("RAW_RANDOM_WEIGHT_FILE", rand)
t.Cleanup(func() {
os.Unsetenv("WRAP_REMAP_FILE")
wrap.FlagRemapFile = ""
os.Unsetenv("RAW_RANDOM_WEIGHT_FILE")
})
@ -50,9 +51,9 @@ func TestNewRemapped(t *testing.T) {
}
func TestNewBuffered(t *testing.T) {
os.Setenv("WRAP_BUFFERED", "true")
wrap.FlagBuffered = true
t.Cleanup(func() {
os.Unsetenv("WRAP_BUFFERED")
wrap.FlagBuffered = false
})
r := input.New(context.Background())

View File

@ -31,9 +31,6 @@ func NewKeyboard() Keyboard {
return Keyboard{}
}
func (kb Keyboard) Refresh() {
}
func (kb Keyboard) Close() {
switch runtime.GOOS {
case "linux":

View File

@ -22,9 +22,6 @@ func NewRandom(generator func() byte) *Random {
return &Random{generator: generator}
}
func (r *Random) Refresh() {
}
func (r *Random) Close() {
}

View File

@ -9,7 +9,6 @@ import (
type Raw interface {
Read() []byte
Close()
Refresh()
}
func New(ctx context.Context) Raw {

View File

@ -55,9 +55,6 @@ func (udp UDP) Read() []byte {
}
}
func (udp UDP) Refresh() {
}
func (udp UDP) Close() {
udp.conn.Close()
}

View File

@ -3,6 +3,7 @@ package wrap
import (
"context"
"mayhem-party/src/device/input/button"
"mayhem-party/src/device/input/raw"
"os"
"sync"
"time"
@ -57,6 +58,11 @@ func (b *Buffered) listen() {
}
}
func (b *Buffered) CloseWrap() raw.Raw {
b.can()
return b.input.CloseWrap()
}
func (b *Buffered) Close() {
b.input.Close()
b.can()

View File

@ -1,24 +0,0 @@
package wrap
import (
"mayhem-party/src/device/input/button"
"mayhem-party/src/device/input/raw"
)
type Protocol struct {
src raw.Raw
}
func NewProtocol(src raw.Raw) Protocol {
return Protocol{
src: src,
}
}
func (p Protocol) Close() {
p.src.Close()
}
func (p Protocol) Read() []button.Button {
panic(nil)
}

View File

@ -4,13 +4,14 @@ import (
"context"
"log"
"mayhem-party/src/device/input/button"
"mayhem-party/src/device/input/raw"
"os"
"os/signal"
"syscall"
)
var (
ChanSigUsr1 = func() chan os.Signal {
chSigUsr1 = func() chan os.Signal {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGUSR1)
return c
@ -22,12 +23,12 @@ type Refresh struct {
input Wrap
}
func NewRefresh(newWrap func() Wrap) *Refresh {
return NewRefreshWith(newWrap, ChanSigUsr1)
func NewRefresh(ctx context.Context, newWrap func() Wrap) *Refresh {
return NewRefreshWith(ctx, newWrap, chSigUsr1)
}
func NewRefreshWith(newWrap func() Wrap, ch <-chan os.Signal) *Refresh {
ctx, can := context.WithCancel(context.Background())
func NewRefreshWith(ctx context.Context, newWrap func() Wrap, ch <-chan os.Signal) *Refresh {
ctx, can := context.WithCancel(ctx)
result := &Refresh{
can: can,
input: newWrap(),
@ -40,16 +41,19 @@ func NewRefreshWith(newWrap func() Wrap, ch <-chan os.Signal) *Refresh {
return
case sig := <-ch:
log.Println("refreshing for", sig)
newInput := newWrap()
oldInput := result.input
result.input = newInput
oldInput.Close()
result.input.CloseWrap()
result.input = newWrap()
}
}
}()
return result
}
func (r *Refresh) CloseWrap() raw.Raw {
r.can()
return r.input.CloseWrap()
}
func (r *Refresh) Read() []button.Button {
return r.input.Read()
}

View File

@ -1,6 +1,8 @@
package wrap
import (
"context"
"mayhem-party/src/device/input/button"
"os"
"syscall"
"testing"
@ -15,7 +17,7 @@ func TestRefresh(t *testing.T) {
}
ch := make(chan os.Signal, 1)
defer close(ch)
refresh := NewRefreshWith(generator, ch)
refresh := NewRefreshWith(context.Background(), generator, ch)
defer refresh.Close()
assertIts := func(t *testing.T, b byte) {
@ -42,3 +44,51 @@ func TestRefresh(t *testing.T) {
assertIts(t, byte('c'))
})
}
func TestRefreshDoesntCloseSources(t *testing.T) {
src := &telemetrySrc{}
newParsers := 0
newParser := func() Wrap {
newParsers += 1
return button.NewPlaintext(src)
}
ctx, can := context.WithCancel(context.Background())
defer can()
refresh := NewRefresh(ctx, newParser)
if newParsers != 1 {
t.Error(newParsers)
}
for i := 0; i < 5; i++ {
refresh.Read()
}
if want := (telemetrySrc{reads: 5}); *src != want {
t.Errorf("%+v", *src)
} else if newParsers != 1 {
t.Error(newParsers)
}
for i := 0; i < 5; i++ {
chSigUsr1 <- syscall.SIGINT
}
time.Sleep(time.Millisecond * 250)
if want := (telemetrySrc{reads: 5}); *src != want {
t.Errorf("want %+v, got %+v", want, *src)
} else if newParsers != 6 {
t.Error(newParsers)
}
}
type telemetrySrc struct {
closes int
reads int
}
func (src *telemetrySrc) Close() {
src.closes += 1
}
func (src *telemetrySrc) Read() []byte {
src.reads += 1
return []byte("foo")
}

View File

@ -2,6 +2,7 @@ package wrap
import (
"mayhem-party/src/device/input/button"
"mayhem-party/src/device/input/raw"
"os"
"github.com/go-yaml/yaml"
@ -38,6 +39,10 @@ func NewRemap(input Wrap, m map[byte]byte) Remap {
}
}
func (re Remap) CloseWrap() raw.Raw {
return re.input.CloseWrap()
}
func (re Remap) Close() {
re.input.Close()
}

View File

@ -3,6 +3,7 @@ package wrap
import (
"context"
"mayhem-party/src/device/input/button"
"mayhem-party/src/device/input/raw"
"os"
)
@ -15,6 +16,7 @@ var (
type Wrap interface {
Read() []button.Button
Close()
CloseWrap() raw.Raw
}
func New(ctx context.Context, srcFunc func() button.Parser) Wrap {
@ -36,7 +38,7 @@ func New(ctx context.Context, srcFunc func() button.Parser) Wrap {
if FlagRefreshOnSigUsr1 {
oldMaker := maker
maker = func() Wrap {
return NewRefresh(oldMaker)
return NewRefresh(ctx, oldMaker)
}
}
return maker()

View File

@ -1,10 +0,0 @@
package wrap_test
import (
"mayhem-party/src/device/input/wrap"
"testing"
)
func TestNewRefreshing(t *testing.T) {
wrap.FlagBuffered = true
}

View File

@ -2,6 +2,7 @@ package wrap
import (
"mayhem-party/src/device/input/button"
"mayhem-party/src/device/input/raw"
"testing"
)
@ -10,12 +11,12 @@ func TestWrap(t *testing.T) {
var _ Wrap = &Refresh{}
var _ Wrap = &Buffered{}
var _ Wrap = &Remap{}
var _ Wrap = Protocol{}
}
type dummyParser button.Button
func (d dummyParser) Close() {}
func (d dummyParser) CloseWrap() raw.Raw { return nil }
func (d dummyParser) Close() {}
func (d dummyParser) Read() []button.Button {
return []button.Button{button.Button(d)}
}