From ac764bccee54023e1d015a580898f51c32a1fb59 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Tue, 9 Nov 2021 18:43:18 +1100 Subject: [PATCH 1/9] Create Query::contains --- crates/bevy_ecs/src/system/query.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 6aaf39bfbaa23..47a36bbf6ad86 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -187,7 +187,7 @@ use thiserror::Error; /// # tuple_system.system(); /// /// # fn non_tuple_system( -/// // This is the preferred method. +/// // This is the preferred method. /// query: Query<&MyComponent> /// # ) {} /// # non_tuple_system.system(); @@ -975,6 +975,20 @@ where self.state .is_empty(self.world, self.last_change_tick, self.change_tick) } + + /// Returns wether the given [`Entity`] matches the query. + #[inline] + pub fn contains(&self, entity: Entity) -> bool { + unsafe { + self.state.get_unchecked_manual( + self.world, + entity, + self.last_change_tick, + self.change_tick, + ) + } + .is_ok() + } } /// An error that occurs when retrieving a specific [`Entity`]'s component from a [`Query`] From 63feae881c3b5de1057cfb8f656ecf2531481920 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Tue, 9 Nov 2021 19:34:53 +1100 Subject: [PATCH 2/9] Add proper docs to Query::contains --- crates/bevy_ecs/src/system/query.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 47a36bbf6ad86..0b180f662861e 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -976,7 +976,31 @@ where .is_empty(self.world, self.last_change_tick, self.change_tick) } - /// Returns wether the given [`Entity`] matches the query. + /// Returns `true` if the given [`Entity`] matches the query. + /// + /// # Example + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// # + /// # #[derive(Component)] + /// # struct Player; + /// # #[derive(Component)] + /// # struct Alive; + /// fn check_if_alive( + /// player_query: Query>, + /// alive_query: Query<(), With>, + /// ) { + /// if let Ok(player) = player_query.get_single() { + /// if alive_query.contains(player) { + /// println!("The player is alive."); + /// } else { + /// println!("The player is dead!"); + /// } + /// } + /// } + /// # check_if_alive.system(); + /// ``` #[inline] pub fn contains(&self, entity: Entity) -> bool { unsafe { From 71796e945989c70ed997c6f20e6ac1cefeb77e28 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Tue, 9 Nov 2021 19:34:53 +1100 Subject: [PATCH 3/9] Add proper docs to Query::contains --- crates/bevy_ecs/src/system/query.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 47a36bbf6ad86..0b180f662861e 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -976,7 +976,31 @@ where .is_empty(self.world, self.last_change_tick, self.change_tick) } - /// Returns wether the given [`Entity`] matches the query. + /// Returns `true` if the given [`Entity`] matches the query. + /// + /// # Example + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// # + /// # #[derive(Component)] + /// # struct Player; + /// # #[derive(Component)] + /// # struct Alive; + /// fn check_if_alive( + /// player_query: Query>, + /// alive_query: Query<(), With>, + /// ) { + /// if let Ok(player) = player_query.get_single() { + /// if alive_query.contains(player) { + /// println!("The player is alive."); + /// } else { + /// println!("The player is dead!"); + /// } + /// } + /// } + /// # check_if_alive.system(); + /// ``` #[inline] pub fn contains(&self, entity: Entity) -> bool { unsafe { From 9ba8cf090bc922d7486664bb41c1adac9c09b6f9 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Wed, 10 Nov 2021 16:14:07 +1100 Subject: [PATCH 4/9] Change Query::contains to use query::get (why didn't I think of that) --- crates/bevy_ecs/src/system/query.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 3a452990c9e14..1258ddf10c914 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -1002,16 +1002,11 @@ where /// # check_if_alive.system(); /// ``` #[inline] - pub fn contains(&self, entity: Entity) -> bool { - unsafe { - self.state.get_unchecked_manual( - self.world, - entity, - self.last_change_tick, - self.change_tick, - ) - } - .is_ok() + pub fn contains(&self, entity: Entity) -> bool + where + Q::Fetch: ReadOnlyFetch, + { + self.get(entity).is_ok() } } From ddd545b3f70d908a300d270b61497e6ed211982b Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Wed, 10 Nov 2021 16:17:35 +1100 Subject: [PATCH 5/9] Use a better example --- crates/bevy_ecs/src/system/query.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 1258ddf10c914..7bd29aea7a1f8 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -187,7 +187,7 @@ use thiserror::Error; /// # tuple_system.system(); /// /// # fn non_tuple_system( -/// // This is the preferred method. +/// // This is the preferred method. /// query: Query<&MyComponent> /// # ) {} /// # non_tuple_system.system(); @@ -984,22 +984,18 @@ where /// # use bevy_ecs::prelude::*; /// # /// # #[derive(Component)] - /// # struct Player; - /// # #[derive(Component)] - /// # struct Alive; - /// fn check_if_alive( - /// player_query: Query>, - /// alive_query: Query<(), With>, - /// ) { - /// if let Ok(player) = player_query.get_single() { - /// if alive_query.contains(player) { - /// println!("The player is alive."); - /// } else { - /// println!("The player is dead!"); - /// } + /// # struct InRange; + /// # + /// # struct Target { + /// # entity: Entity, + /// # } + /// # + /// fn targeting_system(in_range_query: Query<&InRange>, target: Res) { + /// if in_range_query.contains(target.entity) { + /// println!("Bam!") /// } /// } - /// # check_if_alive.system(); + /// # targeting_system.system() /// ``` #[inline] pub fn contains(&self, entity: Entity) -> bool From 17e9fe4a8d2f73622a0cb65b91cba17a2ce84b45 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Wed, 10 Nov 2021 17:29:14 +1100 Subject: [PATCH 6/9] my ide keeps changing this line --- crates/bevy_ecs/src/system/query.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 7bd29aea7a1f8..30b4216f5f532 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -187,7 +187,7 @@ use thiserror::Error; /// # tuple_system.system(); /// /// # fn non_tuple_system( -/// // This is the preferred method. +/// // This is the preferred method. /// query: Query<&MyComponent> /// # ) {} /// # non_tuple_system.system(); From 94da17c3a20b5aed6915e763882b4e234de7c6da Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Wed, 10 Nov 2021 18:42:47 +1100 Subject: [PATCH 7/9] Missed a semicolon --- crates/bevy_ecs/src/system/query.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 30b4216f5f532..e0f104ad67006 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -995,7 +995,7 @@ where /// println!("Bam!") /// } /// } - /// # targeting_system.system() + /// # targeting_system.system(); /// ``` #[inline] pub fn contains(&self, entity: Entity) -> bool From 62d066a27abd571f8bae9dc2c16dd7cf77a9c7d0 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Fri, 4 Feb 2022 16:12:41 +1100 Subject: [PATCH 8/9] Use NopFetch instead --- crates/bevy_ecs/src/system/query.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 7410bd4aa69a0..d9918454c95a3 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -2,8 +2,8 @@ use crate::{ component::Component, entity::Entity, query::{ - Fetch, FilterFetch, QueryCombinationIter, QueryEntityError, QueryIter, QueryState, - WorldQuery, + Fetch, FilterFetch, NopFetch, QueryCombinationIter, QueryEntityError, QueryIter, + QueryState, WorldQuery, }, world::{Mut, World}, }; @@ -984,11 +984,17 @@ where /// # targeting_system.system(); /// ``` #[inline] - pub fn contains(&self, entity: Entity) -> bool - where - Q::Fetch: ReadOnlyFetch, - { - self.get(entity).is_ok() + pub fn contains(&self, entity: Entity) -> bool { + unsafe { + self.state + .get_unchecked_manual::>( + self.world, + entity, + self.last_change_tick, + self.change_tick, + ) + .is_ok() + } } } From 30a04c5774b189dd21d07ea4701bd4076be48f52 Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Fri, 4 Feb 2022 20:27:24 +1100 Subject: [PATCH 9/9] Add safety comment --- crates/bevy_ecs/src/system/query.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index d9918454c95a3..6a384cbd077e9 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -985,6 +985,7 @@ where /// ``` #[inline] pub fn contains(&self, entity: Entity) -> bool { + // SAFE: NopFetch does not access any members while &self ensures no one has exclusive access unsafe { self.state .get_unchecked_manual::>(