-
Notifications
You must be signed in to change notification settings - Fork 92
Description
I have already touched upon my experiments in a slightly related #98, and since @ratijas seemed to be interested, I decided to start a discussion here too.
Maybe you're also interested in reading this little proof of concept that I made last month
Truly interesting. I've been experimenting with Sailfish OS during university course. Wonderful and terribly underestimated piece of mobile technology.
Context
What qmetaobject-rs
currently does, is starting Qt's event loop and handing off control to Qt. From there, Qt calls back into Rust's primitives. In my proof of concept (blog post), I've built an event loop in Rust that's capable of driving all events in Qt (read: all events that I needed on a SailfishOS application). I currently wrote this in the application I am writing, having to duplicate some C++ code from qmetaobject
on the way.
Dispatching the Qt events from a Rust based event loop has one big advantage: there is no need any more to synchronize data between a Rust event loop (you're possibly running sockets and I/O from Rust) and the Qt event loop, because they're one and the same: before this integration, I had to basically put everything behind Arc<Mutex<T>>
. It might also reduce some resource usage, since it reduces the thread count by one (although Qt loves to spawn threads, apparently, so that's not a lot).
Proposals
- I think it might be interesting to provide a
trait QAbstractEventDispatcher
, for further implementation by Rust applications. This should be fairly doable. We'd also require to correctly exportstruct QSockNotifier
, and probably some other types that I have currently not implemented (because they're unneeded in my own case). - I have written a very bare, ugly, and slightly hacky implementation to tie Tokio to a
QAbstractEventDispatcher
. With thorough clean-up, this could land in this crate in two forms:- as an example of how to implement
QAbstractEventDispatcher
- as an actual implementation, feature-gated behind a
cfg(feature = "tokio")
, possibly following with anasync-std
implementation too.
- as an example of how to implement
- This is something I haven't tried yet, but I hope to resolve this some time in the near future: a tighter integration of Qt signals and slots with asynchronous Rust. I have no clue yet how this would take form, and this is probably the most challenging of everything I write in this issue.
Possible results
The benefit of all of this combined, would be to write very idiomatic async Rust code, which would also be driving the GUI. For example, my main application logic currently reads (using Actix):
sys.block_on(async {
gui::run().await.unwrap();
});
This run()
method in turns spawn some asynchronous workers, on the same event loop that the GUI is running on.
Alternative forms
Of course, this is all a lot of new (and extremely experimental) features. Whatever the verdict, I will move the bare Tokio logic out of the application I am writing into an external crate. If you think it is too far out of scope for qmetaobject
, I'll start a separate crate for that.
The discussion I would like to have here is which one of the 1, 2, 3 mentioned above would be welcome here. If part should be externalized, I'd like to discuss what interfaces are still necessary in qmetaobject-rs
, as to keep the Tokio-related stuff clean.
I believe that the design of #100 might keep (3) in mind, so I'm tagging that as slightly-related.