]> git.lizzy.rs Git - hydra-dragonfire.git/blobdiff - poll.go
Merge pull request #4 from Minetest-j45/master
[hydra-dragonfire.git] / poll.go
diff --git a/poll.go b/poll.go
index bfbe298ed6d6dcaeeaff326c82bf0bd1c0a029c8..dfc30a6fa0701a3d51f8e19fb472c8571a566841 100644 (file)
--- a/poll.go
+++ b/poll.go
@@ -1,89 +1,77 @@
 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++
-       }
+type Event interface {
+       handle(l *lua.LState, val lua.LValue)
+}
 
-       var timeout time.Duration
-       hasTimeout := false
-       if l.IsNumber(3) {
-               timeout = time.Duration(lua.CheckNumber(l, 3) * float64(time.Second))
-               hasTimeout = true
-       }
+type EventTimeout struct{}
 
-       for {
-               cases := make([]reflect.SelectCase, 0, len(clients)+2)
+func (evt EventTimeout) handle(l *lua.LState, val lua.LValue) {
+       l.SetField(val, "type", lua.LString("timeout"))
+}
 
-               for _, client := range clients {
-                       if client.state != csConnected {
-                               continue
-                       }
+type EventInterrupt struct{}
 
-                       cases = append(cases, reflect.SelectCase{
-                               Dir:  reflect.SelectRecv,
-                               Chan: reflect.ValueOf(client.queue),
-                       })
-               }
+func (evt EventInterrupt) handle(l *lua.LState, val lua.LValue) {
+       l.SetField(val, "type", lua.LString("interrupt"))
+}
 
-               offset := len(cases)
+func doPoll(l *lua.LState, clients []*Client) int {
+       cases := make([]reflect.SelectCase, 0, len(clients)+2)
 
-               if offset < 1 {
-                       l.PushBoolean(false)
-                       return 1
+       for _, client := range clients {
+               if client.state != csConnected {
+                       continue
                }
 
                cases = append(cases, reflect.SelectCase{
                        Dir:  reflect.SelectRecv,
-                       Chan: reflect.ValueOf(signalChannel()),
+                       Chan: reflect.ValueOf(client.queue),
                })
+       }
 
-               if hasTimeout {
-                       cases = append(cases, reflect.SelectCase{
-                               Dir:  reflect.SelectRecv,
-                               Chan: reflect.ValueOf(time.After(timeout)),
-                       })
-               }
+       offset := len(cases)
 
-               idx, value, ok := reflect.Select(cases)
+       if offset < 1 {
+               return 0
+       }
 
-               if idx >= offset {
-                       l.PushBoolean(true)
-                       return 1
-               }
+       cases = append(cases, reflect.SelectCase{
+               Dir:  reflect.SelectRecv,
+               Chan: reflect.ValueOf(signalChannel),
+       })
 
-               client := clients[idx]
+       if l.GetTop() > 1 {
+               timeout := time.After(time.Duration(float64(l.ToNumber(2)) * float64(time.Second)))
 
-               var pkt *mt.Pkt = nil
-               if ok {
-                       pkt = value.Interface().(*mt.Pkt)
-               } else {
-                       client.state = csDisconnected
-               }
+               cases = append(cases, reflect.SelectCase{
+                       Dir:  reflect.SelectRecv,
+                       Chan: reflect.ValueOf(timeout),
+               })
+       }
 
-               for _, handler := range client.handlers {
-                       handler.handle(pkt, l, idx+1)
-               }
+       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)
        }
 
-       panic("impossible")
-       return 0
+       evt.handle(l, tbl)
+
+       l.Push(tbl)
+       return 1
 }