mirror of
https://github.com/mappu/miqt.git
synced 2025-01-18 04:50:36 +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 {
|
||||
tmp := make([]string, 0, len(m.Parameters)+1)
|
||||
|
||||
@ -342,6 +385,10 @@ extern "C" {
|
||||
|
||||
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+"*")))
|
||||
|
||||
if m.IsSignal {
|
||||
ret.WriteString(fmt.Sprintf("%s %s_connect_%s(void* slot);\n", emitReturnTypeCabi(m.ReturnType), c.ClassName, m.SafeMethodName()))
|
||||
}
|
||||
}
|
||||
|
||||
// delete
|
||||
@ -383,7 +430,13 @@ func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) {
|
||||
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 {
|
||||
|
||||
@ -496,6 +549,19 @@ func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) {
|
||||
shouldReturn, callTarget, nativeMethodName, forwarding,
|
||||
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
|
||||
|
@ -230,7 +230,7 @@ func emitParametersGo2CABIForwarding(m CppMethod) (preamble string, fowarding st
|
||||
func emitGo(src *CppParsedHeader, headerName string) (string, error) {
|
||||
|
||||
ret := strings.Builder{}
|
||||
ret.WriteString(`package miqt
|
||||
ret.WriteString(`package qt
|
||||
|
||||
/*
|
||||
|
||||
@ -374,6 +374,20 @@ import "C"
|
||||
` + 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) {
|
||||
|
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