Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"query attempted to access archetype unavailable via sub world": Bug or just me? #153

Closed
travis-leith opened this issue Jun 18, 2020 · 13 comments

Comments

@travis-leith
Copy link

Here is some code to reproduce (not sure if this is minimal)

use legion::prelude::*;
use tracing::{info, Level};
use tracing_subscriber;

#[derive(Debug)]
struct Money(f64);
#[derive(Debug)]
struct Health(f64);
struct Food(f64);


fn main() {
    let subscriber = tracing_subscriber::fmt()
        .with_max_level(Level::TRACE)
        .init();

    let universe = Universe::new();
    let mut world = universe.create_world();

    world.insert((),
        vec![
            (Money(5.0), Food(5.0)),
        ]
    );
    
    world.insert((),
        vec![
            (Money(4.0), Health(3.0)),
            (Money(4.0), Health(3.0)),
            (Money(4.0), Health(3.0)),
        ]
    );

    let show_me_the_money = SystemBuilder::new("money_show")
        .with_query(<(Read<Money>, Read<Food>)>::query())
        .build(|_, world, _, query| {
            for (money, food) in query.iter(world) {
                info!("Look at my money {:?}", money);
            }
        });

    let health_conscious = SystemBuilder::new("healthy")
        .with_query(<(Read<Money>, Read<Health>)>::query())
        .build(|_, world, _, query| {
            for (money, health) in query.iter(world) {
                info!("So healthy {:?}", health);
            }
        });

    let mut schedule = Schedule::builder()
        .add_system(show_me_the_money)
        .flush()
        .add_system(health_conscious)
        .flush()
        .build();

    let mut resources = Resources::default();
    schedule.execute(&mut world, &mut resources);
}

If you comment out either of the world.insert... statements, it runs without errors.
Am I doing something wrong here?

@Rua
Copy link
Contributor

Rua commented Jun 18, 2020

Not even an hour ago, a patch was committed that fixes some of the access issues with version 0.2.2. Try using the git version instead of 0.2.2 from crates.io, maybe it fixes your issue too.

@travis-leith
Copy link
Author

@Rua I am using the git version, and I just ran "cargo update" (which I think will reload from git). The above code still produces the error.

@TomGillen
Copy link
Collaborator

I have just published the latest fixes as v.0.2.3. I can reproduce this issue on the latest version though, so I'll take a look.

@Rua
Copy link
Contributor

Rua commented Jun 18, 2020

I just noticed #150 appears to be the same issue.

@travis-leith
Copy link
Author

travis-leith commented Jun 18, 2020

@Rua @TomGillen

Further to #150, changing the second system to

let health_conscious = SystemBuilder::new("healthy")
        .with_query(<(Read<Money>, Read<Health>)>::query())
        .read_component::<Money>()
        .read_component::<Health>()
        .build(|_, world, _, query| {
            for (money, health) in query.iter(world) {
                info!("So healthy {:?}", health);
            }
        });

makes the problem go away

@TomGillen
Copy link
Collaborator

Yea, the issue is caused by the query in the 2nd system somehow reporting that it does not access any archetypes. I am trying to track down how that can possibly happen, given that the query by itself correctly iterates through the entities (and so must be finding the archetype it needs).

@TomGillen
Copy link
Collaborator

I am also surprised that none of our unit tests caught this.

@TomGillen
Copy link
Collaborator

Well... I found the problem.

The FilterArchIter returned from EntityFilter::iter_archetype_indexes is totally broken. It stops iterating through archetypes after it finds the first which fails the filter... because there is an if where there should be a while.

This would have totally broken the scheduler in some situations, where it would have run multiple systems together which should not have run together, but I guess nobody noticed because the potential data race could be quite subtle. The new subworld code was catching this because it now validates archetype accesses from systems.

@Rua
Copy link
Contributor

Rua commented Jun 18, 2020

Ouch! A good thing you spotted it.

@TomGillen
Copy link
Collaborator

@ChechyLevas Can you test the latest master commit to see if this is still an issue for you?

@Rua
Copy link
Contributor

Rua commented Jun 19, 2020

I'm running into this error too now, with the latest master. My code:

	SystemBuilder::new("texture_animation_system")
		.read_resource::<AssetStorage>()
		.read_resource::<Duration>()
		.with_query(<Write<MapDynamic>>::query())
		.build_thread_local(move |_, world, (asset_storage, delta), query| {
			for mut map_dynamic in query.iter_mut(world) {

It panics on the last line.

@Rua
Copy link
Contributor

Rua commented Jun 19, 2020

The latest commit fixed the issue for me. Thanks!

@chemicstry
Copy link
Member

I don't think this is completely fixed yet. https://github.com/chemicstry/legion_transform/runs/849506909 still fails with latest master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants