]> git.lizzy.rs Git - hydra-dragonfire.git/blob - poll.go
Merge pull request #4 from Minetest-j45/master
[hydra-dragonfire.git] / poll.go
1 package main
2
3 import (
4         "github.com/yuin/gopher-lua"
5         "reflect"
6         "time"
7 )
8
9 type Event interface {
10         handle(l *lua.LState, val lua.LValue)
11 }
12
13 type EventTimeout struct{}
14
15 func (evt EventTimeout) handle(l *lua.LState, val lua.LValue) {
16         l.SetField(val, "type", lua.LString("timeout"))
17 }
18
19 type EventInterrupt struct{}
20
21 func (evt EventInterrupt) handle(l *lua.LState, val lua.LValue) {
22         l.SetField(val, "type", lua.LString("interrupt"))
23 }
24
25 func doPoll(l *lua.LState, clients []*Client) int {
26         cases := make([]reflect.SelectCase, 0, len(clients)+2)
27
28         for _, client := range clients {
29                 if client.state != csConnected {
30                         continue
31                 }
32
33                 cases = append(cases, reflect.SelectCase{
34                         Dir:  reflect.SelectRecv,
35                         Chan: reflect.ValueOf(client.queue),
36                 })
37         }
38
39         offset := len(cases)
40
41         if offset < 1 {
42                 return 0
43         }
44
45         cases = append(cases, reflect.SelectCase{
46                 Dir:  reflect.SelectRecv,
47                 Chan: reflect.ValueOf(signalChannel),
48         })
49
50         if l.GetTop() > 1 {
51                 timeout := time.After(time.Duration(float64(l.ToNumber(2)) * float64(time.Second)))
52
53                 cases = append(cases, reflect.SelectCase{
54                         Dir:  reflect.SelectRecv,
55                         Chan: reflect.ValueOf(timeout),
56                 })
57         }
58
59         idx, value, _ := reflect.Select(cases)
60
61         var evt Event
62         tbl := l.NewTable()
63
64         if idx > offset {
65                 evt = EventTimeout{}
66         } else if idx == offset {
67                 evt = EventInterrupt{}
68         } else {
69                 evt = value.Interface().(Event)
70                 l.SetField(tbl, "client", clients[idx].userdata)
71         }
72
73         evt.handle(l, tbl)
74
75         l.Push(tbl)
76         return 1
77 }