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
}