-
Notifications
You must be signed in to change notification settings - Fork 1
/
lua_thread.go
99 lines (90 loc) · 2.12 KB
/
lua_thread.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
88
89
90
91
92
93
94
95
96
97
98
99
package lua
import (
"errors"
"unsafe"
)
// #cgo LDFLAGS: -lluajit-5.1 -ldl -lm
//#include "glua.h"
import "C"
type gLuaThread struct {
id int64
thread *C.struct_lua_State
}
func newGLuaThread(vm *C.struct_lua_State) *gLuaThread {
gl := &gLuaThread{}
gl.id, gl.thread = createLuaThread(vm)
return gl
}
func (t *gLuaThread) destory() {
cleanDummy(t.thread)
}
func (t *gLuaThread) call(scriptPath string, methodName string, args ...interface{}) (interface{}, error) {
var ret C.int
if scriptPath != "" {
target, err := LoadScript(scriptPath)
if err != nil {
return nil, err
}
script := C.CString(target)
defer C.free(unsafe.Pointer(script))
ret = C.gluaL_dostring(t.thread, script)
if ret != C.LUA_OK {
ExpireScript(scriptPath)
errStr := C.GoString(C.glua_tostring(t.thread, -1))
return nil, errors.New(errStr)
}
}
cStr := C.CString(methodName)
defer C.free(unsafe.Pointer(cStr))
C.glua_getglobal(t.thread, cStr)
pushToLua(t.thread, args...)
ret = C.lua_resume(t.thread, C.int(len(args)))
switch ret {
case C.LUA_OK:
{
var (
res interface{}
err interface{}
)
num := C.lua_gettop(t.thread)
if num > 1 {
err = pullFromLua(t.thread, -1)
C.lua_remove(t.thread, -1)
res = pullFromLua(t.thread, -1)
} else {
res = pullFromLua(t.thread, -1)
}
C.glua_pop(t.thread, -1)
if err != nil {
return nil, errors.New(err.(string))
}
return res, nil
}
case C.LUA_YIELD:
return nil, errors.New("LUA_YIELD")
default:
temp := C.GoString(C.glua_tostring(t.thread, -1))
return nil, errors.New(temp)
}
}
func (t *gLuaThread) resume(args ...interface{}) (interface{}, error) {
pushToLua(t.thread, args...)
num := C.lua_gettop(t.thread)
ret := C.lua_resume(t.thread, num)
switch ret {
case C.LUA_OK:
err := pullFromLua(t.thread, -1)
C.lua_remove(t.thread, -1)
res := pullFromLua(t.thread, -1)
C.glua_pop(t.thread, -1)
if err != nil {
return nil, errors.New(err.(string))
}
return res, nil
case C.LUA_YIELD:
return nil, errors.New("LUA_YIELD")
default:
temp := C.GoString(C.glua_tostring(t.thread, -1))
return nil, errors.New(temp)
}
}