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

Support triggering the winit render loop from an external source #12159

Closed
R081n opened this issue Feb 27, 2024 · 3 comments
Closed

Support triggering the winit render loop from an external source #12159

R081n opened this issue Feb 27, 2024 · 3 comments
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Feature A new feature, making something new possible

Comments

@R081n
Copy link
Contributor

R081n commented Feb 27, 2024

What problem does this solve or what need does it fill?

We want to use Bevy to display data that is streamed from an external source. Additionally we want to save resources by using WinitSettings::desktop_app(). To do this we need a way to tell bevy to run the render loop from an external source.

What solution would you like?

In version 0.12 it was possible to trigger the event loop, using the winit EventLoopProxy which is added as a Resource in the winit runner. Sending a UserEvent<()> then triggered the event loop once. This seemed to be unintentional.

In version 0.13 the UserEvent no longer triggers the event loop.

A possible solution would be to explicitly handle the UserEvent in the winit runner by simply running an update or allow the default winit runner to be parameterized by a custom handler. I did not find a reason why the EventLoopProxy is currently added as a Resource.

Additionally the EventLoopProxy should be reexported.

@R081n R081n added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Feb 27, 2024
@alice-i-cecile alice-i-cecile added A-Windowing Platform-agnostic interface layer to run your app in and removed S-Needs-Triage This issue needs to be labelled labels Feb 28, 2024
@alice-i-cecile
Copy link
Member

I'd welcome a PR for this :) I don't think it's likely to be prioritized otherwise: this is relatively complex code in a niche use case.

github-merge-queue bot pushed a commit that referenced this issue Mar 4, 2024
Hi, this is a minimal implementation of #12159. I wasn't sure if the
`EventLoopProxy` should be wrapped somewhat to make it more explicit.

# Objective

Minimal implementation of #12159
When using `UpdateMode::Reactive` it is currently not possible to
request a redraw when a long running task is finished or an external
source has new data.

This makes the following possible which will then run an app update once

``` rust
// EventLoopProxy is Send on most architectures
// The EventLoopProxy can also be saved in a thread local for WASM or a static in other architecturecs
pub fn example(proxy: NonSend<EventLoopProxy<()>>) {
    let clone: EventLoopProxy<()> = proxy.clone();
    thread::spawn(move || {
        // do long work
        clone.send_event(());
    });
}
```

## Solution

By using the EventLoopProxy one can manually send events from external
threads to the event loop as `UserEvent`s.
This simply sets redraw_requested when a `UserEvent` is received.

## Changelog

- Added the ability to request a redraw from an external source

---------

Co-authored-by: Kellner, Robin <[email protected]>
mockersf pushed a commit that referenced this issue Mar 5, 2024
Hi, this is a minimal implementation of #12159. I wasn't sure if the
`EventLoopProxy` should be wrapped somewhat to make it more explicit.

Minimal implementation of #12159
When using `UpdateMode::Reactive` it is currently not possible to
request a redraw when a long running task is finished or an external
source has new data.

This makes the following possible which will then run an app update once

``` rust
// EventLoopProxy is Send on most architectures
// The EventLoopProxy can also be saved in a thread local for WASM or a static in other architecturecs
pub fn example(proxy: NonSend<EventLoopProxy<()>>) {
    let clone: EventLoopProxy<()> = proxy.clone();
    thread::spawn(move || {
        // do long work
        clone.send_event(());
    });
}
```

By using the EventLoopProxy one can manually send events from external
threads to the event loop as `UserEvent`s.
This simply sets redraw_requested when a `UserEvent` is received.

- Added the ability to request a redraw from an external source

---------

Co-authored-by: Kellner, Robin <[email protected]>
spectria-limina pushed a commit to spectria-limina/bevy that referenced this issue Mar 9, 2024
…ne#12197)

Hi, this is a minimal implementation of bevyengine#12159. I wasn't sure if the
`EventLoopProxy` should be wrapped somewhat to make it more explicit.

# Objective

Minimal implementation of bevyengine#12159
When using `UpdateMode::Reactive` it is currently not possible to
request a redraw when a long running task is finished or an external
source has new data.

This makes the following possible which will then run an app update once

``` rust
// EventLoopProxy is Send on most architectures
// The EventLoopProxy can also be saved in a thread local for WASM or a static in other architecturecs
pub fn example(proxy: NonSend<EventLoopProxy<()>>) {
    let clone: EventLoopProxy<()> = proxy.clone();
    thread::spawn(move || {
        // do long work
        clone.send_event(());
    });
}
```

## Solution

By using the EventLoopProxy one can manually send events from external
threads to the event loop as `UserEvent`s.
This simply sets redraw_requested when a `UserEvent` is received.

## Changelog

- Added the ability to request a redraw from an external source

---------

Co-authored-by: Kellner, Robin <[email protected]>
@james7132
Copy link
Member

@R081n is there anything remaining after #12197?

@R081n
Copy link
Contributor Author

R081n commented Mar 10, 2024

@R081n is there anything remaining after #12197?

Not really, a way for the EventLoopProxy to carry data would be interesting, though i don't think it is really worth it when a channel can do it already. 👍

mtsr pushed a commit to mtsr/bevy that referenced this issue Mar 15, 2024
…ne#12197)

Hi, this is a minimal implementation of bevyengine#12159. I wasn't sure if the
`EventLoopProxy` should be wrapped somewhat to make it more explicit.

# Objective

Minimal implementation of bevyengine#12159
When using `UpdateMode::Reactive` it is currently not possible to
request a redraw when a long running task is finished or an external
source has new data.

This makes the following possible which will then run an app update once

``` rust
// EventLoopProxy is Send on most architectures
// The EventLoopProxy can also be saved in a thread local for WASM or a static in other architecturecs
pub fn example(proxy: NonSend<EventLoopProxy<()>>) {
    let clone: EventLoopProxy<()> = proxy.clone();
    thread::spawn(move || {
        // do long work
        clone.send_event(());
    });
}
```

## Solution

By using the EventLoopProxy one can manually send events from external
threads to the event loop as `UserEvent`s.
This simply sets redraw_requested when a `UserEvent` is received.

## Changelog

- Added the ability to request a redraw from an external source

---------

Co-authored-by: Kellner, Robin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Feature A new feature, making something new possible
Projects
None yet
Development

No branches or pull requests

3 participants