Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper function to run code on the main UI thread #76

Open
mappu opened this issue Nov 12, 2024 · 0 comments
Open

Add helper function to run code on the main UI thread #76

mappu opened this issue Nov 12, 2024 · 0 comments

Comments

@mappu
Copy link
Owner

mappu commented Nov 12, 2024

The example port in #70 uncovered an issue: that MIQT is currently missing functions that can transport a callback onto the main thread.

Draft plan

Possible ideas:

  1. moveToThread
  2. QCoreApplication::postEvent
  3. Emits are allowed cross-thread ⭐

Add cpp:

#include <QObject>

class signaller : public QObject {
	Q_OBJECT
	
private:
	
	do_self_emit_blocking(handle) {
		emit please_run_blocking(handle);
	}
	do_self_emit_async(handle) {
		emit please_run_async(handle);
	}
	
signals:

	void please_run_blocking(handle);
	void please_run_async(handle);
	
public:

	static signaller* singleton() {
		static signaller instance;
		return &instance;
	}
	
	Qt::HANDLE main_thread_id;
	
	static void do_on_main_thread_async(handle) {
		// Always async, no need to run the callback ourselves
		singleton()->do_self_emit_async(handle)
	}
	
	static void do_on_main_thread_blocking(handle) {
		if (QThread::currentThreadId() == main_thread_id) {
			// Call it ourselves to avoid deadlock
			miqt_exec_callback(handle);
		} else {
			singleton()->do_self_emit_blocking(handle)
		}
	}

}

n.b. needs pre-MOC:

  • /usr/lib/qt5/bin/moc --help
  • /usr/lib/qt6/libexec/moc --help

CABI: After constructing QMainApplication:

// signal comes from another thread, so use queuedconnection
signaller::singleton()->main_thread_id = QThread::currentThreadId();

connect(signaller::singleton(), please_run_blocking, this, [=](handle) {
	miqt_exec_callback(handle);
}, Qt::BlockingQueuedConnection);

connect(signaller::singleton(), please_run_async, this, [=](handle) {
	miqt_exec_callback(handle);
}, Qt::QueuedConnection);

The Go interface:

qt.MainThread(func() {
})

qt.MainThreadAsync(func() {
})

// implementation will call CABI signaler_do_on_main_thread(handle)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant