Improve codegen for world validation (#9464)
# Objective Improve code-gen for `QueryState::validate_world` and `SystemState::validate_world`. ## Solution * Move panics into separate, non-inlined functions, to reduce the code size of the outer methods. * Mark the panicking functions with `#[cold]` to help the compiler optimize for the happy path. * Mark the functions with `#[track_caller]` to make debugging easier. --------- Co-authored-by: James Liu <contact@jamessliu.com>
This commit is contained in:
parent
bdb063497d
commit
e60249e59d
@ -224,12 +224,18 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
|
||||
/// Many unsafe query methods require the world to match for soundness. This function is the easiest
|
||||
/// way of ensuring that it matches.
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub fn validate_world(&self, world_id: WorldId) {
|
||||
assert!(
|
||||
world_id == self.world_id,
|
||||
"Attempted to use {} with a mismatched World. QueryStates can only be used with the World they were created from.",
|
||||
std::any::type_name::<Self>(),
|
||||
);
|
||||
#[inline(never)]
|
||||
#[track_caller]
|
||||
#[cold]
|
||||
fn panic_mismatched(this: WorldId, other: WorldId) -> ! {
|
||||
panic!("Encountered a mismatched World. This QueryState was created from {this:?}, but a method was called using {other:?}.");
|
||||
}
|
||||
|
||||
if self.world_id != world_id {
|
||||
panic_mismatched(self.world_id, world_id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the current [`QueryState`] with information from the provided [`Archetype`]
|
||||
|
||||
@ -232,8 +232,18 @@ impl<Param: SystemParam> SystemState<Param> {
|
||||
|
||||
/// Asserts that the [`SystemState`] matches the provided world.
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
fn validate_world(&self, world_id: WorldId) {
|
||||
assert!(self.matches_world(world_id), "Encountered a mismatched World. A SystemState cannot be used with Worlds other than the one it was created with.");
|
||||
#[inline(never)]
|
||||
#[track_caller]
|
||||
#[cold]
|
||||
fn panic_mismatched(this: WorldId, other: WorldId) -> ! {
|
||||
panic!("Encountered a mismatched World. This SystemState was created from {this:?}, but a method was called using {other:?}.");
|
||||
}
|
||||
|
||||
if !self.matches_world(world_id) {
|
||||
panic_mismatched(self.world_id, world_id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the state's internal view of the [`World`]'s archetypes. If this is not called before fetching the parameters,
|
||||
|
||||
@ -1775,7 +1775,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Attempted to use bevy_ecs::query::state::QueryState<()> with a mismatched World."]
|
||||
#[should_panic = "Encountered a mismatched World."]
|
||||
fn query_validates_world_id() {
|
||||
let mut world1 = World::new();
|
||||
let world2 = World::new();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user