Make `!Send` data initalization use closures
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
This is a tracking issue for making `!Send` data use closures for initialization.
# Goal
We currently allow users to directly insert instances of non-send types into a bevy `App` before startup. This pins that app, and the entire ECS update loop, onto the thread on which those types are constructed (usually the main process thread), and forces us to mount the ECS update loop within the windowing update loop.
This "run-loop turducken" is cursed and bad, and no one I have ever talked to thinks this is a good idea. The first step to removing it is fixing the initialization step. Soooooo...
# Proposal
1. [ ] Allow users to provide `Send` closures that insert objects into the "Main-Thread Storage" during setup.
```rust
fn setup_non_send<'app, F, R>(&'app mut self, func: F) -> &mut App
where
F: FnOnce(world: &mut World) -> R + Send + 'app
R: 'static
```
Closures provided to this function will be retained in the app, and then called only once the runner has started up it's ecs event-loop (on a thread of it's choosing).
2. [ ] Deprecate all existing ways to directly insert `!Send` data.
We do not have to deprecate `init_non_send` (or `init_main_thread_storage` or whatever it's called at this point). We do have to deprecate `insert_non_send`; users should try to migrate to `setup_non_send` instead.
3. [ ] After a full release, remove the deprecated methods.
4. [ ] As follow up, move the ECS out of the main windowing thread, _then_ initialize the non-send data on that new thread.
# Tracking
This has the potential to break users, so we are going to "scream-test" it. This issue should be the main place to discuss the change, and any issues caused by it.
Contributor guide
Assessment
This issue has not been assessed yet.