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

Idiomatic way of removing specific entities #276

Closed
nyvs opened this issue Sep 5, 2021 · 3 comments
Closed

Idiomatic way of removing specific entities #276

nyvs opened this issue Sep 5, 2021 · 3 comments

Comments

@nyvs
Copy link

nyvs commented Sep 5, 2021

Let's say someone wants to delete missiles which have been exploded.
Intuitively, I'd want to delete it directly in the system which goes over all the missiles, but this won't work because of the borrow checker.
The next step for me would be to try to note their 'Entity' which acts as an ID, so I can call world.remove. Which also doesn't work, I cannot "get" the entity in the system.
So that leaves one option open; for every frame, Iterating over every entity and checking if some entity has a special component which hints for this entity to be deleted, then pushing it to a vec, and then going over the vec and calling world.remove?

Is that correct? Is there a better way? Thank you :)

@nyvs
Copy link
Author

nyvs commented Sep 5, 2021

My current way of removing missiles looks like this:

fn remove_dead_missiles(world: &mut World) {
	let mut entity_list = vec![];
	let mut query = <Entity>::query();
	for entity in query.iter(world) {
		entity_list.push(*entity);
	}
	let mut to_delete = vec![];
	for e in entity_list {
		let ent = world.entry(e).unwrap();
		match ent.get_component::<Missile>() {
			Ok(m) => if m.is_set_off {
				to_delete.push(e);
			},
			Err(_) => (),
		}
	}
	for del in to_delete.iter() {
		world.remove(*del);
	}
}

@zedrian
Copy link

zedrian commented Sep 7, 2021

Hi @nyvs, not sure about the idiomatic way, but I can share with you my approach for solving such tasks.

All my logic is packed into systems generated via #[legion::system] macro (and executed in Schedule), so when I need to add/remove entities or components I simply request my system to access CommandBuffer and record corresponding commands into it.

In your case, such a system can look like this:

use legion::{Query, systems::CommandBuffer, world::SubWorld};

#[legion::system]
fn remove_exploded_missiles(objects: &mut Query<(Entity, &Missile)>,
                            commands: &mut CommandBuffer,
                            world: &mut SubWorld)
{
    for (entity, missile) in objects.iter(world) {
        if missile.is_set_off {
            commands.remove(entity);
        }
    }                    
}

Please let us know if this does not work for you.

@nyvs
Copy link
Author

nyvs commented Sep 8, 2021

Hi! Thank you so much. I now successfully moved from plain queries to all-systems, which works beautifully, and even better: everything works as expected. I must say I love legion.

@nyvs nyvs closed this as completed Sep 8, 2021
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

2 participants