- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 4.2k
Implement WorldQuery for EntityRef #6960
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
Changes from all commits
e9fc9d0
              13387e3
              c74843c
              d00da4e
              9cd5baa
              ddd845f
              a94a348
              fc4a1c6
              185310b
              aea7f0b
              a0cbc4b
              39cf337
              0c91c16
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -5,7 +5,7 @@ use crate::{ | |
| entity::Entity, | ||
| query::{Access, DebugCheckedUnwrap, FilteredAccess}, | ||
| storage::{ComponentSparseSet, Table, TableRow}, | ||
| world::{unsafe_world_cell::UnsafeWorldCell, Mut, Ref, World}, | ||
| world::{unsafe_world_cell::UnsafeWorldCell, EntityRef, Mut, Ref, World}, | ||
| }; | ||
| pub use bevy_ecs_macros::WorldQuery; | ||
| use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref}; | ||
|  | @@ -536,6 +536,89 @@ unsafe impl WorldQuery for Entity { | |
| /// SAFETY: access is read only | ||
| unsafe impl ReadOnlyWorldQuery for Entity {} | ||
|  | ||
| /// SAFETY: `Self` is the same as `Self::ReadOnly` | ||
| unsafe impl<'a> WorldQuery for EntityRef<'a> { | ||
| type Fetch<'w> = &'w World; | ||
| type Item<'w> = EntityRef<'w>; | ||
| type ReadOnly = Self; | ||
| type State = (); | ||
|  | ||
| fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> { | ||
| item | ||
| } | ||
|  | ||
| const IS_DENSE: bool = true; | ||
|  | ||
| const IS_ARCHETYPAL: bool = true; | ||
|  | ||
| unsafe fn init_fetch<'w>( | ||
| world: UnsafeWorldCell<'w>, | ||
| _state: &Self::State, | ||
| _last_run: Tick, | ||
| _this_run: Tick, | ||
| ) -> Self::Fetch<'w> { | ||
| // SAFE: EntityRef has permission to access the whole world immutably thanks to update_component_access and update_archetype_component_access | ||
| world.world() | ||
| } | ||
|  | ||
| unsafe fn clone_fetch<'w>(world: &Self::Fetch<'w>) -> Self::Fetch<'w> { | ||
| world | ||
| } | ||
|  | ||
| #[inline] | ||
| unsafe fn set_archetype<'w>( | ||
| _fetch: &mut Self::Fetch<'w>, | ||
| _state: &Self::State, | ||
| _archetype: &'w Archetype, | ||
| _table: &Table, | ||
| ) { | ||
| } | ||
|  | ||
| #[inline] | ||
| unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) { | ||
| } | ||
|  | ||
| #[inline(always)] | ||
| unsafe fn fetch<'w>( | ||
| world: &mut Self::Fetch<'w>, | ||
| entity: Entity, | ||
| _table_row: TableRow, | ||
| ) -> Self::Item<'w> { | ||
| // SAFETY: `fetch` must be called with an entity that exists in the world | ||
| unsafe { world.get_entity(entity).debug_checked_unwrap() } | ||
| } | ||
|  | ||
| fn update_component_access(_state: &Self::State, access: &mut FilteredAccess<ComponentId>) { | ||
| assert!( | ||
| !access.access().has_any_write(), | ||
| "EntityRef conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.", | ||
| ); | ||
| access.read_all(); | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does a  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, but a  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer to split that out (and I do think that should be done): that sort of work needs careful review. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should I address this as a part of this PR or should I leave this for later? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leave it until later please. | ||
| } | ||
|  | ||
| fn update_archetype_component_access( | ||
| _state: &Self::State, | ||
| archetype: &Archetype, | ||
| access: &mut Access<ArchetypeComponentId>, | ||
| ) { | ||
| for component_id in archetype.components() { | ||
| access.add_read(archetype.get_archetype_component_id(component_id).unwrap()); | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This means that you can have a system with  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's probably still fine since it only mutates the command queue and not the entity directly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I didn't expect it to be unsound, just something to keep in mind where a system may panic depending on the entities and components in the world. Like how  | ||
| } | ||
| } | ||
|  | ||
| fn init_state(_world: &mut World) {} | ||
|  | ||
| fn matches_component_set( | ||
| _state: &Self::State, | ||
| _set_contains_id: &impl Fn(ComponentId) -> bool, | ||
| ) -> bool { | ||
| true | ||
| } | ||
| } | ||
|  | ||
| /// SAFETY: access is read only | ||
| unsafe impl<'a> ReadOnlyWorldQuery for EntityRef<'a> {} | ||
|  | ||
| #[doc(hidden)] | ||
| pub struct ReadFetch<'w, T> { | ||
| // T::Storage = TableStorage | ||
|  | ||
Uh oh!
There was an error while loading. Please reload this page.