mirror of
https://github.com/mappu/miqt.git
synced 2025-01-08 00:28:36 +00:00
70 lines
1.3 KiB
Go
70 lines
1.3 KiB
Go
package mainthread
|
|
|
|
import (
|
|
"sync"
|
|
"runtime/cgo"
|
|
)
|
|
|
|
/*
|
|
#cgo pkg-config: Qt6Core
|
|
|
|
#include "mainthread.h"
|
|
*/
|
|
import "C"
|
|
|
|
// Start runs the callback in the main Qt thread. You should use this whenever
|
|
// accessing the main Qt GUI from inside a goroutine.
|
|
// This function is non-blocking.
|
|
func Start(gofunc func()) {
|
|
h := cgo.NewHandle(gofunc)
|
|
|
|
C.mainthread_exec(C.intptr_t(h))
|
|
}
|
|
|
|
// Wait runs the callback in the main Qt thread. You should use this whenever
|
|
// accessing the main Qt GUI from inside a goroutine.
|
|
// The call blocks until the callback is executed in the main thread's eventloop.
|
|
func Wait(gofunc func()) {
|
|
// It's possible to use Qt::BlockingQueuedConnection to implement the
|
|
// blocking, but it has a deadlock risk
|
|
var wg sync.WaitGroup
|
|
wg.Add(1)
|
|
outerfunc := func() {
|
|
gofunc()
|
|
wg.Done()
|
|
}
|
|
Start(outerfunc)
|
|
wg.Wait()
|
|
}
|
|
|
|
func Wait2[T any](gofunc func() T) (ret T) {
|
|
outerfunc := func() {
|
|
ret = gofunc()
|
|
}
|
|
Wait(outerfunc)
|
|
return ret
|
|
}
|
|
|
|
func Wait3[T any](gofunc func() (T, error)) (ret T, err error) {
|
|
outerfunc := func() {
|
|
ret, err = gofunc()
|
|
}
|
|
Wait(outerfunc)
|
|
return ret, err
|
|
}
|
|
|
|
//export mainthread_exec_handle
|
|
func mainthread_exec_handle(u uintptr) {
|
|
h := cgo.Handle(u)
|
|
|
|
gofunc, ok := h.Value().(func())
|
|
if !ok {
|
|
panic("miqt: callback of non-callback type (heap corruption?)")
|
|
}
|
|
|
|
gofunc()
|
|
|
|
// Free handle after use
|
|
h.Delete()
|
|
}
|