Initial commit
This commit is contained in:
commit
285a141825
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
*.o
|
||||
*.a
|
||||
/goci
|
||||
/goci.exe
|
||||
32
glua/cglua.c
Normal file
32
glua/cglua.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include<lua.h>
|
||||
#include<lualib.h>
|
||||
#include<lauxlib.h>
|
||||
#include<stdint.h>
|
||||
|
||||
extern int glua_go_call_func(uint64_t);
|
||||
extern int glua_go_remove_func(uint64_t);
|
||||
|
||||
int glua_metatable_call(lua_State *L) {
|
||||
uint64_t id = *(uint64_t*) lua_touserdata(L, 1);
|
||||
int result = glua_go_call_func(id);
|
||||
if(result < 0) {
|
||||
lua_error(L);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int glua_metatable_gc(lua_State *L) {
|
||||
uint64_t id = *(uint64_t*) lua_touserdata(L, 1);
|
||||
glua_go_remove_func(id);
|
||||
return 0;
|
||||
}
|
||||
int glua_metatable_tostring(lua_State *L) {
|
||||
uint64_t id = *(uint64_t*) lua_touserdata(L, 1);
|
||||
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "gofunc: 0x%X", id);
|
||||
|
||||
lua_pushstring(L, buf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
196
glua/glua.go
Normal file
196
glua/glua.go
Normal file
@ -0,0 +1,196 @@
|
||||
package glua
|
||||
|
||||
/*
|
||||
* Self-contained Go-Lua binding, which handles inter-FFI errors seamlessly unlike others.
|
||||
* */
|
||||
|
||||
// #cgo pkg-config: lua
|
||||
// #cgo LDFLAGS: -L./ -lcglua
|
||||
// #include<lua.h>
|
||||
// #include<lualib.h>
|
||||
// #include<lauxlib.h>
|
||||
// #include<stdlib.h>
|
||||
// extern int glua_metatable_call(lua_State*);
|
||||
// extern int glua_metatable_gc(lua_State*);
|
||||
// extern int glua_metatable_tostring(lua_State*);
|
||||
import "C"
|
||||
|
||||
import "fmt"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type Function func(l *Lua) int
|
||||
|
||||
type FuncStatePair struct {
|
||||
fn Function
|
||||
l *Lua
|
||||
}
|
||||
var FuncIDs map[uint64]FuncStatePair = make(map[uint64]FuncStatePair)
|
||||
var NextFuncID uint64 = 0
|
||||
|
||||
//export glua_go_call_func
|
||||
func glua_go_call_func(id C.uint64_t) (ret C.int) {
|
||||
pair := FuncIDs[uint64(id)]
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
pair.l.PushString(fmt.Sprint(r))
|
||||
ret = -1
|
||||
}
|
||||
}()
|
||||
|
||||
return C.int(pair.fn(pair.l))
|
||||
}
|
||||
|
||||
//export glua_go_remove_func
|
||||
func glua_go_remove_func(id C.uint64_t) {
|
||||
delete(FuncIDs, uint64(id))
|
||||
}
|
||||
|
||||
type Lua struct {
|
||||
state *C.lua_State
|
||||
}
|
||||
|
||||
func NewState() Lua {
|
||||
l := Lua{C.luaL_newstate()}
|
||||
|
||||
C.luaL_newmetatable(l.state, C.CString("GLUA_FUNCTION"))
|
||||
C.lua_pushcclosure(l.state, C.lua_CFunction(C.glua_metatable_call), 0)
|
||||
l.SetField(-2, "__call")
|
||||
|
||||
C.lua_pushcclosure(l.state, C.lua_CFunction(C.glua_metatable_gc), 0)
|
||||
l.SetField(-2, "__gc")
|
||||
|
||||
C.lua_pushcclosure(l.state, C.lua_CFunction(C.glua_metatable_tostring), 0)
|
||||
l.SetField(-2, "__tostring")
|
||||
l.Pop(1)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func (l Lua) Close() {
|
||||
C.lua_close(l.state)
|
||||
}
|
||||
|
||||
func (l Lua) OpenLibs() {
|
||||
C.luaL_openlibs(l.state)
|
||||
}
|
||||
|
||||
func (l Lua) NewTable() {
|
||||
C.lua_createtable(l.state, 0, 0)
|
||||
}
|
||||
|
||||
func (l Lua) SetField(offset int, name string) {
|
||||
cstr := C.CString(name)
|
||||
C.lua_setfield(l.state, C.int(offset), cstr)
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
}
|
||||
|
||||
func (l Lua) SetGlobal(name string) {
|
||||
cstr := C.CString(name)
|
||||
C.lua_setglobal(l.state, cstr)
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
}
|
||||
|
||||
func (l Lua) GetGlobal(name string) {
|
||||
cstr := C.CString(name)
|
||||
C.lua_getglobal(l.state, cstr)
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
}
|
||||
|
||||
func (l Lua) DoFile(filepath string) int {
|
||||
cstr := C.CString(filepath)
|
||||
defer C.free(unsafe.Pointer(cstr))
|
||||
|
||||
err := int(C.luaL_loadfilex(l.state, cstr, nil))
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
err = int(C.lua_pcallk(l.state, 0, -1, 0, 0, nil))
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (l Lua) ToInteger(offset int) int64 {
|
||||
return int64(C.lua_tointegerx(l.state, C.int(offset), nil))
|
||||
}
|
||||
|
||||
func (l Lua) ToNumber(offset int) float64 {
|
||||
return float64(C.lua_tonumberx(l.state, C.int(offset), nil))
|
||||
}
|
||||
|
||||
func (l Lua) ToBoolean(offset int) bool {
|
||||
return C.lua_toboolean(l.state, C.int(offset)) != 0
|
||||
}
|
||||
|
||||
func (l Lua) ToString(offset int) string {
|
||||
var len C.size_t
|
||||
cstr := C.lua_tolstring(l.state, C.int(offset), &len)
|
||||
return C.GoStringN(cstr, C.int(len))
|
||||
}
|
||||
|
||||
func (l Lua) PushInteger(i int64) {
|
||||
C.lua_pushinteger(l.state, C.lua_Integer(i))
|
||||
}
|
||||
|
||||
func (l Lua) PushNumber(f float64) {
|
||||
C.lua_pushnumber(l.state, C.lua_Number(f))
|
||||
}
|
||||
|
||||
func (l Lua) PushString(s string) {
|
||||
cstr := C.CString(s)
|
||||
C.lua_pushstring(l.state, cstr)
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
}
|
||||
|
||||
func (l Lua) PushFunction(fn Function) {
|
||||
i := NextFuncID
|
||||
for true {
|
||||
if _, exists := FuncIDs[i]; !exists {
|
||||
break
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
|
||||
ud := C.lua_newuserdatauv(l.state, 8, 1)
|
||||
|
||||
*(*C.uint64_t)(ud) = C.uint64_t(i)
|
||||
|
||||
cstr := C.CString("GLUA_FUNCTION")
|
||||
C.luaL_setmetatable(l.state, cstr)
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
|
||||
FuncIDs[i] = FuncStatePair{fn, &l};
|
||||
}
|
||||
|
||||
func (l Lua) PushValue(offset int) {
|
||||
C.lua_pushvalue(l.state, C.int(offset));
|
||||
}
|
||||
|
||||
func (l Lua) Pop(count int) {
|
||||
C.lua_settop(l.state, C.int(-count - 1));
|
||||
}
|
||||
|
||||
func (l Lua) Call(nargs int, nresults int, msgh int) int {
|
||||
err := int(C.lua_pcallk(l.state, C.int(nargs), C.int(nresults), C.int(msgh), 0, nil))
|
||||
if err == 2 {
|
||||
l.PushValue(-1)
|
||||
why := l.ToString(-1)
|
||||
l.Pop(1)
|
||||
|
||||
panic(why)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (l Lua) ProtectedCall(nargs int, nresults int, msgh int) int {
|
||||
return int(C.lua_pcallk(l.state, C.int(nargs), C.int(nresults), C.int(msgh), 0, nil))
|
||||
}
|
||||
|
||||
func (l Lua) UnsafeCall(nargs int, nresults int) {
|
||||
C.lua_callk(l.state, C.int(nargs), C.int(nresults), 0, nil)
|
||||
}
|
||||
8
go.mod
Normal file
8
go.mod
Normal file
@ -0,0 +1,8 @@
|
||||
module mid.net.ua/git/mid/goci
|
||||
|
||||
go 1.25
|
||||
|
||||
require (
|
||||
github.com/Shopify/go-lua v0.0.0-20250718183320-1e37f32ad7d0 // indirect
|
||||
github.com/mappu/miqt v0.13.0 // indirect
|
||||
)
|
||||
4
go.sum
Normal file
4
go.sum
Normal file
@ -0,0 +1,4 @@
|
||||
github.com/Shopify/go-lua v0.0.0-20250718183320-1e37f32ad7d0 h1:oGlw/+ndlFMn8KWLjEX5nULcDwOC4tJy3Kk1Pm84Cys=
|
||||
github.com/Shopify/go-lua v0.0.0-20250718183320-1e37f32ad7d0/go.mod h1:M4CxjVc/1Nwka5atBv7G/sb7Ac2BDe3+FxbiT9iVNIQ=
|
||||
github.com/mappu/miqt v0.13.0 h1:Dzvclso1BwAUVNem7giSYCmh4Rx08j2gqt6j4SCy098=
|
||||
github.com/mappu/miqt v0.13.0/go.mod h1:xFg7ADaO1QSkmXPsPODoKe/bydJpRG9fgCYyIDl/h1U=
|
||||
41
main.go
Normal file
41
main.go
Normal file
@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import "os"
|
||||
import "fmt"
|
||||
import "github.com/mappu/miqt/qt6"
|
||||
|
||||
import "mid.net.ua/git/mid/goci/glua"
|
||||
|
||||
func InitUI() {
|
||||
qt6.NewQApplication(os.Args)
|
||||
|
||||
mw := qt6.NewQMainWindow(nil)
|
||||
|
||||
{
|
||||
dock := qt6.NewQDockWidget(mw.QWidget)
|
||||
mw.AddDockWidget(qt6.DockWidgetArea(1), dock)
|
||||
}
|
||||
|
||||
mw.Show()
|
||||
}
|
||||
|
||||
var L glua.Lua
|
||||
func InitLua() {
|
||||
L := glua.NewState()
|
||||
L.OpenLibs()
|
||||
|
||||
L.NewTable()
|
||||
// Our interface functions go here
|
||||
L.SetGlobal("UI")
|
||||
|
||||
L.DoFile("main.lua")
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("I'm printing dis to prevent unused package warning")
|
||||
|
||||
InitUI()
|
||||
InitLua()
|
||||
|
||||
qt6.QApplication_Exec()
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user