func (lua *Lua) PushGoValue(value reflect.Value) { switch t := value.Type(); t.Kind() { case reflect.Bool: if value.Bool() { C.lua_pushboolean(lua.State, C.int(1)) } else { C.lua_pushboolean(lua.State, C.int(0)) } case reflect.String: C.lua_pushstring(lua.State, C.CString(value.String())) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: C.lua_pushnumber(lua.State, C.lua_Number(C.longlong(value.Int()))) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: C.lua_pushnumber(lua.State, C.lua_Number(C.ulonglong(value.Uint()))) case reflect.Float32, reflect.Float64: C.lua_pushnumber(lua.State, C.lua_Number(C.double(value.Float()))) case reflect.Slice: length := value.Len() C.lua_createtable(lua.State, C.int(length), 0) for i := 0; i < length; i++ { C.lua_pushnumber(lua.State, C.lua_Number(i+1)) lua.PushGoValue(value.Index(i)) C.lua_settable(lua.State, -3) } case reflect.Interface: lua.PushGoValue(value.Elem()) case reflect.Ptr, reflect.UnsafePointer: C.lua_pushlightuserdata(lua.State, unsafe.Pointer(value.Pointer())) default: lua.Panic("wrong return value %v %v", value, t.Kind()) } }
// Pushes a boolean value with value b onto the stack. func (s *State) Pushboolean(b bool) { if b { C.lua_pushboolean(s.l, 1) } else { C.lua_pushboolean(s.l, 0) } }
func (L *State) pushBool(b bool) { if b { C.lua_pushboolean(L.s, 1) } else { C.lua_pushboolean(L.s, 0) } }
func luaHasKey(state State) int { L := state.L vmap := mustBeMap(state, 2) if vmap == nil { C.lua_pushboolean(L, 0) pushStringToLua(L, "HasKey() only apply to `map'") return 2 } key, err := state.luaToGoValue(3, nil) if err != nil { C.lua_pushboolean(L, 0) pushStringToLua(L, fmt.Sprintf("%v", err)) return 2 } if key.Type().AssignableTo(vmap.Type().Key()) { value := vmap.MapIndex(key) if value.IsValid() { C.lua_pushboolean(L, 1) return 1 } } C.lua_pushboolean(L, 0) return 1 }
func (state State) goToLuaValue(value reflect.Value) bool { L := state.L gkind := value.Kind() switch gkind { case reflect.Bool: v := value.Bool() if v { C.lua_pushboolean(L, 1) } else { C.lua_pushboolean(L, 0) } return true case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: v := value.Int() C.lua_pushinteger(L, C.lua_Integer(v)) return true case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: v := value.Uint() C.lua_pushinteger(L, C.lua_Integer(v)) return true // case reflect.Uintptr: case reflect.Float32, reflect.Float64: v := value.Float() C.lua_pushnumber(L, C.lua_Number(v)) return true // case reflect.Array: // case reflect.Complex64, reflect.Complex128: // case reflect.Chan // case reflect.Interface case reflect.Ptr: iv := value.Interface() if v, ok := iv.(ILuaRef); ok { v.PushValue(state) return true } state.pushObjToLua(value.Interface()) return true case reflect.Func, reflect.Map, reflect.Slice: state.pushObjToLua(value.Interface()) return true case reflect.String: v := value.String() pushStringToLua(L, v) return true case reflect.Struct: objPtr := reflect.New(value.Type()) objPtr.Elem().Set(value) state.pushObjToLua(objPtr.Interface()) return true //case reflect.UnsafePointer case reflect.Interface: return state.goToLuaValue(value.Elem()) } C.lua_pushnil(L) return false }
func Lua_pushboolean(L Lua_State, b bool) { var v C.int = 0 if b { v = 1 } C.lua_pushboolean(Lua_CStatePtr(L), v) }
// lua_pushboolean func (L *State) PushBoolean(b bool) { var bint int if b { bint = 1 } else { bint = 0 } C.lua_pushboolean(L.s, C.int(bint)) }
func (l *Lua) pushGoValue(v interface{}, name string) error { if v == nil { C.lua_pushnil(l.State) return nil } switch value := v.(type) { case bool: if value { C.lua_pushboolean(l.State, C.int(1)) } else { C.lua_pushboolean(l.State, C.int(0)) } case string: C.lua_pushstring(l.State, C.CString(value)) case int: C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value))) case int8: C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value))) case int16: C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value))) case int32: C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value))) case int64: C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value))) case uint: C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value))) case uint8: C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value))) case uint16: C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value))) case uint32: C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value))) case uint64: C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value))) case float32: C.lua_pushnumber(l.State, C.lua_Number(C.double(value))) case float64: C.lua_pushnumber(l.State, C.lua_Number(C.double(value))) case unsafe.Pointer: C.lua_pushlightuserdata(l.State, value) default: // not basic types, use reflect switch valueType := reflect.TypeOf(v); valueType.Kind() { case reflect.Func: // function if valueType.IsVariadic() { return fmt.Errorf("variadic function is not supported, %s", name) } function := &_Function{ name: name, lua: l, fun: v, funcType: valueType, funcValue: reflect.ValueOf(v), argc: valueType.NumIn(), } funcsLock.Lock() funcs = append(funcs, function) id := len(funcs) - 1 funcsLock.Unlock() C.push_go_func(l.State, C.int64_t(id)) case reflect.Slice: value := reflect.ValueOf(v) length := value.Len() C.lua_createtable(l.State, C.int(length), 0) for i := 0; i < length; i++ { C.lua_pushnumber(l.State, C.lua_Number(i+1)) err := l.pushGoValue(value.Index(i).Interface(), "") if err != nil { return err } C.lua_settable(l.State, -3) } case reflect.Ptr: C.lua_pushlightuserdata(l.State, unsafe.Pointer(reflect.ValueOf(v).Pointer())) default: // unknown type return fmt.Errorf("unsupported type %v", v) } } return nil }