-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
101 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |