Skip to content

Conversation

SpecificProtagonist
Copy link
Contributor

@SpecificProtagonist SpecificProtagonist commented Mar 7, 2025

Objective

Since the issue was made, Bevy's plugins have been split into three stages that are (typically) run before app update: Build, finish and cleanup. They also have a ready method to delay the switch from the build to the finish phase.

This allows plugins to delay up to twice while waiting on other plugins, but the specific dependency is implicit even when reading the code and the ordering of plugins matters. Solve this by making plugin building concurrent.

Also, I've just now seen #8607, which also makes plugins asynchronous. I'll need to take a closer look, but afaik it has the goal of running on bevy_tasks and doesn't address dependencies / plugin ordering (as it build plugins one at a time).

Solution

Adds Plugin::build_async, which runs concurrently for all plugins. The plugin can wait for the world to reach whatever state it needs to continue. While you can define a custom condition, there's also a helper for waiting on a resource; please suggest other ones.

This is intended to replace the old plugin lifecycle machinery, which can be deprecated (and eventually removed) in a later PR, which will make things much simpler. As noted in #1255, we'll want to defer app construction actions (like add_systems); with this PR, the collected actions can be run by turning them into an async plugin.

As a followup, we should be able to use a waker and achieve the goals of #8607.

Testing

(TODO: Add plenty of tests if we decide to do this)

Showcase

#[derive(Resource)]
struct A(i32);

struct MyPlugin;

impl Plugin for MyPlugin {
    async fn build_async(self: Box<Self>, mut ctx: PluginContext<'_>) {
        let a = ctx.resource::<A>().await.unwrap();
        println!("got A: {}", a.0);
    }
}

struct OtherPlugin;

impl Plugin for OtherPlugin {
    async fn build_async(self: Box<Self>, mut ctx: PluginContext<'_>) {
        ctx.app().world_mut().insert_resource(A(1));
    }
}

Migration Guide

(TODO depending on changes)

@SpecificProtagonist SpecificProtagonist added C-Feature A new feature, making something new possible A-App Bevy apps and plugins X-Contentious There are nontrivial implications that should be thought through S-Needs-Review Needs reviewer attention (from anyone!) to move forward D-Async Deals with asynchronous abstractions labels Mar 7, 2025
@JMS55
Copy link
Contributor

JMS55 commented Mar 7, 2025

Waiting on a specific plugin to finish would be nice since sometimes you have:

  • Plugin A sometimes inserts a resource, sometimes doesn't
  • Plugin B wants to wait for Plugin A to finish, and then check if the resource exists or not

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-App Bevy apps and plugins C-Feature A new feature, making something new possible D-Async Deals with asynchronous abstractions S-Needs-Review Needs reviewer attention (from anyone!) to move forward X-Contentious There are nontrivial implications that should be thought through

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugin Dependencies

2 participants