func (tbl *Table) GetWithError(key interface{}) (interface{}, error) { if tbl.Ref == 0 { return nil, fmt.Errorf("cannot get a released lua table") } L := tbl.VM.globalL state := State{tbl.VM, L} bottom := C.lua_gettop(L) defer C.lua_settop(L, bottom) tbl.PushValue(state) vkey := reflect.ValueOf(key) ok := state.goToLuaValue(vkey) if !ok { return nil, fmt.Errorf("invalid key type for lua type: %v", vkey.Kind()) } C.lua_gettable(L, C.int(-2)) vvalue, err := state.luaToGoValue(-1, nil) if err != nil { return nil, err } if vvalue.IsValid() { return vvalue.Interface(), nil } return nil, nil }
// Pcall calls a lua function. no panic func (l *Lua) Pcall(fullname string, args ...interface{}) (returns []interface{}, err error) { C.push_errfunc(l.State) curTop := C.lua_gettop(l.State) // get function path := strings.Split(fullname, ".") for i, name := range path { if i == 0 { C.lua_getfield(l.State, C.LUA_GLOBALSINDEX, cstr(name)) } else { if C.lua_type(l.State, -1) != C.LUA_TTABLE { return nil, fmt.Errorf("%s is not a function", fullname) } C.lua_pushstring(l.State, cstr(name)) C.lua_gettable(l.State, -2) C.lua_remove(l.State, -2) // remove table } } if C.lua_type(l.State, -1) != C.LUA_TFUNCTION { return nil, fmt.Errorf("%s is not a function", fullname) } // args for _, arg := range args { l.pushGoValue(arg, "") } // call l.err = nil if ret := C.lua_pcall(l.State, C.int(len(args)), C.LUA_MULTRET, C.int(-(len(args))-2)); ret != 0 { // error occured return nil, fmt.Errorf("CALL ERROR: %s", C.GoString(C.lua_tolstring(l.State, -1, nil))) } else if l.err != nil { // error raise by invokeGoFunc return nil, l.err } else { // return values nReturn := C.lua_gettop(l.State) - curTop returns = make([]interface{}, int(nReturn)) for i := C.int(0); i < nReturn; i++ { value, err := l.toGoValue(-1-i, interfaceType) if err != nil { return nil, err } returns[int(nReturn-1-i)] = value.Interface() } } return }
func luaGetSubTable(L *C.lua_State, table C.int, key string) (bool, error) { pushStringToLua(L, key) C.lua_gettable(L, table) ltype := C.lua_type(L, -1) if ltype == C.LUA_TNIL { C.lua_createtable(L, 0, 0) // table[key] = {} pushStringToLua(L, key) C.lua_pushvalue(L, -2) C.lua_settable(L, table) } ltype = C.lua_type(L, -1) if ltype != C.LUA_TTABLE { C.lua_settop(L, -2) return false, fmt.Errorf("field `%v` exist, and it is not a table", key) } return true, nil }
// lua_gettable func (L *State) GetTable(index int) { C.lua_gettable(L.s, C.int(index)) }
// Pushes onto the stack the value t[k], where t is the value at the // given valid index and k is the value at the top of the stack. // // This function pops the key from the stack (putting the resulting value // in its place). As in Lua, this function may trigger a metamethod for // the "index" event func (this *State) Gettable(index int) { C.lua_gettable(this.luastate, C.int(index)) }
// Pushes onto the stack the value t[k], where t is the value at the // given valid index and k is the value at the top of the stack. // // This function pops the key from the stack (putting the resulting value // in its place). As in Lua, this function may trigger a metamethod for // the "index" event func (s *State) Gettable(index int) { C.lua_gettable(s.l, C.int(index)) }