diff options
Diffstat (limited to 'poll.go')
-rw-r--r-- | poll.go | 97 |
1 files changed, 36 insertions, 61 deletions
@@ -1,89 +1,64 @@ package main import ( - "github.com/Shopify/go-lua" "github.com/anon55555/mt" + "github.com/yuin/gopher-lua" "reflect" "time" ) -func l_poll(l *lua.State) int { - clients := make([]*Client, 0) - - lua.CheckType(l, 1, lua.TypeTable) - i := 1 - for { - l.RawGetInt(1, i) - if l.IsNil(-1) { - l.Pop(1) - break - } - - clients = append(clients, l.ToUserData(-1).(*Client)) - i++ - } - +func doPoll(l *lua.LState, clients []*Client) (*Client, *mt.Pkt, bool) { var timeout time.Duration hasTimeout := false - if l.IsNumber(3) { - timeout = time.Duration(lua.CheckNumber(l, 3) * float64(time.Second)) + if l.GetTop() > 1 { + timeout = time.Duration(float64(l.ToNumber(2)) * float64(time.Second)) hasTimeout = true } - for { - cases := make([]reflect.SelectCase, 0, len(clients)+2) + cases := make([]reflect.SelectCase, 0, len(clients)+2) + for _, client := range clients { + if client.state != csConnected { + continue + } - for _, client := range clients { - if client.state != csConnected { - continue - } + cases = append(cases, reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(client.queue), + }) + } - cases = append(cases, reflect.SelectCase{ - Dir: reflect.SelectRecv, - Chan: reflect.ValueOf(client.queue), - }) - } + offset := len(cases) - offset := len(cases) + if offset < 1 { + return nil, nil, false + } - if offset < 1 { - l.PushBoolean(false) - return 1 - } + cases = append(cases, reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(signalChannel()), + }) + if hasTimeout { cases = append(cases, reflect.SelectCase{ Dir: reflect.SelectRecv, - Chan: reflect.ValueOf(signalChannel()), + Chan: reflect.ValueOf(time.After(timeout)), }) + } - if hasTimeout { - cases = append(cases, reflect.SelectCase{ - Dir: reflect.SelectRecv, - Chan: reflect.ValueOf(time.After(timeout)), - }) - } - - idx, value, ok := reflect.Select(cases) - - if idx >= offset { - l.PushBoolean(true) - return 1 - } + idx, value, ok := reflect.Select(cases) - client := clients[idx] + if idx >= offset { + return nil, nil, true + } - var pkt *mt.Pkt = nil - if ok { - pkt = value.Interface().(*mt.Pkt) - } else { - client.state = csDisconnected - } + client := clients[idx] - for _, handler := range client.handlers { - handler.handle(pkt, l, idx+1) - } + var pkt *mt.Pkt = nil + if ok { + pkt = value.Interface().(*mt.Pkt) + } else { + client.state = csDisconnected } - panic("impossible") - return 0 + return client, pkt, false } |