Merge pull request #130 from mappu/miqt-mainthread-qt5

qt/mainthread: Add qt5 port, update to avoid cgo_export file
This commit is contained in:
mappu 2025-01-11 17:23:08 +13:00 committed by GitHub
commit 33596d922f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 108 additions and 6 deletions

View 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);
}

View 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()
}

View 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

View File

@ -1,10 +1,11 @@
#include <QMetaObject>
#include <QCoreApplication>
#ifndef _Bool
#define _Bool bool
#endif
#include "_cgo_export.h"
#include "mainthread.h"
extern "C" {
void mainthread_exec_handle(intptr_t);
}
void mainthread_exec(intptr_t cb) {
QMetaObject::invokeMethod(qApp, [=]{

View File

@ -1,7 +1,7 @@
#pragma once
#ifndef QT_MAINTHREAD_H
#define QT_MAINTHREAD_H
#ifndef MIQT_QT6_MAINTHREAD_H
#define MIQT_QT6_MAINTHREAD_H
#include <stdint.h>