mirror of
https://github.com/mappu/miqt.git
synced 2025-01-20 21:50:38 +00:00
mainthread: add qt5 port
This commit is contained in:
parent
4fa5c6b1a2
commit
0b96c758ee
14
qt/mainthread/mainthread.cpp
Normal file
14
qt/mainthread/mainthread.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <QMetaObject>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
#include "mainthread.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void mainthread_exec_handle(intptr_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainthread_exec(intptr_t cb) {
|
||||||
|
QMetaObject::invokeMethod(qApp, [=]{
|
||||||
|
mainthread_exec_handle(cb);
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
}
|
69
qt/mainthread/mainthread.go
Normal file
69
qt/mainthread/mainthread.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package mainthread
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"runtime/cgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo pkg-config: Qt5Core
|
||||||
|
|
||||||
|
#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()
|
||||||
|
}
|
18
qt/mainthread/mainthread.h
Normal file
18
qt/mainthread/mainthread.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef MIQT_QT_MAINTHREAD_H
|
||||||
|
#define MIQT_QT_MAINTHREAD_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void mainthread_exec(intptr_t cb);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user