mirror of
https://github.com/mappu/miqt.git
synced 2025-01-18 12:50:41 +00:00
genbindings/connect: initial implementation
This commit is contained in:
parent
c8ac62fccd
commit
f488e54f8b
@ -68,6 +68,49 @@ func emitReturnTypeCabi(p CppParameter) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// emitParametersCpp emits the parameter definitions exactly how Qt C++ defines them.
|
||||||
|
func emitParametersCpp(m CppMethod) string {
|
||||||
|
tmp := make([]string, 0, len(m.Parameters))
|
||||||
|
for _, p := range m.Parameters {
|
||||||
|
|
||||||
|
cppType := p.ParameterType
|
||||||
|
if p.Const {
|
||||||
|
cppType = "const " + cppType
|
||||||
|
}
|
||||||
|
if p.Pointer {
|
||||||
|
cppType += "*"
|
||||||
|
}
|
||||||
|
if p.ByRef {
|
||||||
|
cppType += "&"
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = append(tmp, cppType+" "+p.ParameterName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(tmp, `, `)
|
||||||
|
}
|
||||||
|
|
||||||
|
func emitParameterTypesCpp(m CppMethod) string {
|
||||||
|
tmp := make([]string, 0, len(m.Parameters))
|
||||||
|
for _, p := range m.Parameters {
|
||||||
|
|
||||||
|
cppType := p.ParameterType
|
||||||
|
if p.Const {
|
||||||
|
cppType = "const " + cppType
|
||||||
|
}
|
||||||
|
if p.Pointer {
|
||||||
|
cppType += "*"
|
||||||
|
}
|
||||||
|
if p.ByRef {
|
||||||
|
cppType += "&"
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = append(tmp, cppType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(tmp, `, `)
|
||||||
|
}
|
||||||
|
|
||||||
func emitParametersCabi(m CppMethod, selfType string) string {
|
func emitParametersCabi(m CppMethod, selfType string) string {
|
||||||
tmp := make([]string, 0, len(m.Parameters)+1)
|
tmp := make([]string, 0, len(m.Parameters)+1)
|
||||||
|
|
||||||
@ -342,6 +385,10 @@ extern "C" {
|
|||||||
|
|
||||||
for _, m := range c.Methods {
|
for _, m := range c.Methods {
|
||||||
ret.WriteString(fmt.Sprintf("%s %s_%s(%s);\n", emitReturnTypeCabi(m.ReturnType), c.ClassName, m.SafeMethodName(), emitParametersCabi(m, c.ClassName+"*")))
|
ret.WriteString(fmt.Sprintf("%s %s_%s(%s);\n", emitReturnTypeCabi(m.ReturnType), c.ClassName, m.SafeMethodName(), emitParametersCabi(m, c.ClassName+"*")))
|
||||||
|
|
||||||
|
if m.IsSignal {
|
||||||
|
ret.WriteString(fmt.Sprintf("%s %s_connect_%s(void* slot);\n", emitReturnTypeCabi(m.ReturnType), c.ClassName, m.SafeMethodName()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete
|
// delete
|
||||||
@ -383,7 +430,13 @@ func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) {
|
|||||||
ret.WriteString(`#include <` + ref + ">\n")
|
ret.WriteString(`#include <` + ref + ">\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.WriteString("\n")
|
ret.WriteString(`
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
extern void miqt_exec_callback(void* cb, int argc, void* argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
`)
|
||||||
|
|
||||||
for _, c := range src.Classes {
|
for _, c := range src.Classes {
|
||||||
|
|
||||||
@ -496,6 +549,19 @@ func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) {
|
|||||||
shouldReturn, callTarget, nativeMethodName, forwarding,
|
shouldReturn, callTarget, nativeMethodName, forwarding,
|
||||||
afterCall,
|
afterCall,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
if m.IsSignal {
|
||||||
|
exactSignal := `static_cast<void (` + c.ClassName + `::*)(` + emitParameterTypesCpp(m) + `)>(&` + c.ClassName + `::` + nativeMethodName + `)`
|
||||||
|
|
||||||
|
ret.WriteString(
|
||||||
|
`void ` + c.ClassName + `_connect_` + m.SafeMethodName() + `(` + c.ClassName + `* self, void* slot) {` + "\n" +
|
||||||
|
"\t" + c.ClassName + `::connect(self, ` + exactSignal + `, self, [=](` + emitParametersCpp(m) + `) {` + "\n" +
|
||||||
|
"\t\t" + `miqt_exec_callback(slot, 0, nullptr);` + "\n" +
|
||||||
|
"\t});\n" +
|
||||||
|
"}\n" +
|
||||||
|
"\n",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
|
@ -230,7 +230,7 @@ func emitParametersGo2CABIForwarding(m CppMethod) (preamble string, fowarding st
|
|||||||
func emitGo(src *CppParsedHeader, headerName string) (string, error) {
|
func emitGo(src *CppParsedHeader, headerName string) (string, error) {
|
||||||
|
|
||||||
ret := strings.Builder{}
|
ret := strings.Builder{}
|
||||||
ret.WriteString(`package miqt
|
ret.WriteString(`package qt
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -374,6 +374,20 @@ import "C"
|
|||||||
` + afterword + `}
|
` + afterword + `}
|
||||||
|
|
||||||
`)
|
`)
|
||||||
|
|
||||||
|
// Add Connect() wrappers for signal functions
|
||||||
|
if m.IsSignal {
|
||||||
|
imports["unsafe"] = struct{}{}
|
||||||
|
imports["runtime/cgo"] = struct{}{}
|
||||||
|
ret.WriteString(`func (this *` + c.ClassName + `) On` + m.SafeMethodName() + `(slot func()) {
|
||||||
|
var slotWrapper miqtCallbackFunc = func(argc C.int, args *C.void) {
|
||||||
|
slot()
|
||||||
|
}
|
||||||
|
|
||||||
|
C.` + c.ClassName + `_connect_` + m.SafeMethodName() + `(this.h, unsafe.Pointer(uintptr(cgo.NewHandle(slotWrapper))))
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if AllowDelete(c) {
|
if AllowDelete(c) {
|
||||||
|
18
qt/binding.go
Normal file
18
qt/binding.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package qt
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
type miqtCallbackFunc func(argc C.int, args *C.void)
|
||||||
|
|
||||||
|
//export miqt_exec_callback
|
||||||
|
func miqt_exec_callback(cb *C.void, argc C.int, args *C.void) {
|
||||||
|
// Our CABI for all callbacks is void(int, void*).
|
||||||
|
// Our Go ABI is CallbackFunc
|
||||||
|
// Then the Go bindings can unmarshal the arguments and C.free() them as necessary
|
||||||
|
cfunc, ok := (cgo.Handle(uintptr(unsafe.Pointer(cb))).Value()).(miqtCallbackFunc)
|
||||||
|
if !ok {
|
||||||
|
panic("miqt: callback of non-callback type (heap corruption?)")
|
||||||
|
}
|
||||||
|
|
||||||
|
cfunc(argc, args)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user