archetype access not updated on all systems (Result::unwrap()
on an Err
value: CannotReadArchetype) #259
Closed
Description
In the example i try to access a component by entity, but it fails as the archetype_access for the system is not updated after the spawning of the entity with (A,C)
use bevy::prelude::*;
fn main() {
App::build()
.add_default_plugins()
.add_startup_system(startup_system.system())
.add_system(normal_system.system())
.run();
}
fn startup_system(mut commands: Commands) {
commands.spawn((B(None),));
}
#[derive(Debug)]
struct A;
struct B(Option<Entity>);
struct C;
fn normal_system(mut commands: Commands, a: Query<&mut A>, mut b: Query<&mut B>) {
for mut b in &mut b.iter() {
match b.0 {
Some(entity) => {
dbg!(a.get::<A>(entity)).unwrap();
}
None => {
let new = commands.spawn((A, C)).current_entity().unwrap();
b.0 = Some(new);
}
}
}
}
output
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: CannotReadArchetype', examples/ecs/startup_system.rs:27:42
Something like this fixes it, but im not sure if this is the right solution. (should probably be fixed in parralel_executor). It you could give me some pointers i would love to make a PR.
diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs
index 96a4cff4..8cc1e001 100644
--- a/crates/bevy_ecs/src/system/into_system.rs
+++ b/crates/bevy_ecs/src/system/into_system.rs
@@ -4,7 +4,7 @@ use crate::{
resource::{FetchResource, ResourceQuery, Resources, UnsafeClone},
system::{ArchetypeAccess, Commands, System, SystemId, ThreadLocalExecution},
};
-use bevy_hecs::{Fetch, Query as HecsQuery, World};
+use bevy_hecs::{ArchetypesGeneration, Fetch, Query as HecsQuery, World};
use std::borrow::Cow;
pub(crate) struct SystemFn<State, F, ThreadLocalF, Init, SetArchetypeAccess>
@@ -25,6 +25,7 @@ where
pub id: SystemId,
pub archetype_access: ArchetypeAccess,
pub set_archetype_access: SetArchetypeAccess,
+ last_archetypes_generation: ArchetypesGeneration,
}
impl<State, F, ThreadLocalF, Init, SetArchetypeAccess> System
@@ -58,6 +63,10 @@ where
#[inline]
fn run(&mut self, world: &World, resources: &Resources) {
+ if self.last_archetypes_generation != world.archetypes_generation() {
+ self.update_archetype_access(world);
+ self.last_archetypes_generation = world.archetypes_generation();
+ }
(self.func)(world, resources, &self.archetype_access, &mut self.state);
}
@@ -120,6 +129,7 @@ macro_rules! impl_into_foreach_system {
<($($resource,)*)>::initialize(resources, Some(id));
},
resource_access: <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::access(),
+ last_archetypes_generation: ArchetypesGeneration(u64::MAX),
archetype_access: ArchetypeAccess::default(),
set_archetype_access: |world, archetype_access, _state| {
archetype_access.clear();
@@ -195,6 +205,7 @@ macro_rules! impl_into_query_system {
},
resource_access: <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::access(),
archetype_access: ArchetypeAccess::default(),
+ last_archetypes_generation: ArchetypesGeneration(u64::MAX),
set_archetype_access: |world, archetype_access, state| {
archetype_access.clear();
let mut i = 0;
@@ -321,6 +332,7 @@ where
name: core::any::type_name::<F>().into(),
id: SystemId::new(),
resource_access: TypeAccess::default(),
+ last_archetypes_generation: ArchetypesGeneration(u64::MAX),
archetype_access: ArchetypeAccess::default(),
})
}