White-Oak / qml-rust

QML (Qt Quick) bindings for Rust language
MIT License
205 stars 18 forks source link

allow manually spinning the event loop #25

Closed flanfly closed 7 years ago

flanfly commented 7 years ago

Exposes sendPostedEvents and processEvents. See filcuc/DOtherSide#49 for details.

White-Oak commented 7 years ago

@flanfly soo, ehh, what is the use case? Any examples?

flanfly commented 7 years ago

A simple example would be a long running function that's called from QML. While the function is running, the GUI freezes. Calling process_events() and send_posted_events() inside this function keeps the event loop spinning and the UI responsive. My use case is a bit more complex. I need to integrate QML with another event loop. So instead of QmlEngine::exec() I do this:

loop {
    engine.send_posted_events();
    engine.process_events();
    if !dispatch_my_events() {
        break;
    }
}
rustonaut commented 7 years ago

while it can be done, it is generally highly recommended to run any longer running jobs in a different thread. Hacking some background job into the main thread makes only sense if you have some other strong extern restrictions, e.g. when using it on some "special" embedded system.

Through a reason could be to merge another event loop into the main event loop, which forwards it's events to the Qt's event loop and you want to evade some multi threading dangers, or possible racing conditions.

So if it is not much overhead it might not hurt and get some usages, through IMHO most good usages for it require a interface for the general event system, too.

rustonaut commented 7 years ago

well, it looks like a safe, strait and simple forwarding of a DOS function, so why not :smile:

flanfly commented 7 years ago

Hey @dathinab. I actually do launch threads for long running tasks and this is a reason I need my own event loop in the main thread. When the thread finishes I need to manipulate QObjects to signal the QML side that new data is available. This can only be done from the main thread.

rustonaut commented 7 years ago

ok, through can't you use signals? They are thread safe as far as I know (through their data might not).

flanfly commented 7 years ago

Edit: For this a QObject would need to live in the new thread and emit a signal when it's done. QObjects in qml-rust don't implement Send, so I cannot move it into the new thread.

  1. Edit: Doing it the other way around: emitting a signal from an QObject living in the main thread also involves Send. Without it the new thread cannot acquire the needed reference to the QObject.
rustonaut commented 7 years ago

Oh, I was not aware of this. In this case just ignore what I said before :=) Through in the long run it would be nice to be able to register signals from another thread.

On Fri, Nov 18, 2016, 19:57 Kai Michaelis notifications@github.com wrote:

QObjects in qml-rust don't implement Send, so I cannot move it into the new thread.

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/White-Oak/qml-rust/pull/25#issuecomment-261612140, or mute the thread https://github.com/notifications/unsubscribe-auth/AHR0ka1XLPXelWvoS8ZzeStxRnvWsj7rks5q_fUNgaJpZM4K2U8E .

White-Oak commented 7 years ago

This is, actually, a big problem -- whether QObject should be Send or not.

It is easily made into one, but I'm not sure if underlying Qt's object is thread-safe. There is an example in this repo, that shows, that it is ok to call signals from other threads, but I didn't check if it is okay to do this with slots as well.

@flanfly will it solve your problem, if QObject is made Send?

Edit: threaded methof in the linked example is implemented here. It is done via unsafe magic, because, as mentioned before, QObject is not Send.

flanfly commented 7 years ago

Hey @White-Oak, using your threaded method solves my problem. A "real" use where a thread accesses fields or properties of the structure needs a lock to synchronize access, though.

White-Oak commented 7 years ago

@flanfly definetily! Thanks for the suggestion