bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.7k stars 3.53k forks source link

System ordering using `before` and `after` panics when inserting resources #8602

Closed TsujimotoYukasuke closed 1 year ago

TsujimotoYukasuke commented 1 year ago

System Information

Issue

Was attempting to insert a resource into my ecs using one system which would then be used by another. I used the .before and .after system ordering in order to do this. I remember being able to do so using simple system names.

Here's a reproducible example:

use bevy::prelude::*;

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

fn main() {
    App::new()
        .add_startup_system(system_a)
        .add_startup_system(system_b.after(system_a))
        .run();
}

fn system_a(mut commands: Commands) {
    commands.insert_resource(AResource(5));
}

fn system_b(a_resource: Res<AResource>) {
    println!("{}", a_resource.0);
}

What I expected to happen

The system to print 5

What actually happened

Rust panic. Error: thread 'TaskPool (10)' panicked at 'Resource requested by bug_test::system_b does not exist: bug_test::AResource', C:\Users\tsuji\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_ecs-0.10.1\src\system\system_param.rs:460:17

Additional information

This works properly if I use system sets rather than using .before or .after.

use bevy::prelude::*;

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

fn main() {
    App::new()
        .add_startup_system(system_a.in_base_set(StartupSet::PreStartup))
        .add_startup_system(system_b.in_base_set(StartupSet::PostStartup))
        .run();
}

fn system_a(mut commands: Commands) {
    commands.insert_resource(AResource(5));
}

fn system_b(a_resource: Res<AResource>) {
    println!("{}", a_resource.0);
}

I'm wondering if I am just using this incorrectly, and if so I apologize for the false report.

SkiFire13 commented 1 year ago

Commands are not immediately applied after a system ends, but instead they are applied only at certain synchronization points. There is a default synchronization point between the two sets, but using after/before/chain doesn't create one. Instead you have to manually insert a apply_system_buffers system in between the two.

TsujimotoYukasuke commented 1 year ago

I see, I remember reading that somewhere. This works as intended then, sorry for the false bug report.