-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpoll.go
77 lines (58 loc) · 1.43 KB
/
poll.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
package main
import (
"github.com/yuin/gopher-lua"
"reflect"
"time"
)
type Event interface {
handle(l *lua.LState, val lua.LValue)
}
type EventTimeout struct{}
func (evt EventTimeout) handle(l *lua.LState, val lua.LValue) {
l.SetField(val, "type", lua.LString("timeout"))
}
type EventInterrupt struct{}
func (evt EventInterrupt) handle(l *lua.LState, val lua.LValue) {
l.SetField(val, "type", lua.LString("interrupt"))
}
func doPoll(l *lua.LState, clients []*Client) int {
cases := make([]reflect.SelectCase, 0, len(clients)+2)
for _, client := range clients {
if client.state != csConnected {
continue
}
cases = append(cases, reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(client.queue),
})
}
offset := len(cases)
if offset < 1 {
return 0
}
cases = append(cases, reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(signalChannel),
})
if l.GetTop() > 1 {
timeout := time.After(time.Duration(float64(l.ToNumber(2)) * float64(time.Second)))
cases = append(cases, reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(timeout),
})
}
idx, value, _ := reflect.Select(cases)
var evt Event
tbl := l.NewTable()
if idx > offset {
evt = EventTimeout{}
} else if idx == offset {
evt = EventInterrupt{}
} else {
evt = value.Interface().(Event)
l.SetField(tbl, "client", clients[idx].userdata)
}
evt.handle(l, tbl)
l.Push(tbl)
return 1
}