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