rj00a / evenio

An event-driven Entity Component System
MIT License
133 stars 14 forks source link

A bug in `iter_unchecked` #27

Closed jidoc01 closed 6 months ago

jidoc01 commented 6 months ago

Problem

In iter_unchecked, it should be assured that state must have a dangling pointer when states is empty but it can be violated if the states were once non-empty and got empty. And if it happens, then next in Iter cannot check whether it has reached its end.

Reproducible code


#[derive(Event)]
struct Tick;

#[derive(Component)]
struct Name(String);

fn empty_iter_test() {
    let mut world = World::new();
    world.add_handler(|_: Receiver<Tick>, mut fetcher: Fetcher<(EntityId, &mut Name)>| {
        fetcher.iter_mut().for_each(|(e, name)| {
            println!("{}", name.0);
        });
    });
    let e = world.spawn();
    world.insert(e, Name("hello".into()));
    world.send(Tick);
    world.despawn(e);
    world.send(Tick);
}

Solution

We may check the emptiness of states manually and assign dangling pointers if necessary: https://github.com/jidoc01/evenio/commit/0666ff705bcb7630e67848901ee47a56eb22ed1e

By the way, thank you for your amazing work :D

rj00a commented 6 months ago

Thanks for the report! I've included a fix for this in v0.4.0.