Skip to content

archetype access not updated on all systems (Result::unwrap() on an Err value: CannotReadArchetype) #259

Closed
@robinvd

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(),
         })
     }

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-BugAn unexpected or incorrect behaviorP-CrashA sudden unexpected crash

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions