mirror of
https://github.com/akyaiy/GoSally-mvp.git
synced 2026-01-08 09:12:25 +00:00
Project structure refactor:
- Change package name general_server to gateway - Changing the structure of directories and packages - Adding vendor to the project
This commit is contained in:
184
vendor/github.com/yuin/gopher-lua/channellib.go
generated
vendored
Normal file
184
vendor/github.com/yuin/gopher-lua/channellib.go
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
package lua
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func checkChannel(L *LState, idx int) reflect.Value {
|
||||
ch := L.CheckChannel(idx)
|
||||
return reflect.ValueOf(ch)
|
||||
}
|
||||
|
||||
func checkGoroutineSafe(L *LState, idx int) LValue {
|
||||
v := L.CheckAny(2)
|
||||
if !isGoroutineSafe(v) {
|
||||
L.ArgError(2, "can not send a function, userdata, thread or table that has a metatable")
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func OpenChannel(L *LState) int {
|
||||
var mod LValue
|
||||
//_, ok := L.G.builtinMts[int(LTChannel)]
|
||||
// if !ok {
|
||||
mod = L.RegisterModule(ChannelLibName, channelFuncs)
|
||||
mt := L.SetFuncs(L.NewTable(), channelMethods)
|
||||
mt.RawSetString("__index", mt)
|
||||
L.G.builtinMts[int(LTChannel)] = mt
|
||||
// }
|
||||
L.Push(mod)
|
||||
return 1
|
||||
}
|
||||
|
||||
var channelFuncs = map[string]LGFunction{
|
||||
"make": channelMake,
|
||||
"select": channelSelect,
|
||||
}
|
||||
|
||||
func channelMake(L *LState) int {
|
||||
buffer := L.OptInt(1, 0)
|
||||
L.Push(LChannel(make(chan LValue, buffer)))
|
||||
return 1
|
||||
}
|
||||
|
||||
func channelSelect(L *LState) int {
|
||||
//TODO check case table size
|
||||
cases := make([]reflect.SelectCase, L.GetTop())
|
||||
top := L.GetTop()
|
||||
for i := 0; i < top; i++ {
|
||||
cas := reflect.SelectCase{
|
||||
Dir: reflect.SelectSend,
|
||||
Chan: reflect.ValueOf(nil),
|
||||
Send: reflect.ValueOf(nil),
|
||||
}
|
||||
tbl := L.CheckTable(i + 1)
|
||||
dir, ok1 := tbl.RawGetInt(1).(LString)
|
||||
if !ok1 {
|
||||
L.ArgError(i+1, "invalid select case")
|
||||
}
|
||||
switch string(dir) {
|
||||
case "<-|":
|
||||
ch, ok := tbl.RawGetInt(2).(LChannel)
|
||||
if !ok {
|
||||
L.ArgError(i+1, "invalid select case")
|
||||
}
|
||||
cas.Chan = reflect.ValueOf((chan LValue)(ch))
|
||||
v := tbl.RawGetInt(3)
|
||||
if !isGoroutineSafe(v) {
|
||||
L.ArgError(i+1, "can not send a function, userdata, thread or table that has a metatable")
|
||||
}
|
||||
cas.Send = reflect.ValueOf(v)
|
||||
case "|<-":
|
||||
ch, ok := tbl.RawGetInt(2).(LChannel)
|
||||
if !ok {
|
||||
L.ArgError(i+1, "invalid select case")
|
||||
}
|
||||
cas.Chan = reflect.ValueOf((chan LValue)(ch))
|
||||
cas.Dir = reflect.SelectRecv
|
||||
case "default":
|
||||
cas.Dir = reflect.SelectDefault
|
||||
default:
|
||||
L.ArgError(i+1, "invalid channel direction:"+string(dir))
|
||||
}
|
||||
cases[i] = cas
|
||||
}
|
||||
|
||||
if L.ctx != nil {
|
||||
cases = append(cases, reflect.SelectCase{
|
||||
Dir: reflect.SelectRecv,
|
||||
Chan: reflect.ValueOf(L.ctx.Done()),
|
||||
Send: reflect.ValueOf(nil),
|
||||
})
|
||||
}
|
||||
|
||||
pos, recv, rok := reflect.Select(cases)
|
||||
|
||||
if L.ctx != nil && pos == L.GetTop() {
|
||||
return 0
|
||||
}
|
||||
|
||||
lv := LNil
|
||||
if recv.Kind() != 0 {
|
||||
lv, _ = recv.Interface().(LValue)
|
||||
if lv == nil {
|
||||
lv = LNil
|
||||
}
|
||||
}
|
||||
tbl := L.Get(pos + 1).(*LTable)
|
||||
last := tbl.RawGetInt(tbl.Len())
|
||||
if last.Type() == LTFunction {
|
||||
L.Push(last)
|
||||
switch cases[pos].Dir {
|
||||
case reflect.SelectRecv:
|
||||
if rok {
|
||||
L.Push(LTrue)
|
||||
} else {
|
||||
L.Push(LFalse)
|
||||
}
|
||||
L.Push(lv)
|
||||
L.Call(2, 0)
|
||||
case reflect.SelectSend:
|
||||
L.Push(tbl.RawGetInt(3))
|
||||
L.Call(1, 0)
|
||||
case reflect.SelectDefault:
|
||||
L.Call(0, 0)
|
||||
}
|
||||
}
|
||||
L.Push(LNumber(pos + 1))
|
||||
L.Push(lv)
|
||||
if rok {
|
||||
L.Push(LTrue)
|
||||
} else {
|
||||
L.Push(LFalse)
|
||||
}
|
||||
return 3
|
||||
}
|
||||
|
||||
var channelMethods = map[string]LGFunction{
|
||||
"receive": channelReceive,
|
||||
"send": channelSend,
|
||||
"close": channelClose,
|
||||
}
|
||||
|
||||
func channelReceive(L *LState) int {
|
||||
rch := checkChannel(L, 1)
|
||||
var v reflect.Value
|
||||
var ok bool
|
||||
if L.ctx != nil {
|
||||
cases := []reflect.SelectCase{{
|
||||
Dir: reflect.SelectRecv,
|
||||
Chan: reflect.ValueOf(L.ctx.Done()),
|
||||
Send: reflect.ValueOf(nil),
|
||||
}, {
|
||||
Dir: reflect.SelectRecv,
|
||||
Chan: rch,
|
||||
Send: reflect.ValueOf(nil),
|
||||
}}
|
||||
_, v, ok = reflect.Select(cases)
|
||||
} else {
|
||||
v, ok = rch.Recv()
|
||||
}
|
||||
if ok {
|
||||
L.Push(LTrue)
|
||||
L.Push(v.Interface().(LValue))
|
||||
} else {
|
||||
L.Push(LFalse)
|
||||
L.Push(LNil)
|
||||
}
|
||||
return 2
|
||||
}
|
||||
|
||||
func channelSend(L *LState) int {
|
||||
rch := checkChannel(L, 1)
|
||||
v := checkGoroutineSafe(L, 2)
|
||||
rch.Send(reflect.ValueOf(v))
|
||||
return 0
|
||||
}
|
||||
|
||||
func channelClose(L *LState) int {
|
||||
rch := checkChannel(L, 1)
|
||||
rch.Close()
|
||||
return 0
|
||||
}
|
||||
|
||||
//
|
||||
Reference in New Issue
Block a user