amethyst / specs

Specs - Parallel ECS
https://amethyst.github.io/specs/
Apache License 2.0
2.49k stars 219 forks source link

How do I create a system that also has the capacity to remove entities? #744

Closed codedcosmos closed 2 years ago

codedcosmos commented 2 years ago

Description

Say I have a "decayable" component. Just a component that has some life but loses it over time:

pub struct Decayable {
    life: f32,
}

impl Decayable {
    pub fn new(life: f32) -> Self {
        Self {
            life
        }
    }
    ...
}

and every tick it loses some life..


impl Decayable {
    ...
    pub fn update(&mut self) {
        self.life -= 0.01;
    }
    ...
}

and when that reaches zero I want to remove the entity from the world:

impl Decayable {
    ...
    pub fn should_remove(&self) -> bool {
        self.life <= 0.0
    }
}

How do I remove entities based on this condition in legion?

Current Implementation

I have tried making a decay system

struct DecaySys;

impl<'a> System<'a> for DecaySys {
    type SystemData = (Entities<'a>, WriteStorage<'a, Decayable>);

    fn run(&mut self, (entities, mut life): Self::SystemData) {
        for (life) in (&mut life).join() {
            life.update();

            if life.should_remove() {
                // How to remove this entity
            }
        }
    }
}

Additional notes

I'm sure I will have to run world.maintain(); at some point as well but that's okay.

I couldn't figure out how to do this based on the documentation anywhere. Labeling this as feature-request in case it isn't because it could be added to the documentation. Perhaps this method of removing entities is bad practice. But it might be good to have some example to remove entities. (Assuming one isn't already there).

Thanks

codedcosmos commented 2 years ago

You can do this:

struct DecaySys;

impl<'a> System<'a> for DecaySys {
    type SystemData = (Entities<'a>, WriteStorage<'a, Decayable>);

    fn run(&mut self, (entities, mut life): Self::SystemData) {
        for (e, life) in (&entities, &mut life).join() {
            log!("life: {}", life.val());
            life.update();

            if life.should_remove() {
                entities.delete(e);
            }
        }
    }
}