/
window.go
129 lines (114 loc) · 2.36 KB
/
window.go
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package win
import (
"runtime"
"github.com/go-gl/gl/v2.1/gl"
"github.com/go-gl/glfw/v3.2/glfw"
)
// Represents a single window.
type Window struct {
id uint64
gw *glfw.Window
closing chan struct{}
closed chan struct{}
pev chan interface{}
ev chan interface{}
}
func (w *Window) run(f func(*Window)) {
runtime.LockOSThread()
w.gw.MakeContextCurrent()
glfw.SwapInterval(1)
gl.Init()
f(w)
}
// Swap the front and back buffers.
func (w *Window) Swap() {
w.gw.SwapBuffers()
}
// Return this window's event channel.
func (w *Window) Events() <-chan interface{} {
return w.ev
}
// Try to read a single event off the event channel, or return nil if none are buffered.
func (w *Window) Poll() interface{} {
for {
select {
case ie := <-w.Events():
return ie
default:
return nil
}
}
}
// Close this window.
func (w *Window) Destroy() {
close(w.closing)
<-w.closed
}
func (w *Window) initialize() {
w.closing = make(chan struct{})
w.closed = make(chan struct{})
w.pev = make(chan interface{}, 10)
w.ev = make(chan interface{}, 1000)
go func() {
in := w.pev
out := w.ev
out = nil
// TODO: Buffer this so we never block?
var stored interface{}
defer close(w.closed)
defer close(w.ev)
for {
select {
case e := <-in:
stored = e
in = nil
out = w.ev
case out <- stored:
stored = nil
in = w.pev
out = nil
case <-w.closing:
go func() {
for range w.pev {
}
}()
return
}
}
}()
w.gw.SetSizeCallback(func(gw *glfw.Window, width, height int) {
w.pev <- EventResize{
Width: width,
Height: height,
}
})
w.gw.SetCloseCallback(func(gw *glfw.Window) {
w.pev <- EventClose{}
})
w.gw.SetKeyCallback(func(gw *glfw.Window, key glfw.Key, scanCode int, action glfw.Action, mod glfw.ModifierKey) {
w.pev <- EventKey{
Key: Key(key),
ScanCode: scanCode,
Action: Action(action),
Mod: Mod(mod),
}
})
w.gw.SetCharCallback(func(gw *glfw.Window, key rune) {
w.pev <- EventChar{
Char: key,
}
})
w.gw.SetCursorPosCallback(func(gw *glfw.Window, x, y float64) {
w.pev <- EventMousePos{
X: int(x),
Y: int(y),
}
})
w.gw.SetMouseButtonCallback(func(gw *glfw.Window, button glfw.MouseButton, action glfw.Action, mod glfw.ModifierKey) {
w.pev <- EventMouseButton{
Button: Button(button),
Action: Action(action),
Mod: Mod(mod),
}
})
}