Пример #1
0
func MessThingTellallMethod(state *lua.State, thing *Thing) int {
	state.PushGoFunction(func(state *lua.State) int {
		place := checkThing(state, 1)
		text := state.CheckString(2)

		// If arg 3 is present, it should be a table of Things to exclude.
		excludes := make(map[ThingId]bool)
		if 2 < state.GetTop() {
			if !state.IsTable(3) {
				state.ArgError(3, "expected `table` for exclude argument if present")
			}
			numExcludes := int(state.ObjLen(3))
			for i := 0; i < numExcludes; i++ {
				state.RawGeti(3, i+1)
				exclude := checkThing(state, -1)
				excludes[exclude.Id] = true
			}
		}

		for _, content := range place.GetContents() {
			if excludes[content.Id] {
				continue
			}
			if content.Client != nil {
				content.Client.Send(text)
			}
		}

		return 0
	})
	return 1
}
Пример #2
0
func (p *Plugin) apiProcessNew(l *lua.State) int {
	callback := luar.NewLuaObject(l, 1)
	command := l.ToString(2)

	args := make([]string, l.GetTop()-2)
	for i := 3; i <= l.GetTop(); i++ {
		args[i-3] = l.ToString(i)
	}

	proc := &process{
		cmd: exec.Command(command, args...),
	}

	go func() {
		var str string
		bytes, err := proc.cmd.Output()
		if err == nil {
			if bytes != nil {
				str = string(bytes)
			}
			p.callValue(callback, proc.cmd.ProcessState.Success(), str)
		} else {
			p.callValue(callback, false, "")
		}
		callback.Close()
	}()

	obj := luar.NewLuaObjectFromValue(l, proc)
	obj.Push()
	obj.Close()
	return 1
}
Пример #3
0
func printStackTypes(state *lua.State) {
	topIndex := state.GetTop()
	segments := make([]interface{}, topIndex+1)
	segments[0] = "Stack types:"
	for i := 1; i <= topIndex; i++ {
		segments[i] = state.LTypename(i)
	}
	log.Println(segments...)
}
Пример #4
0
Файл: luar.go Проект: imvu/Tetra
// GoLuaFunc converts an arbitrary Go function into a Lua-compatible GoFunction.
// There are special optimized cases for functions that go from strings to strings,
// and doubles to doubles, but otherwise Go
// reflection is used to provide a generic wrapper function
func GoLuaFunc(L *lua.State, fun interface{}) lua.LuaGoFunction {
	switch f := fun.(type) {
	case func(*lua.State) int:
		return f
	case func(string) string:
		return func(L *lua.State) int {
			L.PushString(f(L.ToString(1)))
			return 1
		}
	case func(float64) float64:
		return func(L *lua.State) int {
			L.PushNumber(f(L.ToNumber(1)))
			return 1
		}
	default:
	}
	var funv reflect.Value
	switch ff := fun.(type) {
	case reflect.Value:
		funv = ff
	default:
		funv = valueOf(fun)
	}
	funt := funv.Type()
	targs, tout := functionArgRetTypes(funt)
	return func(L *lua.State) int {
		var lastT reflect.Type
		orig_targs := targs
		isVariadic := funt.IsVariadic()
		if isVariadic {
			n := len(targs)
			lastT = targs[n-1].Elem()
			targs = targs[0 : n-1]
		}
		args := make([]reflect.Value, len(targs))
		for i, t := range targs {
			val := LuaToGo(L, t, i+1)
			args[i] = valueOfNil(val)
			//println(i,args[i].String())
		}
		if isVariadic {
			n := L.GetTop()
			for i := len(targs) + 1; i <= n; i++ {
				ival := LuaToGo(L, lastT, i)
				args = append(args, valueOfNil(ival))
			}
			targs = orig_targs
		}
		resv := callGo(L, funv, args)
		for i, val := range resv {
			GoToLua(L, tout[i], val, false)
		}
		return len(resv)
	}
}
Пример #5
0
func goLuaFunc(L *lua.State, fun reflect.Value) lua.LuaGoFunction {
	switch f := fun.Interface().(type) {
	case func(*lua.State) int:
		return f
	}

	funT := fun.Type()
	tArgs := make([]reflect.Type, funT.NumIn())
	for i := range tArgs {
		tArgs[i] = funT.In(i)
	}

	return func(L *lua.State) int {
		var lastT reflect.Type
		origTArgs := tArgs
		isVariadic := funT.IsVariadic()

		if isVariadic {
			n := len(tArgs)
			lastT = tArgs[n-1].Elem()
			tArgs = tArgs[0 : n-1]
		}

		args := make([]reflect.Value, len(tArgs))
		for i, t := range tArgs {
			val := LuaToGo(L, t, i+1)
			args[i] = valueOfNil(val)
		}

		if isVariadic {
			n := L.GetTop()
			for i := len(tArgs) + 1; i <= n; i++ {
				iVal := LuaToGo(L, lastT, i)
				args = append(args, valueOfNil(iVal))
			}
			tArgs = origTArgs
		}
		resV := callGo(L, fun, args)
		for _, val := range resV {
			if val.Kind() == reflect.Struct {
				// If the function returns a struct (and not a pointer to a struct),
				// calling GoToLua directly will convert it to a table, making the
				// mathods inaccessible. We work around that issue by forcibly passing a
				// pointer to a struct.
				n := reflect.New(val.Type())
				n.Elem().Set(val)
				val = n
			}
			GoToLua(L, nil, val, false)
		}
		return len(resV)
	}
}
Пример #6
0
func (p *Plugin) apiAudioSetTarget(l *lua.State) int {
	if l.GetTop() == 0 {
		p.instance.Client.VoiceTarget = nil
		return 0
	}

	voiceTarget, ok := luar.LuaToGo(l, nil, 1).(*gumble.VoiceTarget)
	if !ok {
		l.PushBoolean(false)
		return 1
	}
	p.instance.Client.Send(voiceTarget)
	p.instance.Client.VoiceTarget = voiceTarget
	return 0
}
Пример #7
0
func LuaIntColumnQuery(L *lua.State) int {
	if (L.GetTop() != 1) && (L.GetTop() != 3) {
		panic(errors.New("Wrong number of arguments to columnq"))
		return 0
	}

	name := L.ToString(1)
	op := ""
	value := ""
	if L.GetTop() == 3 {
		op = L.ToString(2)
		value = L.ToString(3)
		L.Pop(3)
	} else {
		L.Pop(1)
	}

	if name[0] == ':' {
		panic(errors.New("Column name can not start with ':'"))
		return 0
	}

	L.CheckStack(1)
	tl := GetTasklistFromLua(L)

	tl.luaState.PushGoStruct(&SimpleExpr{name, op, value, nil, 0, ""})
	return 1
}
Пример #8
0
func LuaIntGetterSetterFunction(fname string, L *lua.State, getter func(tl *Tasklist, entry *Entry) string, setter func(tl *Tasklist, entry *Entry, value string)) int {
	argNum := L.GetTop()

	if argNum == 0 {
		entry := GetEntryFromLua(L, CURSOR, fname)
		tl := GetTasklistFromLua(L)
		L.PushString(getter(tl, entry))
		return 1
	} else if argNum == 1 {
		value := L.ToString(1)
		entry := GetEntryFromLua(L, CURSOR, fname)
		tl := GetTasklistFromLua(L)
		setter(tl, entry, value)
		if !tl.luaFlags.cursorCloned {
			tl.luaFlags.cursorEdited = true
		}
		return 0
	}

	panic(errors.New(fmt.Sprintf("Incorrect number of argoments to %s (only 0 or 1 accepted)", fname)))
	return 0
}
Пример #9
0
func LuaIntBoolQuery(L *lua.State, operator, name string) int {
	if L.GetTop() < 2 {
		panic(errors.New("Wrong number of arguments to " + name))
		return 0
	}

	L.CheckStack(1)
	tl := GetTasklistFromLua(L)

	r := &BoolExpr{operator, make([]Clausable, 0)}

	for i := 1; i <= L.GetTop(); i++ {
		clausable := GetQueryObject(tl, i)
		if clausable == nil {
			panic(errors.New("Wrong argument type to " + name + " only query objects accepted as arguments"))
			return 0
		}
		r.subExpr = append(r.subExpr, clausable)
	}

	tl.luaState.PushGoStruct(r)
	return 1
}
Пример #10
0
func LuaIntColumn(L *lua.State) int {
	argNum := L.GetTop()

	if argNum == 1 {
		name := L.ToString(1)
		entry := GetEntryFromLua(L, CURSOR, "column()")
		L.PushString(entry.Column(name))
		return 1
	} else if argNum == 2 {
		name := L.ToString(1)
		value := L.ToString(2)
		entry := GetEntryFromLua(L, CURSOR, "column()")
		entry.SetColumn(name, value)
		tl := GetTasklistFromLua(L)
		if !tl.luaFlags.cursorCloned {
			tl.luaFlags.cursorEdited = true
		}
		return 0
	}

	panic(errors.New("Incorrect number of arguments to column (only 1 or 2 accepted)"))
	return 0
}
Пример #11
0
func LuaIntSearch(L *lua.State) int {
	if (L.GetTop() < 1) || (L.GetTop() > 2) {
		panic(errors.New("Wrong number of arguments to search()"))
		return 0
	}

	L.CheckStack(2)
	tl := GetTasklistFromLua(L)

	if !tl.luaFlags.freeCursor {
		panic(errors.New("search() function only available on a free cursor"))
		return 0
	}

	query := L.ToString(1)
	var luaClausable Clausable = nil
	if L.GetTop() == 2 {
		luaClausable = GetQueryObject(tl, 2)
	}

	theselect, _, _, _, _, _, _, perr := tl.ParseSearch(query, luaClausable)
	Must(perr)

	entries, serr := tl.Retrieve(theselect, "", false)
	Must(serr)

	Logf(INFO, "Searching from lua interface <%s> clausable: <%v> yields %d results\n", query, luaClausable, len(entries))

	r := []string{}
	for _, entry := range entries {
		r = append(r, entry.Id())
	}

	PushStringVec(L, r)
	return 1
}
Пример #12
0
func LuaIntSplit(L *lua.State) int {
	if L.GetTop() < 2 {
		panic(errors.New("Wrong number of arguments to split()"))
		return 0
	}

	instr := L.ToString(1)
	sepstr := L.ToString(2)

	n := -1

	if L.GetTop() == 3 {
		n = L.ToInteger(3)
	}

	if L.GetTop() > 3 {
		panic(errors.New("Wrong number of arguments to split()"))
		return 0
	}

	PushStringVec(L, strings.SplitN(instr, sepstr, n))

	return 1
}
Пример #13
0
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), false)
		}
		L.SetField(-2, name)

		if t.Kind() == reflect.Func {
			var lf func(*lua.State) int
			if convertFun {
				lf = GoLuaFunc(L, val)
			} else {
				lf = val.(func(*lua.State) int)
			}
			L.PushGoFunction(func(L *lua.State) (ret int) {
				defer func() {
					if err2 := recover(); err2 != nil {
						GoToLua(L, typeof(err2), valueOf(err2), false)
						ret = 1
						return
					}
				}()

				ret = lf(L)
				pos := L.GetTop() - ret + 1
				L.PushNil()
				L.Insert(pos)

				for i := 0; i < L.GetTop(); i++ {
					fmt.Println(L.Typename(int(L.Type(i + 1))))
				}
				return ret + 1
			})
			L.SetField(-2, "safe_"+name)
		}
	}
	if pop {
		L.Pop(1)
	}
}
Пример #14
0
func luaAssertArgnum(L *lua.State, n int, fname string) {
	if L.GetTop() != n {
		panic(errors.New("Incorrect number of arguments to " + fname))
	}
}