-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevents.go
147 lines (133 loc) · 3.11 KB
/
events.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package main
import (
"github.com/veandco/go-sdl2/sdl"
"time"
)
type SdlEventStream struct {
closing chan chan error
events chan sdl.Event
thread *Thread
}
// NewSdlEventStream takes the sdl thread and returns the stream
// struct
func NewSdlEventStream(thread *Thread) *SdlEventStream {
ses := &SdlEventStream{
closing: make(chan chan error),
events: make(chan sdl.Event),
thread: thread,
}
go ses.loop()
return ses
}
func (ses *SdlEventStream) Close() error {
c := make(chan error)
ses.closing <- c
return <-c
}
// pollEvent polls an SDL event in the SDL thread
func (ses *SdlEventStream) pollEvent() sdl.Event {
es := ses.thread.Exec(func() interface{} {
return struct{ e sdl.Event }{sdl.PollEvent()}
}).(struct{ e sdl.Event })
return es.e
}
func (ses *SdlEventStream) loop() {
var err error
for {
evt := ses.pollEvent()
select {
case errc := <-ses.closing:
errc <- err
close(ses.events)
return
case <-time.After(1 * time.Second):
default:
if evt != nil {
ses.events <- evt
}
}
}
}
// Receive returns a read only channel where sdl Events will
// be submitted
func (ses *SdlEventStream) Receive() <-chan sdl.Event {
return ses.events
}
type subscribeMessage struct {
Key sdl.Keycode
Chan chan sdl.Event
}
// KeyEventSubscriber sfilters key events from an event stream
type EventSubscriber struct {
eventStream *SdlEventStream
eventChan <-chan sdl.Event
closing chan chan error
recepients map[sdl.Keycode][]chan sdl.Event
newSubscriber chan subscribeMessage
}
// NewKeyFilter returns an initialized KeyFilter
func NewEventSubscriber(stream *SdlEventStream) *EventSubscriber {
es := &EventSubscriber{}
es.eventStream = stream
es.eventChan = es.eventStream.Receive()
es.recepients = make(map[sdl.Keycode][]chan sdl.Event)
es.closing = make(chan chan error)
es.newSubscriber = make(chan subscribeMessage)
go es.loop()
return es
}
func (es *EventSubscriber) loop() {
var err error
for {
select {
case errc := <-es.closing:
errc <- err
return
case evt := <-es.eventChan:
switch et := evt.(type) {
case *sdl.KeyDownEvent:
for _, c := range es.recepients[et.Keysym.Sym] {
c <- evt
}
}
case sub := <-es.newSubscriber:
if es.recepients[sub.Key] == nil {
es.recepients[sub.Key] = []chan sdl.Event{sub.Chan}
} else {
es.recepients[sub.Key] = append(es.recepients[sub.Key], sub.Chan)
}
}
}
}
func (es *EventSubscriber) Subscribe(key sdl.Keycode) <-chan sdl.Event {
c := make(chan sdl.Event)
es.newSubscriber <- subscribeMessage{key, c}
return c
}
func (es *EventSubscriber) Close() error {
errc := make(chan error)
es.closing <- errc
return <-errc
}
// KeyDownEventHandler tackles KeyDown Events and executes action on correct key
func KeyDownEventHandler(key sdl.Keycode, action func(), quit chan bool) chan sdl.Event {
eventChan := make(chan sdl.Event)
go func() {
for {
select {
case e := <-eventChan:
switch et := e.(type) {
case *sdl.KeyDownEvent:
switch et.Keysym.Sym {
case key:
action()
}
}
case <-quit:
quit <- true
return
}
}
}()
return eventChan
}