Skip to content

Render events #18517

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Render events #18517

wants to merge 8 commits into from

Conversation

ecoskey
Copy link
Contributor

@ecoskey ecoskey commented Mar 24, 2025

Objective

fix #18491 (comment)
Sometimes users want to send events from the render world to the main world. While not often advised, some advanced use-cases like readback use a similar pattern, which often requires setting up a channel and relaying events manually.

Solution

Add a simple abstraction (App::init_render_event) to set up the channel and relay events to the main world, retaining caller information.

Note: this pr makes Events::send_with_caller public, but does not add a similar public method on EventWriter

Testing

Ran example

Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@ecoskey ecoskey requested a review from IceSentry March 24, 2025 17:52
@ecoskey ecoskey added A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Mar 24, 2025
@JMS55
Copy link
Contributor

JMS55 commented Mar 24, 2025

Quickly leaving my thoughts, I don't love the events naming.

It has nothing to do with events about rendering, but is just an arbitrary channel for sending data back to the main world, right?

Not sure what a better name is though, and again haven't looked at the PR to deeply yet.

@IceSentry
Copy link
Contributor

They are events from the render world. I think it's fair to call them render event. Presumably, users will need this to send events in the context of rendering. Otherwise they wouldn't need events sent from the render world. Maybe specify render world event just to remove any possible ambiguity, but I'm not sure what kind of ambiguity there could be.

@ecoskey ecoskey added this to the 0.17 milestone Apr 10, 2025
Comment on lines +38 to +45
let send_render_event = (
ParamBuilder,
ParamBuilder,
ParamBuilder,
LocalBuilder(Timer::from_seconds(2.0, TimerMode::Repeating)),
)
.build_state(render_app.world_mut())
.build_system(send_render_event);
Copy link
Contributor

Choose a reason for hiding this comment

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

This feels a bit unnecessarily complex. I'd suggest using a resource instead just because that's a more common ECS api.

Copy link
Member

@tychedelia tychedelia left a comment

Choose a reason for hiding this comment

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

Think formalizing this makes sense versus ad hoc. 👍


use crate::RenderApp;

pub trait RenderEventApp {
Copy link
Member

Choose a reason for hiding this comment

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

Not sure what our convention is here -- should this be in the prelude so it doesn't have to be imported?

///
/// Internally, this struct writes to a channel, the contents of which are relayed
/// to the main world's [`Events`] stream during [`PreUpdate`]. Note that because
/// the render world is pipelined, the events may not arrive before the next frame begins.
Copy link
Member

Choose a reason for hiding this comment

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

They almost certainly will not, but they also could. I think we might want to be clearer about how this works. In practice, you'll receive events from rendering frame N-2 with respect the the main world, but that isn't guaranteed. Users should supply their own temporal correlation id if necessary.

@@ -0,0 +1,90 @@
//! Simple example demonstrating the use of [`App::init_render_event`] to send events from the
Copy link
Member

Choose a reason for hiding this comment

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

This should be expanded to say, in effect, "you probably don't want to do this."

@tychedelia tychedelia added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Apr 21, 2025
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

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

Broadly on-board with this pattern and it existing, but I think we need to clean this up before merging.

Key things:

  • the system builder in the example is too complicated and distracts from the point of the example
  • the example description needs to be expanded to give more context
  • this needs a non "Event" naming scheming to avoid confusion. Maybe something with "channel" in it?

Long-term, this should be baked into a multi-world ECS design, and not need channels, but formalizing this pattern in some form is a good way to gather requirements and ease refactoring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

Send events from the render world to the main world
5 participants