]> git.lizzy.rs Git - hydra-dragonfire.git/blob - poll.go
Migrate to gopher-lua
[hydra-dragonfire.git] / poll.go
1 package main
2
3 import (
4         "github.com/anon55555/mt"
5         "github.com/yuin/gopher-lua"
6         "reflect"
7         "time"
8 )
9
10 func doPoll(l *lua.LState, clients []*Client) (*Client, *mt.Pkt, bool) {
11         var timeout time.Duration
12         hasTimeout := false
13         if l.GetTop() > 1 {
14                 timeout = time.Duration(float64(l.ToNumber(2)) * float64(time.Second))
15                 hasTimeout = true
16         }
17
18         cases := make([]reflect.SelectCase, 0, len(clients)+2)
19         for _, client := range clients {
20                 if client.state != csConnected {
21                         continue
22                 }
23
24                 cases = append(cases, reflect.SelectCase{
25                         Dir:  reflect.SelectRecv,
26                         Chan: reflect.ValueOf(client.queue),
27                 })
28         }
29
30         offset := len(cases)
31
32         if offset < 1 {
33                 return nil, nil, false
34         }
35
36         cases = append(cases, reflect.SelectCase{
37                 Dir:  reflect.SelectRecv,
38                 Chan: reflect.ValueOf(signalChannel()),
39         })
40
41         if hasTimeout {
42                 cases = append(cases, reflect.SelectCase{
43                         Dir:  reflect.SelectRecv,
44                         Chan: reflect.ValueOf(time.After(timeout)),
45                 })
46         }
47
48         idx, value, ok := reflect.Select(cases)
49
50         if idx >= offset {
51                 return nil, nil, true
52         }
53
54         client := clients[idx]
55
56         var pkt *mt.Pkt = nil
57         if ok {
58                 pkt = value.Interface().(*mt.Pkt)
59         } else {
60                 client.state = csDisconnected
61         }
62
63         return client, pkt, false
64 }