func register(L *lua.State, table string, values Map, convertFun bool) { pop := true if table == "*" { pop = false } else if len(table) > 0 { L.GetGlobal(table) if L.IsNil(-1) { L.NewTable() L.SetGlobal(table) L.GetGlobal(table) } } else { L.GetGlobal("_G") } for name, val := range values { t := reflect.TypeOf(val) if t.Kind() == reflect.Func { if convertFun { L.PushGoFunction(GoLuaFunc(L, val)) } else { lf := val.(func(*lua.State) int) L.PushGoFunction(lf) } } else { GoToLua(L, t, valueOf(val)) } L.SetField(-2, name) } if pop { L.Pop(1) } }
func isValueProxy(L *lua.State, idx int) bool { res := false if L.IsUserdata(idx) { L.GetMetaTable(idx) if !L.IsNil(-1) { L.GetField(-1, "luago.value") res = !L.IsNil(-1) L.Pop(1) } L.Pop(1) } return res }
// return the Lua table at 'idx' as a copied Go slice. If 't' is nil then the slice // type is []interface{} func CopyTableToSlice(L *lua.State, t reflect.Type, idx int) interface{} { if t == nil { t = reflect.TypeOf(tslice) } te := t.Elem() n := int(L.ObjLen(idx)) slice := reflect.MakeSlice(t, n, n) for i := 1; i <= n; i++ { L.RawGeti(idx, i) val := LuaToGo(L, te, -1) slice.Index(i - 1).Set(valueOf(val)) L.Pop(1) } return slice.Interface() }
// return the Lua table at 'idx' as a copied Go map. If 't' is nil then the map // type is map[string]interface{} func CopyTableToMap(L *lua.State, t reflect.Type, idx int) interface{} { if t == nil { t = reflect.TypeOf(tmap) } te, tk := t.Elem(), t.Key() m := reflect.MakeMap(t) L.PushNil() if idx < 0 { idx-- } for L.Next(idx) != 0 { // key at -2, value at -1 key := valueOf(LuaToGo(L, tk, -2)) val := valueOf(LuaToGo(L, te, -1)) m.SetMapIndex(key, val) L.Pop(1) } return m.Interface() }
func CopyTableToStruct(L *lua.State, t reflect.Type, idx int) interface{} { if t.Kind() == reflect.Ptr { t = t.Elem() } s := reflect.New(t) // T -> *T ref := s.Elem() L.PushNil() if idx < 0 { idx-- } for L.Next(idx) != 0 { key := L.ToString(-2) f := ref.FieldByName(key) if f.IsValid() { val := valueOf(LuaToGo(L, f.Type(), -1)) f.Set(val) } L.Pop(1) } return s.Interface() }
func initializeProxies(L *lua.State) { add_index := func(name string, fun lua.GoFunction) { L.PushGoCallback(fun) L.SetField(-2, name) } flagValue := func() { L.PushBoolean(true) L.SetField(-2, "luago.value") L.Pop(1) } L.NewMetaTable(SLICE_META) add_index("__index", slice__index) add_index("__newindex", slice__newindex) add_index("__len", slicemap__len) flagValue() L.NewMetaTable(MAP_META) add_index("__index", map__index) add_index("__newindex", map__newindex) add_index("__len", slicemap__len) flagValue() L.NewMetaTable(STRUCT_META) add_index("__index", struct__index) add_index("__newindex", struct__newindex) flagValue() L.NewMetaTable(INTERFACE_META) add_index("__index", interface__index) flagValue() L.NewMetaTable(CHANNEL_META) //~ RegisterFunctions(L,"*",FMap { //~ "Send":channel_send, //~ "Recv":channel_recv, //~ }) L.NewTable() L.PushGoFunction(channel_send) L.SetField(-2, "Send") L.PushGoFunction(channel_recv) L.SetField(-2, "Recv") L.SetField(-2, "__index") flagValue() }