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

Feature Request: Add poll_events API to cooperate with other event loop #2763

Open
zuoxinyu opened this issue May 22, 2023 · 9 comments
Open
Labels
api Changes or additions to APIs enhancement New feature or request

Comments

@zuoxinyu
Copy link

I'm using C++ API, need a slint::poll_events API to integrate with other event system like SDL2 or libuv. Currently there is a workaround by using a repeat timer. But I'm glad to see there would be a dedicate API for this purpose.

@zuoxinyu zuoxinyu changed the title Feature Request: Add poll_events API to integrate with other event loop Feature Request: Add poll_events API to cooperate with other event loop May 22, 2023
@tronical tronical added the enhancement New feature or request label May 26, 2023
@tronical
Copy link
Member

Yes, perhaps this is doable. What's a little tricky is that neither with Qt nor with Winit we can get the file descriptors needed for polling. Could you describe a little how your ideal setup would look like?

@zuoxinyu
Copy link
Author

zuoxinyu commented May 26, 2023

Yes, perhaps this is doable. What's a little tricky is that neither with Qt nor with Winit we can get the file descriptors needed for polling. Could you describe a little how your ideal setup would look like?

I don't think it has anything to do with file descriptors here.

A poll() API typically is used as while (true) { slint::poll(); } instead of slint::run_event_loop(). Inner the loop users can do some other stuffs.

@tronical
Copy link
Member

At what point should slint::poll(); return? Only when an event was received? If no event was received, then after a timeout? What do you do after the timeout? Poll libuv? If you want to poll both simultaneously then, then it sounds like you end up spinning the CPU needlessly?

@zuoxinyu
Copy link
Author

zuoxinyu commented May 26, 2023

There are several strategies:

  1. return after a fixed timeout such as 16ms, e.g. an overloaded version poll(duration) in c++ or a poll_timeout(duration) in rust.
  2. after processing all the queued events, return a true or an int indicates the number of processed events.
  3. if the event queue is empty, then return a false or zero immediately.

These are very common usecases in an eventloop based programming model. In other frameworks, an event loop is always combined with a poll semantic such as SDL2, libuv, Qt, asio.

If you want to poll both simultaneously then, then it sounds like you end up spinning the CPU needlessly?

It's the users' duty to avoid a busy loop in case of using a poll semantic.

@tronical
Copy link
Member

Right, so you'd basically run a while loop that first polls Slint, then polls SDL, then maybe libuv - each with a timeout one after the other? It's not optimal, but probably acceptable for many :-)

We could offer this, indeed - using processEvents() with Qt and run_return() with winit - despite all the caveats.

@zuoxinyu
Copy link
Author

Yes, users who use this api should take care about the caveats themeselves.

@willglynn
Copy link

These are very common usecases in an eventloop based programming model. In other frameworks, an event loop is always combined with a poll semantic such as SDL2, libuv, Qt, asio.

This is specifically incompatible with target environments where the platform owns the event loop. This includes every web browser, Windows, MacOS, and both major mobile platforms. winit was originally built the way you describe, with the user running a loop {} in fn main(), but ultimately was rearchitected to invert the control flow. Having the platform loop call the application always works, while having an application loop call the platform doesn't.

Slint could offer a poll_events() API in at least some configurations, but I don't think it's viable to offer it in all configurations.

@zuoxinyu
Copy link
Author

These are very common usecases in an eventloop based programming model. In other frameworks, an event loop is always combined with a poll semantic such as SDL2, libuv, Qt, asio.

This is specifically incompatible with target environments where the platform owns the event loop. This includes every web browser, Windows, MacOS, and both major mobile platforms. winit was originally built the way you describe, with the user running a loop {} in fn main(), but ultimately was rearchitected to invert the control flow. Having the platform loop call the application always works, while having an application loop call the platform doesn't.

Slint could offer a poll_events() API in at least some configurations, but I don't think it's viable to offer it in all configurations.

Then alternatively, Slint could provide a hook method to support this.

@ogoffart
Copy link
Member

Maybe it would be useful to understand the exact use-case and how we can solve it.
What are we trying to solve?
Can this be solved by using thread and callbacks? (slint::invoke_from_event_loop or slint::blocking_invoke_from_event_loop

@ogoffart ogoffart added the api Changes or additions to APIs label Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api Changes or additions to APIs enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants