-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
[Merged by Bors] - Add error messages for the spooky insertions #2581
Conversation
if let Some(mut entity) = world.get_entity_mut(self.entity) { | ||
entity.insert_bundle(self.bundle); | ||
} else { | ||
panic!("Could not insert a bundle for entity {:?} because it no longer exists.\n\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"no longer" implies that it did exist at some point, which isn't necessarily true (although this should generally be true)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps? I think that making error messages 'worse' because someone has manually created an entity id is not the tradeoff I'd prefer to make.
We can change this to "doesn't exist" though if you're adamant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For docs and error messages I'd prefer to not say things that are "approximately true". Omitting information in the interest of clarity is ok, but I'd prefer to keep this crisp, especially given that the new renderer "spawns at specific entities" / "shares entities across worlds".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Acted on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be added for |
@@ -162,6 +162,7 @@ pub struct Entities { | |||
/// Once `flush()` is done, `free_cursor` will equal `pending.len()`. | |||
pending: Vec<u32>, | |||
free_cursor: AtomicI64, | |||
/// Stores the number of free entities for [`len`](Entities::len) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't that Entities::len
link just be a link to itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so? There's a function also called len, which this should point to
I can check though at some point. It's only an internal documentation anyway, since it's on a private field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I didn't see the method with the same name in this diff 👍
Anyway I can't get rust-analyser to correctly link to something from Entities
, not sure why...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rust-analyser
's intra doc links syntax is a subset of valid links, from what I've found.
The way to try this is with cargo doc -- --document-private-items
(or whatever the precise correct syntax is)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have confirmed that it links correctly
There are several other bugs which running cargo doc --open --document-private-items
makes appear, but that's not the job of this PR.
Previously, it paniced when the value was out of the range, it now returns an Option. It was also erroniously marked as `unsafe`, even though it is a safe method I've renamed it - hopefully this rename makes sense I've also reworked `contains` to use this method, which allows it to be more precise about out-of-range entities.
bbe568e
to
8624bbe
Compare
bors r+ |
# Objective Sometimes, the unwraps in `entity_mut` could fail here, if the entity was despawned *before* this command was applied. The simplest case involves two command buffers: ```rust use bevy::prelude::*; fn b(mut commands1: Commands, mut commands2: Commands) { let id = commands2.spawn().insert_bundle(()).id(); commands1.entity(id).despawn(); } fn main() { App::build().add_system(b.system()).run(); } ``` However, a more complicated version arises in the case of ambiguity: ```rust use std::time::Duration; use bevy::{app::ScheduleRunnerPlugin, prelude::*}; use rand::Rng; fn cleanup(mut e: ResMut<Option<Entity>>) { *e = None; } fn sleep_randomly() { let mut rng = rand::thread_rng(); std::thread::sleep(Duration::from_millis(rng.gen_range(0..50))); } fn spawn(mut commands: Commands, mut e: ResMut<Option<Entity>>) { *e = Some(commands.spawn().insert_bundle(()).id()); } fn despawn(mut commands: Commands, e: Res<Option<Entity>>) { let mut rng = rand::thread_rng(); std::thread::sleep(Duration::from_millis(rng.gen_range(0..50))); if let Some(e) = *e { commands.entity(e).despawn(); } } fn main() { App::build() .add_system(cleanup.system().label("cleanup")) .add_system(sleep_randomly.system().label("before_despawn")) .add_system(despawn.system().after("cleanup").after("before_despawn")) .add_system(sleep_randomly.system().label("before_spawn")) .add_system(spawn.system().after("cleanup").after("before_spawn")) .insert_resource(None::<Entity>) .add_plugin(ScheduleRunnerPlugin::default()) .run(); } ``` In the cases where this example crashes, it's because `despawn` was ordered before `spawn` in the topological ordering of systems (which determines when buffers are applied). However, `despawn` actually ran *after* `spawn`, because these systems are ambiguous, so the jiggles in the sleeping time triggered a case where this works. ## Solution - Give a better error message
Objective
Sometimes, the unwraps in
entity_mut
could fail here, if the entity was despawned before this command was applied.The simplest case involves two command buffers:
However, a more complicated version arises in the case of ambiguity:
In the cases where this example crashes, it's because
despawn
was ordered beforespawn
in the topological ordering of systems (which determines when buffers are applied). However,despawn
actually ran afterspawn
, because these systems are ambiguous, so the jiggles in the sleeping time triggered a case where this works.Solution