Example #1
0
File: lua.go Project: hxyxj/goinfi
func (vm *VM) AddFunc(name string, fn interface{}) (bool, error) {
	value := reflect.ValueOf(fn)
	fnType := reflect.TypeOf(fn)
	if value.Kind() != reflect.Func {
		return false, fmt.Errorf("AddFunc only add function type")
	}
	_, err := checkFunc(fnType)
	if err != nil {
		return false, err
	}
	namePath := strings.Split(name, ".")
	baseName := namePath[len(namePath)-1]
	path := namePath[:len(namePath)-1]

	L := vm.globalL
	state := State{vm, L}

	if len(path) <= 0 {
		// _G[a] = fn
		pushStringToLua(L, baseName)
		state.pushObjToLua(fn)
		C.lua_settable(vm.globalL, C.LUA_GLOBALSINDEX)
		return true, nil
	}

	// _G.a.b.c = fn
	ok, err := luaPushMultiLevelTable(L, path)
	if !ok {
		return false, err
	}
	pushStringToLua(L, baseName)
	state.pushObjToLua(fn)
	C.lua_settable(vm.globalL, -3)
	return true, nil
}
Example #2
0
File: lgo.go Project: reusee/lgo
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())
	}
}
Example #3
0
File: pack.go Project: hxyxj/goinfi
func unpackMapToLua(state State, m *P.Map) {
	L := state.L
	n := len(m.Elems)

	C.lua_createtable(L, 0, 0)

	for i := 0; i < n; i++ {
		key := m.Elems[i].Key
		value := m.Elems[i].Value

		// key
		switch key.(type) {
		case int, int8, int32, int64, uint, uint8, uint32, uint64, float32, float64, string:
			UnpackObjectToLua(state, key)
		case []byte:
			bytes := key.([]byte)
			pushBytesToLua(L, bytes)
		default:
			continue
		}

		// value
		UnpackObjectToLua(state, value)

		C.lua_settable(L, -3)
	}
}
Example #4
0
File: lua.go Project: hxyxj/goinfi
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
}
Example #5
0
func (tbl *Table) Set(key interface{}, value interface{}) (bool, error) {
	if tbl.Ref == 0 {
		return false, fmt.Errorf("cannot set 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 false, fmt.Errorf("invalid key type for lua type: %v", vkey.Kind())
	}
	state.goToLuaValue(reflect.ValueOf(value))
	C.lua_settable(L, C.int(-3))

	return true, nil
}
Example #6
0
File: lua.go Project: szll/golua
// lua_settable
func (L *State) SetTable(index int) {
	C.lua_settable(L.s, C.int(index))
}
Example #7
0
// Does the equivalent to t[k] = v, where t is the value at the given valid
// index, v is the value at the top of the stack, and k is the value just
// below the top.
//
// This function pops both the key and the value from the stack. As in Lua,
// this function may trigger a metamethod for the "newindex" event.
func (this *State) Settable(index int) {
	C.lua_settable(this.luastate, C.int(index))
}
Example #8
0
// Does the equivalent to t[k] = v, where t is the value at the given valid
// index, v is the value at the top of the stack, and k is the value just
// below the top.
//
// This function pops both the key and the value from the stack. As in Lua,
// this function may trigger a metamethod for the "newindex" event.
func (s *State) Settable(index int) {
	C.lua_settable(s.l, C.int(index))
}
Example #9
0
File: lua.go Project: reusee/lua
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
}