Skip to content

[Merged by Bors] - Fix Events::<drain/clear> bug#2206

Closed
NathanSWard wants to merge 2 commits into
bevyengine:mainfrom
NathanSWard:nward/events-drain-bug-fix
Closed

[Merged by Bors] - Fix Events::<drain/clear> bug#2206
NathanSWard wants to merge 2 commits into
bevyengine:mainfrom
NathanSWard:nward/events-drain-bug-fix

Conversation

@NathanSWard

@NathanSWard NathanSWard commented May 18, 2021

Copy link
Copy Markdown
Contributor

Taken from #2145

On draining and clearing, dangling EventReaders would not read into the correct event offset.

@NathanSWard NathanSWard added C-Bug An unexpected or incorrect behavior A-ECS Entities, components, systems, and events labels May 18, 2021
@NathanSWard NathanSWard force-pushed the nward/events-drain-bug-fix branch from cb71e4d to 598196b Compare May 18, 2021 03:01
@alice-i-cecile

Copy link
Copy Markdown
Member

Thanks! This is a nice thing to pull over.

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label May 18, 2021
@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

Good call. Looks like events.clear() also needs to reset its counters. I'll put together a follow up.

@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

bors r+

bors Bot pushed a commit that referenced this pull request May 18, 2021
Taken from #2145

On draining, `Events` did not reset it's internal event count members.
@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

bors r-

@bors

bors Bot commented May 18, 2021

Copy link
Copy Markdown

Canceled.

@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

Hmm one issue to discuss that I discovered when putting together my followup:

Resetting event_count means that existing event readers will skip over newly sent events? The test looks like it should fail, so I need to understand why it works before merging :)

@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

image

@NathanSWard

NathanSWard commented May 18, 2021

Copy link
Copy Markdown
Contributor Author

Good call. Looks like events.clear() also needs to reset its counters. I'll put together a follow up.

@cart I'll add this fix to the PR as well.

Resetting event_count means that existing event readers will skip over newly sent events? The test looks like it should fail, so I need to understand why it works before merging :)

Hmm yes this does seem to be incorrect...
Looks like we might need to add a dirty_flag or something of the sort.

@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

This makes the test above pass, but it feels like I'm missing a corner case:
image

@NathanSWard

NathanSWard commented May 18, 2021

Copy link
Copy Markdown
Contributor Author

Yep adding this:

        events.send(E(1));
        let _ = events.drain();
        assert_eq!(reader.iter(&events).next(), None);

in the tests causes it to fail.

@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

Yep adding this:

Is that with or without the "fix" above? Adding that passes with the fix for me.

@NathanSWard

Copy link
Copy Markdown
Contributor Author

@cart, a possible solution:
we might need to add a version field to Events and Event<Reader/Writer> and on calling clear/drain, update the version. So when the Reader/Writer calls .iter() check the versions and reset the Reader/Writer's internal count to 0 if the version has changed.

@NathanSWard

Copy link
Copy Markdown
Contributor Author

Is that with or without the "fix" above? Adding that passes with the fix for me.

With your change included.
here is the full test i have:

#[test]
    fn test_events_drain() {
        #[derive(PartialEq, Eq, Debug)]
        struct E(usize);

        let mut events = Events::<E>::default();
        let mut reader = events.get_reader();

        assert!(reader.iter(&events).next().is_none());

        events.send(E(0));
        assert_eq!(reader.iter(&events).next(), Some(&E(0)));
        assert_eq!(reader.iter(&events).next(), None);

        events.send(E(1));
        let _ = events.drain();
        assert_eq!(reader.iter(&events).next(), None);

        events.send(E(2));
        events.send(E(3));
        assert_eq!(reader.iter(&events).next(), Some(&E(2)));
        assert_eq!(reader.iter(&events).next(), Some(&E(3)));
        assert_eq!(reader.iter(&events).next(), None);
    }

@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

Found another corner case. Adding an events.update() breaks it.

#[test]
fn test_events_drain() {
    #[derive(PartialEq, Eq, Debug)]
    struct E(usize);
    let mut events = Events::<E>::default();
    let mut reader = events.get_reader();

    assert!(reader.iter(&events).next().is_none());

    events.send(E(0));
    assert_eq!(*reader.iter(&events).next().unwrap(), E(0));
    assert_eq!(reader.iter(&events).next(), None);

    let _ = events.drain();
    assert!(reader.iter(&events).next().is_none());

    events.send(E(1));
    events.update();
    events.send(E(2));
    assert_eq!(*reader.iter(&events).next().unwrap(), E(1));
    assert_eq!(*reader.iter(&events).next().unwrap(), E(2));
}

@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

I'm gonna keep working through my PR review queue. If you find a fix definitely do it for clear() too 😄

I'll check back in later / help out if it hasn't been sorted out yet.

@NathanSWard

NathanSWard commented May 18, 2021

Copy link
Copy Markdown
Contributor Author

@cart it turns out our last #[test]s are actually invalid... haha 😅

reader.iter(&events) returns an iterator over all events.
We were calling it multiple times expecting it to return a single value.

This is how the test should be structured...

#[test]
    fn test_events_drain() {
        // test stuff

        events.send(E(1));
        events.update();
        events.send(E(2));

        let mut iter = reader.iter(&events);
        assert_eq!(*iter.next().unwrap(), E(1));
        assert_eq!(*iter.next().unwrap(), E(2));
    }

@cart

cart commented May 18, 2021

Copy link
Copy Markdown
Member

Bahaha whoops. Nice catch!

@NathanSWard NathanSWard force-pushed the nward/events-drain-bug-fix branch from 598196b to c623cc4 Compare May 18, 2021 23:15
@NathanSWard NathanSWard changed the title Fix Events::drain bug Fix Events::<drain/clear> bug May 18, 2021
Co-authored-by: Alice Cecile <alice-i-cecile@users.noreply.github.com>
@NathanSWard NathanSWard force-pushed the nward/events-drain-bug-fix branch from c623cc4 to 8b1abbb Compare May 18, 2021 23:18

@alice-i-cecile alice-i-cecile left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good; factoring out that logic reduces the risk of bugs in the future.

@NathanSWard

Copy link
Copy Markdown
Contributor Author

@cart I have this current implementation which passed the failing test we set up.
I'm currently toying around with other potential failing tests, and please let me know if you can think of any :)

Comment thread crates/bevy_ecs/src/event.rs Outdated
@cart

cart commented May 19, 2021

Copy link
Copy Markdown
Member

bors r+

bors Bot pushed a commit that referenced this pull request May 19, 2021
Taken from #2145

On draining and clearing, dangling `EventReaders` would not read into the correct event offset.
@bors

bors Bot commented May 19, 2021

Copy link
Copy Markdown

@bors bors Bot changed the title Fix Events::<drain/clear> bug [Merged by Bors] - Fix Events::<drain/clear> bug May 19, 2021
@bors bors Bot closed this May 19, 2021
ostwilkens pushed a commit to ostwilkens/bevy that referenced this pull request Jul 27, 2021
Taken from bevyengine#2145

On draining and clearing, dangling `EventReaders` would not read into the correct event offset.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ECS Entities, components, systems, and events C-Bug An unexpected or incorrect behavior S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants