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

Investigate: Reinitialize EventChannel<_> for states with custom dispatchers #119

Closed
3 tasks done
azriel91 opened this issue Mar 12, 2020 · 1 comment
Closed
3 tasks done
Labels
F: core Core application functionality - managing resources, state, etcetera.
Milestone

Comments

@azriel91
Copy link
Owner

In GitLab by @azriel91 on May 2, 2019, 23:03

For states with custom dispatchers (including every state that impl AppState), Systems which register ReaderIds against EventChannel<_>s will be dropped when the State ends. This means those event channels will persist in the World, and cause a memory leak -- the reader never reads, so the event channel holds onto the events that have not been read by every reader.

Attempting to re-initialize a channel in State#on_stop causes an index out of bounds error:

thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', /rustc/e305df1846a6d985315917ae0c81b74af8b4e641\src\libcore\slice\mod.rs:2693:14
fn on_stop(&mut self, data: StateData<'_, GameData<'a, 'b>>) {
    // Replace the event channel, so that reader IDs from previous instantiations of this
    // `State` will not cause the buffer to grow indefinitely.
    let mut character_selection_ec = data
        .world
        .write_resource::<EventChannel<CharacterSelectionEvent>>();
    *character_selection_ec = EventChannel::<CharacterSelectionEvent>::new();
}

This is further complicated by event channels that are long lived, such as EventChannel<ControlInputEvent>.


Options:

  • Try to implement remove(ReaderId) for EventChannel in shrev.

    This is part of shrev 1.0.

  • Figure out what's still running the Systems that try to read the event channel.

    InputToControlInputSystem was doing a delta from the existing ControllerInput value against the InputEvent value, and sending a ControlInputEvent if it didn't match. This meant it would always send an event for new entities with a ControllerInput component.

    !123 changes the behaviour to send ControlInputEvents when InputEvents are sent.

  • Try to drop / initialize the EventChannel somewhere else (note, AppState sets up the dispatcher before calling on_start on the delegate).

    Bad solution -- it's hard to discover who is replacing the EventChannel.

  • Register all systems in the main dispatcher, use state specific status types to decide whether to:

    • Drop events.
    • Proceed with regular system logic.
  • Try to drop the ReaderId in State#on_stop

    Needs more thought. See Improve ReaderId rustgd/shrev-rs#28 (comment)

@azriel91 azriel91 added the F: core Core application functionality - managing resources, state, etcetera. label Mar 12, 2020
@azriel91 azriel91 added this to the Backlog milestone Mar 12, 2020
@azriel91
Copy link
Owner Author

In GitLab by @azriel91 on Jul 19, 2019, 21:13

This shouldn't be an issue -- dropped ReaderIds unregister themselves on drop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F: core Core application functionality - managing resources, state, etcetera.
Projects
None yet
Development

No branches or pull requests

1 participant