1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
package gui
import (
"image"
"image/draw"
"time"
"git.samanthony.xyz/share"
)
const timeout = 1 * time.Second
// trySend returns true if v can be sent to c within timeout, or false otherwise.
func trySend[T any](c chan<- T, v T, timeout time.Duration) bool {
timer := time.NewTimer(timeout)
select {
case c <- v:
return true
case <-timer.C:
return false
}
}
// tryRecv returns the value received from c, or false if no value is received within timeout.
func tryRecv[T any](c <-chan T, timeout time.Duration) (*T, bool) {
timer := time.NewTimer(timeout)
select {
case v := <-c:
return &v, true
case <-timer.C:
return nil, false
}
}
type dummyEnv struct {
events share.Queue[Event]
drawIn chan<- func(draw.Image) image.Rectangle
drawOut <-chan func(draw.Image) image.Rectangle
kill chan<- bool
dead <-chan bool
attachChan chan<- victim
}
func newDummyEnv(size image.Rectangle) dummyEnv {
events := share.NewQueue[Event]()
drawIn := make(chan func(draw.Image) image.Rectangle)
drawOut := make(chan func(draw.Image) image.Rectangle)
kill := make(chan bool)
dead := make(chan bool)
child := newKiller()
go func() {
defer func() {
dead <- true
close(dead)
}()
defer close(kill)
defer close(drawOut)
defer close(drawIn)
defer close(events.Enqueue)
defer func() {
go drain(drawIn)
child.Kill() <- true
<-child.Dead()
}()
for {
select {
case d := <-drawIn:
drawOut <- d
case <-kill:
return
}
}
}()
events.Enqueue <- Resize{size}
return dummyEnv{events, drawIn, drawOut, kill, dead, child.attach()}
}
func (de dummyEnv) Events() <-chan Event {
return de.events.Dequeue
}
func (de dummyEnv) Draw() chan<- func(draw.Image) image.Rectangle {
return de.drawIn
}
func (de dummyEnv) Kill() chan<- bool {
return de.kill
}
func (de dummyEnv) Dead() <-chan bool {
return de.dead
}
func (de dummyEnv) attach() chan<- victim {
return de.attachChan
}
type dummyEvent struct {
s string
}
func (e dummyEvent) String() string {
return e.s
}
|