forked from hootrhino/rulex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxpipline.go
87 lines (76 loc) · 2.09 KB
/
xpipline.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package typex
import (
"errors"
"strconv"
lua "github.com/hootrhino/gopher-lua"
)
// RunPipline
//
// Run lua as pipline
func RunPipline(vm *lua.LState, funcs map[string]*lua.LFunction, arg lua.LValue) (lua.LValue, error) {
// start 1
acc := 1
return pipLine(vm, acc, funcs, arg)
}
func pipLine(vm *lua.LState, acc int, funcs map[string]*lua.LFunction, arg lua.LValue) (lua.LValue, error) {
if acc == len(funcs) {
values, err0 := callLuaFunc(vm, funcs[strconv.Itoa(acc)], arg)
if err0 != nil {
return nil, err0
}
return validate(values, func() (lua.LValue, error) {
result := values[1]
return result, nil
})
}
values, err0 := callLuaFunc(vm, funcs[strconv.Itoa(acc)], arg)
if err0 != nil {
return nil, err0
}
return validate(values, func() (lua.LValue, error) {
next := values[0]
result := values[1]
if next.Type() == lua.LTBool {
if next.(lua.LBool) {
return pipLine(vm, acc+1, funcs, result)
}
return result, nil
}
return nil, errors.New("'Action' callback first argument is must be bool")
})
}
// validate lua callback
func validate(values []lua.LValue, f func() (lua.LValue, error)) (lua.LValue, error) {
// Lua call back must have 2 args!!!
if len(values) != 2 {
return nil, errors.New("'Action' callback must have 2 return value:[bool, T]")
} else {
return f()
}
}
// 执行lua函数的接口, 后期可以用这个接口来实现运行 lua 微服务
func Execute(vm *lua.LState, k string, args ...lua.LValue) (interface{}, error) {
callable := vm.GetGlobal(k)
if callable.Type() == lua.LTFunction {
return callLuaFunc(vm, callable.(*lua.LFunction), args...)
}
return nil, errors.New("target:" + k + " is not a lua function")
}
// callLuaFunc
func callLuaFunc(vm *lua.LState, callable *lua.LFunction, args ...lua.LValue) ([]lua.LValue, error) {
if callable == nil {
return nil, errors.New("callable function is not exists")
}
err := vm.CallByParam(lua.P{
Fn: callable,
NRet: 2,
Protect: true,
}, args...)
if err != nil {
return nil, err
}
vm.Pop(-1)
vm.Pop(-2)
vm.Pop(-3)
return []lua.LValue{vm.Get(-2), vm.Get(-1)}, nil
}