-
-
Couldn't load subscription status.
- Fork 4.2k
Description
Bevy version
I saw this behavior at around 0.14 I think but only now got around making a minimal reproducible example on main, or at least a fairly recent commit behind main.
What you did
I ran this code:
use bevy::prelude::*;
#[derive(Resource)]
struct InsertTest;
fn insert_system(mut commands: Commands) {
commands.insert_resource(InsertTest);
}
fn assert_system(world: &mut World) {
assert!(world.contains_resource::<InsertTest>())
}
fn main() {
App::new()
.add_systems(
Update,
(insert_system, assert_system).chain_ignore_deferred()
)
.update();
}What went wrong
assert_system is an exclusive system, therefore it is expected that the command in insert_system is flushed before it runs. The assertion should not fail but it does.
Additional information
I did some extensive testing and noticed that this bug occurs no matter how I do this configuration as long I make use of the _ignore_deferred variants. The following table lists these configurations and gives each a number because that matters for another observation I elaborate further down.
| inserting config by | asserting config by | config | test |
|---|---|---|---|
| system | system | after_ignore_deferred |
❌ 1 |
| system | system | before_ignore_deferred |
❌ 2 |
| system | system | chain_ignore_deferred |
❌ 3 |
| system | set | after_ignore_deferred |
❌ 4 |
| system | set | before_ignore_deferred |
❌ 5 |
| set | system | after_ignore_deferred |
❌ 6 |
| set | system | before_ignore_deferred |
❌ 7 |
| set | set | after_ignore_deferred |
❌ 8 |
| set | set | before_ignore_deferred |
❌ 9 |
| set | set | chain_ignore_deferred |
❌ 10 |
For example the configuration...
(insert_system, assert_system).chain_ignore_deferred()... is the third row in the table, where "inserting config by" with "system" means that the first element in the chain tuple is the system, and "asserting config by" with "system" means that the second element in the tuple is also the system itself.
"set" means if the argument is a set, so a configure_sets with this configuration...
(SetWithInsertSystem, SetWithAssertSystem).chain_ignore_deferred()... is the last row.
chain cannot mix systems and sets, but before and after can mix, therefore these have more rows.
General observations regarding the two system:
- the tests do not fail if
insert_systemis exclusive - the tests do not fail if
insert_systemis exclusive andassert_systemis not exclusive
Third system affecting the outcome of the tests
Now I am adding a third, empty system and order them after the two above. I observed that this results in some test going green suddenly.
fn third() {}| insert-assert config by | third config by | config | ✅ fixes the failing test of ... |
|---|---|---|---|
| each system | system | after |
1 3 4 7 8 9 10 |
| config tuple | system | before |
1 3 4 7 8 9 10 |
| config tuple | system | chain |
4 7 8 9 10 |
| each system | set | after |
1 2 3 5 6 8 9 10 |
| config tuple | set | before |
1 3 4 7 8 9 10 |
| set | system | after |
1 2 3 4 5 7 8 9 10 |
| set | system | before |
1 2 3 5 6 |
| set | set | after |
1 2 3 5 6 |
| set | set | before |
1 2 3 5 6 |
| set | set | chain |
1 2 3 5 6 |
For example this is the first row with 3...
fn main() {
App::new()
.add_systems(
Update,
(
(insert_system, assert_system).chain_ignore_deferred(),
third.after(insert_system).after(assert_system)
)
)
.update();
}... and this the second row with 3 ...
fn main() {
App::new()
.add_systems(
Update,
(
(insert_system, assert_system)
.chain_ignore_deferred().before(third),
third
)
)
.update();
}... which both no longer fail.
General observations regarding the third system:
- it does not matter if
thirdis exclusive or not - If
thirdis configured with_ignore_deferredvariants, it does not affect the results of the first tests - If
thirdis put before the two, not after, it does not affect the result of the first tests
Test file
I generated the tests with this file which also tests many other combinations that do not fail. It might come useful for testing fixes for this issue. Sorry if it looks horribly, that is how I generate tests. 🫣 Also worth noting that I double-checked that like 5 times but mistakes may only come up with a sixth time. I am just comfortable enough to list the results.