Skip to content

Add external eventloop support#6750

Merged
emilk merged 7 commits intoemilk:masterfrom
wpbrown:new_external2
Apr 29, 2025
Merged

Add external eventloop support#6750
emilk merged 7 commits intoemilk:masterfrom
wpbrown:new_external2

Conversation

@wpbrown
Copy link
Contributor

@wpbrown wpbrown commented Apr 15, 2025

Adds create_native. Similiar to run_native but it returns an EframeWinitApplication which is a winit::ApplicationHandler. This can be run on your own event loop. A helper fn pump_eframe_app is provided to pump the event loop and get the control flow state back.

I have been using this approach for a few months.

@wpbrown
Copy link
Contributor Author

wpbrown commented Apr 15, 2025

I provided an example of running an event loop on top of tokio. I only use Linux, so I could use help with other native platforms.

@wpbrown
Copy link
Contributor Author

wpbrown commented Apr 15, 2025

If this approach is viable I will work on doc comments.

@wpbrown wpbrown marked this pull request as ready for review April 15, 2025 04:17
@github-actions
Copy link

Preview available at https://egui-pr-preview.github.io/pr/6750-newexternal2
Note that it might take a couple seconds for the update to show up after the preview_build workflow has completed.

@lucasmerlin
Copy link
Collaborator

This looks pretty cool! Just out of curiosity, what are the benefits of running egui in an async way like your example? Versus, just spawning the tokio runtime in another thread.
Is it that you can do spawn_local from the ui and that you only need a single thread?

@wpbrown
Copy link
Contributor Author

wpbrown commented Apr 16, 2025

This looks pretty cool! Just out of curiosity, what are the benefits of running egui in an async way like your example? Versus, just spawning the tokio runtime in another thread. Is it that you can do spawn_local from the ui and that you only need a single thread?

Yes exactly. I am building an app with a lot of CRUD. There is plenty of CPU available to run the UI and the async tasks. Not having to worry about anything being Sync greatly simplifies development (as seen in the example, the UI and background task can share data without locks). When you need to run anything CPU intensive you can use spawn_blocking.

@lucasmerlin
Copy link
Collaborator

This looks great! Please add the missing doc comments and maybe also mention in the example readme why you'd want to do this (basically what you explained in the comment).

@wpbrown
Copy link
Contributor Author

wpbrown commented Apr 27, 2025

@lucasmerlin I updated the readmes and added doc comments.

I fixed the CI issues for windows, ios, mac. I used required-features to prevent building the linux example unless the linux-example feature is specifically added. Unfortunately the check script and CI run with "--all-features", so it tries to build the example on other platforms.

FWIW, I attempted to extend the async example to windows, but it turns out it's not possible with tokio. It would require changes to mio. To block waiting for GUI events on windows you need to use WaitForMultipleObjectsEx. I tried running it on a background thread, but it only works on the thread that created the window. Hopefully in the future someone who cares more about windows or mac will update the example with async executors that supports waiting for GUI events on their platforms.

@lucasmerlin lucasmerlin added feature New feature or request eframe Relates to epi and eframe labels Apr 28, 2025
Copy link
Collaborator

@lucasmerlin lucasmerlin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@wpbrown
Copy link
Contributor Author

wpbrown commented Apr 28, 2025

@lucasmerlin Sorry the update to 1.84 on master broke CI. Here is a successful CI run with master merged in https://github.com/wpbrown/egui/actions/runs/14708125657

@emilk emilk changed the title add external eventloop support Add external eventloop support Apr 29, 2025
@emilk emilk merged commit c075053 into emilk:master Apr 29, 2025
25 checks passed
darkwater pushed a commit to darkwater/egui that referenced this pull request Aug 24, 2025
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

* Closes emilk#2875
* Closes emilk#3340
* [x] I have followed the instructions in the PR template

Adds `create_native`. Similiar to `run_native` but it returns an
`EframeWinitApplication` which is a `winit::ApplicationHandler`. This
can be run on your own event loop. A helper fn `pump_eframe_app` is
provided to pump the event loop and get the control flow state back.

I have been using this approach for a few months.

---------

Co-authored-by: Will Brown <opensource@rebeagle.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

eframe Relates to epi and eframe feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Eframe] Allow eframe to run on an existing event loop

3 participants