Skip to content

Query::get and Query::get_component return different references #6623

Closed
@greytdepression

Description

@greytdepression

Bevy version

0.9
308e092

What you did

I ran the following snippet of code

use bevy::prelude::*;

fn main() {
    App::new()

        // We need a game loop for the problem to occur.
        .add_plugins(DefaultPlugins)

        // spawn some entities
        .insert_resource(MyEntities::default())
        .add_startup_system(spawn_entities)
        .add_system(query_system)
        .run();
}

#[derive(Default, Resource)]
struct MyEntities(Vec<Entity>);

#[derive(Debug, Component, PartialEq, Eq)]
struct IndexComponent(i32); // we use this component to check that we have the correct component

#[derive(Component)]
#[component(storage = "SparseSet")]
struct MySparseComponent;


fn spawn_entities(mut commands: Commands, mut my_entities: ResMut<MyEntities>) {
    (0..10)
        .for_each(|i|
            // spawn an entity, give it an `IndexComponent` with its number, and push it into `MyEntities`
            my_entities.0.push(commands.spawn(IndexComponent(i)).id())
        );
}


fn query_system(
    mut commands: Commands,
    my_entities: Res<MyEntities>,
    query: Query<&IndexComponent>,
    mut frame_counter: Local<usize>,
) {

    let mut last: Option<Entity> = None;

    for &entity in my_entities.0.iter() {
        let get = query.get(entity).unwrap();
        let get_comp = query.get_component::<IndexComponent>(entity).unwrap();

        // give the entity the sparse component
        commands.entity(entity)
            .insert(MySparseComponent);

        // remove the sparse component from the last entity
        if let Some(last) = last {
            commands.entity(last)
                .remove::<MySparseComponent>();
        }

        // this is where things go wrong
        if get != get_comp {
            dbg!(entity, get, get_comp);
            dbg!(*frame_counter);
            panic!("AAAA");
        }

        last = Some(entity);
    }

    // count what frame we are on
    *frame_counter += 1;
}

What went wrong

Here, get and get_comp should have the same value, which they do on the first frame, but not on the second.

Additional information

In this example MyEntities and IndexcComponent are just some scaffolding in order to demonstrate the problem. What is important is MySparseComponent and the fact that it is of storage type SparseSet.

I made a git repo containing this snippet for convenience.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-BugAn unexpected or incorrect behaviorP-HighThis is particularly urgent, and deserves immediate attentionP-UnsoundA bug that results in undefined compiler behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions