Let query items borrow from query state to avoid needing to clone (#15396)
# Objective Improve the performance of `FilteredEntity(Ref|Mut)` and `Entity(Ref|Mut)Except`. `FilteredEntityRef` needs an `Access<ComponentId>` to determine what components it can access. There is one stored in the query state, but query items cannot borrow from the state, so it has to `clone()` the access for each row. Cloning the access involves memory allocations and can be expensive. ## Solution Let query items borrow from their query state. Add an `'s` lifetime to `WorldQuery::Item` and `WorldQuery::Fetch`, similar to the one in `SystemParam`, and provide `&'s Self::State` to the fetch so that it can borrow from the state. Unfortunately, there are a few cases where we currently return query items from temporary query states: the sorted iteration methods create a temporary state to query the sort keys, and the `EntityRef::components<Q>()` methods create a temporary state for their query. To allow these to continue to work with most `QueryData` implementations, introduce a new subtrait `ReleaseStateQueryData` that converts a `QueryItem<'w, 's>` to `QueryItem<'w, 'static>`, and is implemented for everything except `FilteredEntity(Ref|Mut)` and `Entity(Ref|Mut)Except`. `#[derive(QueryData)]` will generate `ReleaseStateQueryData` implementations that apply when all of the subqueries implement `ReleaseStateQueryData`. This PR does not actually change the implementation of `FilteredEntity(Ref|Mut)` or `Entity(Ref|Mut)Except`! That will be done as a follow-up PR so that the changes are easier to review. I have pushed the changes as chescock/bevy#5. ## Testing I ran performance traces of many_foxes, both against main and against chescock/bevy#5, both including #15282. These changes do appear to make generalized animation a bit faster: (Red is main, yellow is chescock/bevy#5)  ## Migration Guide The `WorldQuery::Item` and `WorldQuery::Fetch` associated types and the `QueryItem` and `ROQueryItem` type aliases now have an additional lifetime parameter corresponding to the `'s` lifetime in `Query`. Manual implementations of `WorldQuery` will need to update the method signatures to include the new lifetimes. Other uses of the types will need to be updated to include a lifetime parameter, although it can usually be passed as `'_`. In particular, `ROQueryItem` is used when implementing `RenderCommand`. Before: ```rust fn render<'w>( item: &P, view: ROQueryItem<'w, Self::ViewQuery>, entity: Option<ROQueryItem<'w, Self::ItemQuery>>, param: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult; ``` After: ```rust fn render<'w>( item: &P, view: ROQueryItem<'w, '_, Self::ViewQuery>, entity: Option<ROQueryItem<'w, '_, Self::ItemQuery>>, param: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult; ``` --- Methods on `QueryState` that take `&mut self` may now result in conflicting borrows if the query items capture the lifetime of the mutable reference. This affects `get()`, `iter()`, and others. To fix the errors, first call `QueryState::update_archetypes()`, and then replace a call `state.foo(world, param)` with `state.query_manual(world).foo_inner(param)`. Alternately, you may be able to restructure the code to call `state.query(world)` once and then make multiple calls using the `Query`. Before: ```rust let mut state: QueryState<_, _> = ...; let d1 = state.get(world, e1); let d2 = state.get(world, e2); // Error: cannot borrow `state` as mutable more than once at a time println!("{d1:?}"); println!("{d2:?}"); ``` After: ```rust let mut state: QueryState<_, _> = ...; state.update_archetypes(world); let d1 = state.get_manual(world, e1); let d2 = state.get_manual(world, e2); // OR state.update_archetypes(world); let d1 = state.query(world).get_inner(e1); let d2 = state.query(world).get_inner(e2); // OR let query = state.query(world); let d1 = query.get_inner(e1); let d1 = query.get_inner(e2); println!("{d1:?}"); println!("{d2:?}"); ```
This commit is contained in:
parent
e610badf6c
commit
f7e112a3c9
@ -847,7 +847,7 @@ impl ViewNode for SmaaNode {
|
|||||||
view_smaa_uniform_offset,
|
view_smaa_uniform_offset,
|
||||||
smaa_textures,
|
smaa_textures,
|
||||||
view_smaa_bind_groups,
|
view_smaa_bind_groups,
|
||||||
): QueryItem<'w, Self::ViewQuery>,
|
): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let pipeline_cache = world.resource::<PipelineCache>();
|
let pipeline_cache = world.resource::<PipelineCache>();
|
||||||
|
@ -150,20 +150,22 @@ pub struct AssetChangedState<A: AsAssetId> {
|
|||||||
#[expect(unsafe_code, reason = "WorldQuery is an unsafe trait.")]
|
#[expect(unsafe_code, reason = "WorldQuery is an unsafe trait.")]
|
||||||
/// SAFETY: `ROQueryFetch<Self>` is the same as `QueryFetch<Self>`
|
/// SAFETY: `ROQueryFetch<Self>` is the same as `QueryFetch<Self>`
|
||||||
unsafe impl<A: AsAssetId> WorldQuery for AssetChanged<A> {
|
unsafe impl<A: AsAssetId> WorldQuery for AssetChanged<A> {
|
||||||
type Fetch<'w> = AssetChangedFetch<'w, A>;
|
type Fetch<'w, 's> = AssetChangedFetch<'w, A>;
|
||||||
|
|
||||||
type State = AssetChangedState<A>;
|
type State = AssetChangedState<A>;
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
fetch: Self::Fetch<'wlong, 's>,
|
||||||
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
fetch
|
fetch
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_fetch<'w>(
|
unsafe fn init_fetch<'w, 's>(
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
state: &Self::State,
|
state: &'s Self::State,
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) -> Self::Fetch<'w> {
|
) -> Self::Fetch<'w, 's> {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// - `AssetChanges` is private and only accessed mutably in the `AssetEventSystems` system set.
|
// - `AssetChanges` is private and only accessed mutably in the `AssetEventSystems` system set.
|
||||||
// - `resource_id` was obtained from the type ID of `AssetChanges<A::Asset>`.
|
// - `resource_id` was obtained from the type ID of `AssetChanges<A::Asset>`.
|
||||||
@ -201,9 +203,9 @@ unsafe impl<A: AsAssetId> WorldQuery for AssetChanged<A> {
|
|||||||
|
|
||||||
const IS_DENSE: bool = <&A>::IS_DENSE;
|
const IS_DENSE: bool = <&A>::IS_DENSE;
|
||||||
|
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
state: &Self::State,
|
state: &'s Self::State,
|
||||||
archetype: &'w Archetype,
|
archetype: &'w Archetype,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
) {
|
) {
|
||||||
@ -215,7 +217,11 @@ unsafe impl<A: AsAssetId> WorldQuery for AssetChanged<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
|
unsafe fn set_table<'w, 's>(
|
||||||
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
|
state: &Self::State,
|
||||||
|
table: &'w Table,
|
||||||
|
) {
|
||||||
if let Some(inner) = &mut fetch.inner {
|
if let Some(inner) = &mut fetch.inner {
|
||||||
// SAFETY: We delegate to the inner `set_table` for `A`
|
// SAFETY: We delegate to the inner `set_table` for `A`
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -265,7 +271,7 @@ unsafe impl<A: AsAssetId> QueryFilter for AssetChanged<A> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn filter_fetch(
|
unsafe fn filter_fetch(
|
||||||
fetch: &mut Self::Fetch<'_>,
|
fetch: &mut Self::Fetch<'_, '_>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
@ -121,7 +121,7 @@ impl ViewNode for BloomNode {
|
|||||||
bloom_settings,
|
bloom_settings,
|
||||||
upsampling_pipeline_ids,
|
upsampling_pipeline_ids,
|
||||||
downsampling_pipeline_ids,
|
downsampling_pipeline_ids,
|
||||||
): QueryItem<'w, Self::ViewQuery>,
|
): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
if bloom_settings.intensity == 0.0 {
|
if bloom_settings.intensity == 0.0 {
|
||||||
|
@ -227,7 +227,7 @@ impl ExtractComponent for Bloom {
|
|||||||
type QueryFilter = With<Hdr>;
|
type QueryFilter = With<Hdr>;
|
||||||
type Out = (Self, BloomUniforms);
|
type Out = (Self, BloomUniforms);
|
||||||
|
|
||||||
fn extract_component((bloom, camera): QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
|
fn extract_component((bloom, camera): QueryItem<'_, '_, Self::QueryData>) -> Option<Self::Out> {
|
||||||
match (
|
match (
|
||||||
camera.physical_viewport_rect(),
|
camera.physical_viewport_rect(),
|
||||||
camera.physical_viewport_size(),
|
camera.physical_viewport_size(),
|
||||||
|
@ -31,7 +31,7 @@ impl ViewNode for MainOpaquePass2dNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
(camera, view, target, depth): QueryItem<'w, Self::ViewQuery>,
|
(camera, view, target, depth): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let (Some(opaque_phases), Some(alpha_mask_phases)) = (
|
let (Some(opaque_phases), Some(alpha_mask_phases)) = (
|
||||||
|
@ -28,7 +28,7 @@ impl ViewNode for MainTransparentPass2dNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
(camera, view, target, depth): bevy_ecs::query::QueryItem<'w, Self::ViewQuery>,
|
(camera, view, target, depth): bevy_ecs::query::QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let Some(transparent_phases) =
|
let Some(transparent_phases) =
|
||||||
|
@ -45,7 +45,7 @@ impl ViewNode for MainOpaquePass3dNode {
|
|||||||
skybox_pipeline,
|
skybox_pipeline,
|
||||||
skybox_bind_group,
|
skybox_bind_group,
|
||||||
view_uniform_offset,
|
view_uniform_offset,
|
||||||
): QueryItem<'w, Self::ViewQuery>,
|
): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let (Some(opaque_phases), Some(alpha_mask_phases)) = (
|
let (Some(opaque_phases), Some(alpha_mask_phases)) = (
|
||||||
|
@ -36,7 +36,7 @@ impl ViewNode for EarlyDeferredGBufferPrepassNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
view_query: QueryItem<'w, Self::ViewQuery>,
|
view_query: QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
run_deferred_prepass(
|
run_deferred_prepass(
|
||||||
@ -74,7 +74,7 @@ impl ViewNode for LateDeferredGBufferPrepassNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
view_query: QueryItem<'w, Self::ViewQuery>,
|
view_query: QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let (_, _, _, _, occlusion_culling, no_indirect_drawing) = view_query;
|
let (_, _, _, _, occlusion_culling, no_indirect_drawing) = view_query;
|
||||||
@ -107,6 +107,7 @@ fn run_deferred_prepass<'w>(
|
|||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
(camera, extracted_view, view_depth_texture, view_prepass_textures, _, _): QueryItem<
|
(camera, extracted_view, view_depth_texture, view_prepass_textures, _, _): QueryItem<
|
||||||
'w,
|
'w,
|
||||||
|
'_,
|
||||||
<LateDeferredGBufferPrepassNode as ViewNode>::ViewQuery,
|
<LateDeferredGBufferPrepassNode as ViewNode>::ViewQuery,
|
||||||
>,
|
>,
|
||||||
is_late: bool,
|
is_late: bool,
|
||||||
|
@ -352,7 +352,7 @@ impl ViewNode for DepthOfFieldNode {
|
|||||||
view_bind_group_layouts,
|
view_bind_group_layouts,
|
||||||
depth_of_field_uniform_index,
|
depth_of_field_uniform_index,
|
||||||
auxiliary_dof_texture,
|
auxiliary_dof_texture,
|
||||||
): QueryItem<'w, Self::ViewQuery>,
|
): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let pipeline_cache = world.resource::<PipelineCache>();
|
let pipeline_cache = world.resource::<PipelineCache>();
|
||||||
|
@ -61,7 +61,7 @@ impl ViewNode for MsaaWritebackNode {
|
|||||||
&self,
|
&self,
|
||||||
_graph: &mut RenderGraphContext,
|
_graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
(target, blit_pipeline_id, msaa): QueryItem<'w, Self::ViewQuery>,
|
(target, blit_pipeline_id, msaa): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
if *msaa == Msaa::Off {
|
if *msaa == Msaa::Off {
|
||||||
|
@ -352,7 +352,7 @@ impl ViewNode for PostProcessingNode {
|
|||||||
&self,
|
&self,
|
||||||
_: &mut RenderGraphContext,
|
_: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
(view_target, pipeline_id, chromatic_aberration, post_processing_uniform_buffer_offsets): QueryItem<'w, Self::ViewQuery>,
|
(view_target, pipeline_id, chromatic_aberration, post_processing_uniform_buffer_offsets): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let pipeline_cache = world.resource::<PipelineCache>();
|
let pipeline_cache = world.resource::<PipelineCache>();
|
||||||
@ -485,7 +485,7 @@ impl ExtractComponent for ChromaticAberration {
|
|||||||
type Out = ChromaticAberration;
|
type Out = ChromaticAberration;
|
||||||
|
|
||||||
fn extract_component(
|
fn extract_component(
|
||||||
chromatic_aberration: QueryItem<'_, Self::QueryData>,
|
chromatic_aberration: QueryItem<'_, '_, Self::QueryData>,
|
||||||
) -> Option<Self::Out> {
|
) -> Option<Self::Out> {
|
||||||
// Skip the postprocessing phase entirely if the intensity is zero.
|
// Skip the postprocessing phase entirely if the intensity is zero.
|
||||||
if chromatic_aberration.intensity > 0.0 {
|
if chromatic_aberration.intensity > 0.0 {
|
||||||
|
@ -36,7 +36,7 @@ impl ViewNode for EarlyPrepassNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
view_query: QueryItem<'w, Self::ViewQuery>,
|
view_query: QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
run_prepass(graph, render_context, view_query, world, "early prepass")
|
run_prepass(graph, render_context, view_query, world, "early prepass")
|
||||||
@ -73,7 +73,7 @@ impl ViewNode for LatePrepassNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
query: QueryItem<'w, Self::ViewQuery>,
|
query: QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
// We only need a late prepass if we have occlusion culling and indirect
|
// We only need a late prepass if we have occlusion culling and indirect
|
||||||
@ -112,7 +112,7 @@ fn run_prepass<'w>(
|
|||||||
_,
|
_,
|
||||||
_,
|
_,
|
||||||
has_deferred,
|
has_deferred,
|
||||||
): QueryItem<'w, <LatePrepassNode as ViewNode>::ViewQuery>,
|
): QueryItem<'w, '_, <LatePrepassNode as ViewNode>::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
label: &'static str,
|
label: &'static str,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
|
@ -113,7 +113,9 @@ impl ExtractComponent for Skybox {
|
|||||||
type QueryFilter = ();
|
type QueryFilter = ();
|
||||||
type Out = (Self, SkyboxUniforms);
|
type Out = (Self, SkyboxUniforms);
|
||||||
|
|
||||||
fn extract_component((skybox, exposure): QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
|
fn extract_component(
|
||||||
|
(skybox, exposure): QueryItem<'_, '_, Self::QueryData>,
|
||||||
|
) -> Option<Self::Out> {
|
||||||
let exposure = exposure
|
let exposure = exposure
|
||||||
.map(Exposure::exposure)
|
.map(Exposure::exposure)
|
||||||
.unwrap_or_else(|| Exposure::default().exposure());
|
.unwrap_or_else(|| Exposure::default().exposure());
|
||||||
|
@ -76,6 +76,7 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
|||||||
let user_generics_with_world = {
|
let user_generics_with_world = {
|
||||||
let mut generics = ast.generics;
|
let mut generics = ast.generics;
|
||||||
generics.params.insert(0, parse_quote!('__w));
|
generics.params.insert(0, parse_quote!('__w));
|
||||||
|
generics.params.insert(0, parse_quote!('__s));
|
||||||
generics
|
generics
|
||||||
};
|
};
|
||||||
let (user_impl_generics_with_world, user_ty_generics_with_world, user_where_clauses_with_world) =
|
let (user_impl_generics_with_world, user_ty_generics_with_world, user_where_clauses_with_world) =
|
||||||
@ -256,11 +257,11 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
|||||||
for #read_only_struct_name #user_ty_generics #user_where_clauses {
|
for #read_only_struct_name #user_ty_generics #user_where_clauses {
|
||||||
const IS_READ_ONLY: bool = true;
|
const IS_READ_ONLY: bool = true;
|
||||||
type ReadOnly = #read_only_struct_name #user_ty_generics;
|
type ReadOnly = #read_only_struct_name #user_ty_generics;
|
||||||
type Item<'__w> = #read_only_item_struct_name #user_ty_generics_with_world;
|
type Item<'__w, '__s> = #read_only_item_struct_name #user_ty_generics_with_world;
|
||||||
|
|
||||||
fn shrink<'__wlong: '__wshort, '__wshort>(
|
fn shrink<'__wlong: '__wshort, '__wshort, '__s>(
|
||||||
item: Self::Item<'__wlong>
|
item: Self::Item<'__wlong, '__s>
|
||||||
) -> Self::Item<'__wshort> {
|
) -> Self::Item<'__wshort, '__s> {
|
||||||
#read_only_item_struct_name {
|
#read_only_item_struct_name {
|
||||||
#(
|
#(
|
||||||
#field_idents: <#read_only_field_types>::shrink(item.#field_idents),
|
#field_idents: <#read_only_field_types>::shrink(item.#field_idents),
|
||||||
@ -278,16 +279,28 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
/// SAFETY: we call `fetch` for each member that implements `Fetch`.
|
/// SAFETY: we call `fetch` for each member that implements `Fetch`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn fetch<'__w>(
|
unsafe fn fetch<'__w, '__s>(
|
||||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||||
_entity: #path::entity::Entity,
|
_entity: #path::entity::Entity,
|
||||||
_table_row: #path::storage::TableRow,
|
_table_row: #path::storage::TableRow,
|
||||||
) -> Self::Item<'__w> {
|
) -> Self::Item<'__w, '__s> {
|
||||||
Self::Item {
|
Self::Item {
|
||||||
#(#field_idents: <#read_only_field_types>::fetch(&mut _fetch.#named_field_idents, _entity, _table_row),)*
|
#(#field_idents: <#read_only_field_types>::fetch(&mut _fetch.#named_field_idents, _entity, _table_row),)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl #user_impl_generics #path::query::ReleaseStateQueryData
|
||||||
|
for #read_only_struct_name #user_ty_generics #user_where_clauses
|
||||||
|
// Make these HRTBs with an unused lifetime parameter to allow trivial constraints
|
||||||
|
// See https://github.com/rust-lang/rust/issues/48214
|
||||||
|
where #(for<'__a> #field_types: #path::query::QueryData<ReadOnly: #path::query::ReleaseStateQueryData>,)* {
|
||||||
|
fn release_state<'__w>(_item: Self::Item<'__w, '_>) -> Self::Item<'__w, 'static> {
|
||||||
|
Self::Item {
|
||||||
|
#(#field_idents: <#read_only_field_types>::release_state(_item.#field_idents),)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {}
|
quote! {}
|
||||||
@ -301,11 +314,11 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
|||||||
for #struct_name #user_ty_generics #user_where_clauses {
|
for #struct_name #user_ty_generics #user_where_clauses {
|
||||||
const IS_READ_ONLY: bool = #is_read_only;
|
const IS_READ_ONLY: bool = #is_read_only;
|
||||||
type ReadOnly = #read_only_struct_name #user_ty_generics;
|
type ReadOnly = #read_only_struct_name #user_ty_generics;
|
||||||
type Item<'__w> = #item_struct_name #user_ty_generics_with_world;
|
type Item<'__w, '__s> = #item_struct_name #user_ty_generics_with_world;
|
||||||
|
|
||||||
fn shrink<'__wlong: '__wshort, '__wshort>(
|
fn shrink<'__wlong: '__wshort, '__wshort, '__s>(
|
||||||
item: Self::Item<'__wlong>
|
item: Self::Item<'__wlong, '__s>
|
||||||
) -> Self::Item<'__wshort> {
|
) -> Self::Item<'__wshort, '__s> {
|
||||||
#item_struct_name {
|
#item_struct_name {
|
||||||
#(
|
#(
|
||||||
#field_idents: <#field_types>::shrink(item.#field_idents),
|
#field_idents: <#field_types>::shrink(item.#field_idents),
|
||||||
@ -323,17 +336,29 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
/// SAFETY: we call `fetch` for each member that implements `Fetch`.
|
/// SAFETY: we call `fetch` for each member that implements `Fetch`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn fetch<'__w>(
|
unsafe fn fetch<'__w, '__s>(
|
||||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||||
_entity: #path::entity::Entity,
|
_entity: #path::entity::Entity,
|
||||||
_table_row: #path::storage::TableRow,
|
_table_row: #path::storage::TableRow,
|
||||||
) -> Self::Item<'__w> {
|
) -> Self::Item<'__w, '__s> {
|
||||||
Self::Item {
|
Self::Item {
|
||||||
#(#field_idents: <#field_types>::fetch(&mut _fetch.#named_field_idents, _entity, _table_row),)*
|
#(#field_idents: <#field_types>::fetch(&mut _fetch.#named_field_idents, _entity, _table_row),)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl #user_impl_generics #path::query::ReleaseStateQueryData
|
||||||
|
for #struct_name #user_ty_generics #user_where_clauses
|
||||||
|
// Make these HRTBs with an unused lifetime parameter to allow trivial constraints
|
||||||
|
// See https://github.com/rust-lang/rust/issues/48214
|
||||||
|
where #(for<'__a> #field_types: #path::query::ReleaseStateQueryData,)* {
|
||||||
|
fn release_state<'__w>(_item: Self::Item<'__w, '_>) -> Self::Item<'__w, 'static> {
|
||||||
|
Self::Item {
|
||||||
|
#(#field_idents: <#field_types>::release_state(_item.#field_idents),)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#read_only_data_impl
|
#read_only_data_impl
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -23,6 +23,7 @@ pub fn derive_query_filter_impl(input: TokenStream) -> TokenStream {
|
|||||||
let user_generics_with_world = {
|
let user_generics_with_world = {
|
||||||
let mut generics = ast.generics;
|
let mut generics = ast.generics;
|
||||||
generics.params.insert(0, parse_quote!('__w));
|
generics.params.insert(0, parse_quote!('__w));
|
||||||
|
generics.params.insert(0, parse_quote!('__s));
|
||||||
generics
|
generics
|
||||||
};
|
};
|
||||||
let (user_impl_generics_with_world, user_ty_generics_with_world, user_where_clauses_with_world) =
|
let (user_impl_generics_with_world, user_ty_generics_with_world, user_where_clauses_with_world) =
|
||||||
@ -101,8 +102,8 @@ pub fn derive_query_filter_impl(input: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn filter_fetch<'__w>(
|
unsafe fn filter_fetch<'__w, '__s>(
|
||||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||||
_entity: #path::entity::Entity,
|
_entity: #path::entity::Entity,
|
||||||
_table_row: #path::storage::TableRow,
|
_table_row: #path::storage::TableRow,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
@ -34,14 +34,14 @@ pub(crate) fn item_struct(
|
|||||||
#derive_macro_call
|
#derive_macro_call
|
||||||
#item_attrs
|
#item_attrs
|
||||||
#visibility struct #item_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
|
#visibility struct #item_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
|
||||||
#(#(#field_attrs)* #field_visibilities #field_idents: <#field_types as #path::query::QueryData>::Item<'__w>,)*
|
#(#(#field_attrs)* #field_visibilities #field_idents: <#field_types as #path::query::QueryData>::Item<'__w, '__s>,)*
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Fields::Unnamed(_) => quote! {
|
Fields::Unnamed(_) => quote! {
|
||||||
#derive_macro_call
|
#derive_macro_call
|
||||||
#item_attrs
|
#item_attrs
|
||||||
#visibility struct #item_struct_name #user_impl_generics_with_world #user_where_clauses_with_world(
|
#visibility struct #item_struct_name #user_impl_generics_with_world #user_where_clauses_with_world(
|
||||||
#( #field_visibilities <#field_types as #path::query::QueryData>::Item<'__w>, )*
|
#( #field_visibilities <#field_types as #path::query::QueryData>::Item<'__w, '__s>, )*
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Fields::Unit => quote! {
|
Fields::Unit => quote! {
|
||||||
@ -78,8 +78,8 @@ pub(crate) fn world_query_impl(
|
|||||||
)]
|
)]
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
#visibility struct #fetch_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
|
#visibility struct #fetch_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
|
||||||
#(#named_field_idents: <#field_types as #path::query::WorldQuery>::Fetch<'__w>,)*
|
#(#named_field_idents: <#field_types as #path::query::WorldQuery>::Fetch<'__w, '__s>,)*
|
||||||
#marker_name: &'__w (),
|
#marker_name: (&'__w(), &'__s()),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #user_impl_generics_with_world Clone for #fetch_struct_name #user_ty_generics_with_world
|
impl #user_impl_generics_with_world Clone for #fetch_struct_name #user_ty_generics_with_world
|
||||||
@ -87,7 +87,7 @@ pub(crate) fn world_query_impl(
|
|||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
#(#named_field_idents: self.#named_field_idents.clone(),)*
|
#(#named_field_idents: self.#named_field_idents.clone(),)*
|
||||||
#marker_name: &(),
|
#marker_name: (&(), &()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,26 +96,26 @@ pub(crate) fn world_query_impl(
|
|||||||
unsafe impl #user_impl_generics #path::query::WorldQuery
|
unsafe impl #user_impl_generics #path::query::WorldQuery
|
||||||
for #struct_name #user_ty_generics #user_where_clauses {
|
for #struct_name #user_ty_generics #user_where_clauses {
|
||||||
|
|
||||||
type Fetch<'__w> = #fetch_struct_name #user_ty_generics_with_world;
|
type Fetch<'__w, '__s> = #fetch_struct_name #user_ty_generics_with_world;
|
||||||
type State = #state_struct_name #user_ty_generics;
|
type State = #state_struct_name #user_ty_generics;
|
||||||
|
|
||||||
fn shrink_fetch<'__wlong: '__wshort, '__wshort>(
|
fn shrink_fetch<'__wlong: '__wshort, '__wshort, '__s>(
|
||||||
fetch: <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wlong>
|
fetch: <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wlong, '__s>
|
||||||
) -> <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wshort> {
|
) -> <#struct_name #user_ty_generics as #path::query::WorldQuery>::Fetch<'__wshort, '__s> {
|
||||||
#fetch_struct_name {
|
#fetch_struct_name {
|
||||||
#(
|
#(
|
||||||
#named_field_idents: <#field_types>::shrink_fetch(fetch.#named_field_idents),
|
#named_field_idents: <#field_types>::shrink_fetch(fetch.#named_field_idents),
|
||||||
)*
|
)*
|
||||||
#marker_name: &(),
|
#marker_name: (&(), &()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_fetch<'__w>(
|
unsafe fn init_fetch<'__w, '__s>(
|
||||||
_world: #path::world::unsafe_world_cell::UnsafeWorldCell<'__w>,
|
_world: #path::world::unsafe_world_cell::UnsafeWorldCell<'__w>,
|
||||||
state: &Self::State,
|
state: &'__s Self::State,
|
||||||
_last_run: #path::component::Tick,
|
_last_run: #path::component::Tick,
|
||||||
_this_run: #path::component::Tick,
|
_this_run: #path::component::Tick,
|
||||||
) -> <Self as #path::query::WorldQuery>::Fetch<'__w> {
|
) -> <Self as #path::query::WorldQuery>::Fetch<'__w, '__s> {
|
||||||
#fetch_struct_name {
|
#fetch_struct_name {
|
||||||
#(#named_field_idents:
|
#(#named_field_idents:
|
||||||
<#field_types>::init_fetch(
|
<#field_types>::init_fetch(
|
||||||
@ -125,7 +125,7 @@ pub(crate) fn world_query_impl(
|
|||||||
_this_run,
|
_this_run,
|
||||||
),
|
),
|
||||||
)*
|
)*
|
||||||
#marker_name: &(),
|
#marker_name: (&(), &()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,9 +133,9 @@ pub(crate) fn world_query_impl(
|
|||||||
|
|
||||||
/// SAFETY: we call `set_archetype` for each member that implements `Fetch`
|
/// SAFETY: we call `set_archetype` for each member that implements `Fetch`
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_archetype<'__w>(
|
unsafe fn set_archetype<'__w, '__s>(
|
||||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||||
_state: &Self::State,
|
_state: &'__s Self::State,
|
||||||
_archetype: &'__w #path::archetype::Archetype,
|
_archetype: &'__w #path::archetype::Archetype,
|
||||||
_table: &'__w #path::storage::Table
|
_table: &'__w #path::storage::Table
|
||||||
) {
|
) {
|
||||||
@ -144,9 +144,9 @@ pub(crate) fn world_query_impl(
|
|||||||
|
|
||||||
/// SAFETY: we call `set_table` for each member that implements `Fetch`
|
/// SAFETY: we call `set_table` for each member that implements `Fetch`
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_table<'__w>(
|
unsafe fn set_table<'__w, '__s>(
|
||||||
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
|
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w, '__s>,
|
||||||
_state: &Self::State,
|
_state: &'__s Self::State,
|
||||||
_table: &'__w #path::storage::Table
|
_table: &'__w #path::storage::Table
|
||||||
) {
|
) {
|
||||||
#(<#field_types>::set_table(&mut _fetch.#named_field_idents, &_state.#named_field_idents, _table);)*
|
#(<#field_types>::set_table(&mut _fetch.#named_field_idents, &_state.#named_field_idents, _table);)*
|
||||||
|
@ -141,7 +141,7 @@ pub struct NameOrEntity {
|
|||||||
pub entity: Entity,
|
pub entity: Entity,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> core::fmt::Display for NameOrEntityItem<'a> {
|
impl<'w, 's> core::fmt::Display for NameOrEntityItem<'w, 's> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
match self.name {
|
match self.name {
|
||||||
@ -274,9 +274,9 @@ mod tests {
|
|||||||
let e2 = world.spawn(name.clone()).id();
|
let e2 = world.spawn(name.clone()).id();
|
||||||
let mut query = world.query::<NameOrEntity>();
|
let mut query = world.query::<NameOrEntity>();
|
||||||
let d1 = query.get(&world, e1).unwrap();
|
let d1 = query.get(&world, e1).unwrap();
|
||||||
let d2 = query.get(&world, e2).unwrap();
|
|
||||||
// NameOrEntity Display for entities without a Name should be {index}v{generation}
|
// NameOrEntity Display for entities without a Name should be {index}v{generation}
|
||||||
assert_eq!(d1.to_string(), "0v0");
|
assert_eq!(d1.to_string(), "0v0");
|
||||||
|
let d2 = query.get(&world, e2).unwrap();
|
||||||
// NameOrEntity Display for entities with a Name should be the Name
|
// NameOrEntity Display for entities with a Name should be the Name
|
||||||
assert_eq!(d2.to_string(), "MyName");
|
assert_eq!(d2.to_string(), "MyName");
|
||||||
}
|
}
|
||||||
|
@ -1078,7 +1078,7 @@ mod tests {
|
|||||||
struct ChildOf(Entity);
|
struct ChildOf(Entity);
|
||||||
|
|
||||||
impl<D> Traversal<D> for &'_ ChildOf {
|
impl<D> Traversal<D> for &'_ ChildOf {
|
||||||
fn traverse(item: Self::Item<'_>, _: &D) -> Option<Entity> {
|
fn traverse(item: Self::Item<'_, '_>, _: &D) -> Option<Entity> {
|
||||||
Some(item.0)
|
Some(item.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -103,7 +103,7 @@ pub unsafe trait QueryFilter: WorldQuery {
|
|||||||
/// Must always be called _after_ [`WorldQuery::set_table`] or [`WorldQuery::set_archetype`]. `entity` and
|
/// Must always be called _after_ [`WorldQuery::set_table`] or [`WorldQuery::set_archetype`]. `entity` and
|
||||||
/// `table_row` must be in the range of the current table and archetype.
|
/// `table_row` must be in the range of the current table and archetype.
|
||||||
unsafe fn filter_fetch(
|
unsafe fn filter_fetch(
|
||||||
fetch: &mut Self::Fetch<'_>,
|
fetch: &mut Self::Fetch<'_, '_>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
@ -144,10 +144,13 @@ pub struct With<T>(PhantomData<T>);
|
|||||||
/// `update_component_access` adds a `With` filter for `T`.
|
/// `update_component_access` adds a `With` filter for `T`.
|
||||||
/// This is sound because `matches_component_set` returns whether the set contains the component.
|
/// This is sound because `matches_component_set` returns whether the set contains the component.
|
||||||
unsafe impl<T: Component> WorldQuery for With<T> {
|
unsafe impl<T: Component> WorldQuery for With<T> {
|
||||||
type Fetch<'w> = ();
|
type Fetch<'w, 's> = ();
|
||||||
type State = ComponentId;
|
type State = ComponentId;
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
_: Self::Fetch<'wlong, 's>,
|
||||||
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch(
|
unsafe fn init_fetch(
|
||||||
@ -204,7 +207,7 @@ unsafe impl<T: Component> QueryFilter for With<T> {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn filter_fetch(
|
unsafe fn filter_fetch(
|
||||||
_fetch: &mut Self::Fetch<'_>,
|
_fetch: &mut Self::Fetch<'_, '_>,
|
||||||
_entity: Entity,
|
_entity: Entity,
|
||||||
_table_row: TableRow,
|
_table_row: TableRow,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -244,10 +247,13 @@ pub struct Without<T>(PhantomData<T>);
|
|||||||
/// `update_component_access` adds a `Without` filter for `T`.
|
/// `update_component_access` adds a `Without` filter for `T`.
|
||||||
/// This is sound because `matches_component_set` returns whether the set does not contain the component.
|
/// This is sound because `matches_component_set` returns whether the set does not contain the component.
|
||||||
unsafe impl<T: Component> WorldQuery for Without<T> {
|
unsafe impl<T: Component> WorldQuery for Without<T> {
|
||||||
type Fetch<'w> = ();
|
type Fetch<'w, 's> = ();
|
||||||
type State = ComponentId;
|
type State = ComponentId;
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
_: Self::Fetch<'wlong, 's>,
|
||||||
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch(
|
unsafe fn init_fetch(
|
||||||
@ -304,7 +310,7 @@ unsafe impl<T: Component> QueryFilter for Without<T> {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn filter_fetch(
|
unsafe fn filter_fetch(
|
||||||
_fetch: &mut Self::Fetch<'_>,
|
_fetch: &mut Self::Fetch<'_, '_>,
|
||||||
_entity: Entity,
|
_entity: Entity,
|
||||||
_table_row: TableRow,
|
_table_row: TableRow,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -345,12 +351,12 @@ unsafe impl<T: Component> QueryFilter for Without<T> {
|
|||||||
pub struct Or<T>(PhantomData<T>);
|
pub struct Or<T>(PhantomData<T>);
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct OrFetch<'w, T: WorldQuery> {
|
pub struct OrFetch<'w, 's, T: WorldQuery> {
|
||||||
fetch: T::Fetch<'w>,
|
fetch: T::Fetch<'w, 's>,
|
||||||
matches: bool,
|
matches: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: WorldQuery> Clone for OrFetch<'_, T> {
|
impl<T: WorldQuery> Clone for OrFetch<'_, '_, T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fetch: self.fetch.clone(),
|
fetch: self.fetch.clone(),
|
||||||
@ -384,10 +390,10 @@ macro_rules! impl_or_query_filter {
|
|||||||
/// `update_component_access` replace the filters with a disjunction where every element is a conjunction of the previous filters and the filters of one of the subqueries.
|
/// `update_component_access` replace the filters with a disjunction where every element is a conjunction of the previous filters and the filters of one of the subqueries.
|
||||||
/// This is sound because `matches_component_set` returns a disjunction of the results of the subqueries' implementations.
|
/// This is sound because `matches_component_set` returns a disjunction of the results of the subqueries' implementations.
|
||||||
unsafe impl<$($filter: QueryFilter),*> WorldQuery for Or<($($filter,)*)> {
|
unsafe impl<$($filter: QueryFilter),*> WorldQuery for Or<($($filter,)*)> {
|
||||||
type Fetch<'w> = ($(OrFetch<'w, $filter>,)*);
|
type Fetch<'w, 's> = ($(OrFetch<'w, 's, $filter>,)*);
|
||||||
type State = ($($filter::State,)*);
|
type State = ($($filter::State,)*);
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(fetch: Self::Fetch<'wlong, 's>) -> Self::Fetch<'wshort, 's> {
|
||||||
let ($($filter,)*) = fetch;
|
let ($($filter,)*) = fetch;
|
||||||
($(
|
($(
|
||||||
OrFetch {
|
OrFetch {
|
||||||
@ -400,7 +406,7 @@ macro_rules! impl_or_query_filter {
|
|||||||
const IS_DENSE: bool = true $(&& $filter::IS_DENSE)*;
|
const IS_DENSE: bool = true $(&& $filter::IS_DENSE)*;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch<'w>(world: UnsafeWorldCell<'w>, state: &Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w> {
|
unsafe fn init_fetch<'w, 's>(world: UnsafeWorldCell<'w>, state: &'s Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w, 's> {
|
||||||
let ($($filter,)*) = state;
|
let ($($filter,)*) = state;
|
||||||
($(OrFetch {
|
($(OrFetch {
|
||||||
// SAFETY: The invariants are upheld by the caller.
|
// SAFETY: The invariants are upheld by the caller.
|
||||||
@ -410,7 +416,7 @@ macro_rules! impl_or_query_filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
|
unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w, 's>, state: &'s Self::State, table: &'w Table) {
|
||||||
let ($($filter,)*) = fetch;
|
let ($($filter,)*) = fetch;
|
||||||
let ($($state,)*) = state;
|
let ($($state,)*) = state;
|
||||||
$(
|
$(
|
||||||
@ -423,9 +429,9 @@ macro_rules! impl_or_query_filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
state: & Self::State,
|
state: &'s Self::State,
|
||||||
archetype: &'w Archetype,
|
archetype: &'w Archetype,
|
||||||
table: &'w Table
|
table: &'w Table
|
||||||
) {
|
) {
|
||||||
@ -495,7 +501,7 @@ macro_rules! impl_or_query_filter {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn filter_fetch(
|
unsafe fn filter_fetch(
|
||||||
fetch: &mut Self::Fetch<'_>,
|
fetch: &mut Self::Fetch<'_, '_>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow
|
table_row: TableRow
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -528,7 +534,7 @@ macro_rules! impl_tuple_query_filter {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn filter_fetch(
|
unsafe fn filter_fetch(
|
||||||
fetch: &mut Self::Fetch<'_>,
|
fetch: &mut Self::Fetch<'_, '_>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow
|
table_row: TableRow
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -568,10 +574,13 @@ pub struct Allows<T>(PhantomData<T>);
|
|||||||
/// `update_component_access` adds an archetypal filter for `T`.
|
/// `update_component_access` adds an archetypal filter for `T`.
|
||||||
/// This is sound because it doesn't affect the query
|
/// This is sound because it doesn't affect the query
|
||||||
unsafe impl<T: Component> WorldQuery for Allows<T> {
|
unsafe impl<T: Component> WorldQuery for Allows<T> {
|
||||||
type Fetch<'w> = ();
|
type Fetch<'w, 's> = ();
|
||||||
type State = ComponentId;
|
type State = ComponentId;
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
_: Self::Fetch<'wlong, 's>,
|
||||||
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch(_: UnsafeWorldCell, _: &ComponentId, _: Tick, _: Tick) {}
|
unsafe fn init_fetch(_: UnsafeWorldCell, _: &ComponentId, _: Tick, _: Tick) {}
|
||||||
@ -609,7 +618,7 @@ unsafe impl<T: Component> QueryFilter for Allows<T> {
|
|||||||
const IS_ARCHETYPAL: bool = true;
|
const IS_ARCHETYPAL: bool = true;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn filter_fetch(_: &mut Self::Fetch<'_>, _: Entity, _: TableRow) -> bool {
|
unsafe fn filter_fetch(_: &mut Self::Fetch<'_, '_>, _: Entity, _: TableRow) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -710,21 +719,23 @@ impl<T: Component> Clone for AddedFetch<'_, T> {
|
|||||||
/// `update_component_access` adds a `With` filter for a component.
|
/// `update_component_access` adds a `With` filter for a component.
|
||||||
/// This is sound because `matches_component_set` returns whether the set contains that component.
|
/// This is sound because `matches_component_set` returns whether the set contains that component.
|
||||||
unsafe impl<T: Component> WorldQuery for Added<T> {
|
unsafe impl<T: Component> WorldQuery for Added<T> {
|
||||||
type Fetch<'w> = AddedFetch<'w, T>;
|
type Fetch<'w, 's> = AddedFetch<'w, T>;
|
||||||
type State = ComponentId;
|
type State = ComponentId;
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
fetch: Self::Fetch<'wlong, 's>,
|
||||||
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
fetch
|
fetch
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch<'w>(
|
unsafe fn init_fetch<'w, 's>(
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
&id: &ComponentId,
|
&id: &'s ComponentId,
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) -> Self::Fetch<'w> {
|
) -> Self::Fetch<'w, 's> {
|
||||||
Self::Fetch::<'w> {
|
Self::Fetch::<'w, 's> {
|
||||||
ticks: StorageSwitch::new(
|
ticks: StorageSwitch::new(
|
||||||
|| None,
|
|| None,
|
||||||
|| {
|
|| {
|
||||||
@ -748,9 +759,9 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
component_id: &ComponentId,
|
component_id: &'s ComponentId,
|
||||||
_archetype: &'w Archetype,
|
_archetype: &'w Archetype,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
) {
|
) {
|
||||||
@ -763,9 +774,9 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_table<'w>(
|
unsafe fn set_table<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
&component_id: &ComponentId,
|
&component_id: &'s ComponentId,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
) {
|
) {
|
||||||
let table_ticks = Some(
|
let table_ticks = Some(
|
||||||
@ -807,7 +818,7 @@ unsafe impl<T: Component> QueryFilter for Added<T> {
|
|||||||
const IS_ARCHETYPAL: bool = false;
|
const IS_ARCHETYPAL: bool = false;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn filter_fetch(
|
unsafe fn filter_fetch(
|
||||||
fetch: &mut Self::Fetch<'_>,
|
fetch: &mut Self::Fetch<'_, '_>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -936,21 +947,23 @@ impl<T: Component> Clone for ChangedFetch<'_, T> {
|
|||||||
/// `update_component_access` adds a `With` filter for a component.
|
/// `update_component_access` adds a `With` filter for a component.
|
||||||
/// This is sound because `matches_component_set` returns whether the set contains that component.
|
/// This is sound because `matches_component_set` returns whether the set contains that component.
|
||||||
unsafe impl<T: Component> WorldQuery for Changed<T> {
|
unsafe impl<T: Component> WorldQuery for Changed<T> {
|
||||||
type Fetch<'w> = ChangedFetch<'w, T>;
|
type Fetch<'w, 's> = ChangedFetch<'w, T>;
|
||||||
type State = ComponentId;
|
type State = ComponentId;
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
fetch: Self::Fetch<'wlong, 's>,
|
||||||
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
fetch
|
fetch
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch<'w>(
|
unsafe fn init_fetch<'w, 's>(
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
&id: &ComponentId,
|
&id: &'s ComponentId,
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) -> Self::Fetch<'w> {
|
) -> Self::Fetch<'w, 's> {
|
||||||
Self::Fetch::<'w> {
|
Self::Fetch::<'w, 's> {
|
||||||
ticks: StorageSwitch::new(
|
ticks: StorageSwitch::new(
|
||||||
|| None,
|
|| None,
|
||||||
|| {
|
|| {
|
||||||
@ -974,9 +987,9 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
component_id: &ComponentId,
|
component_id: &'s ComponentId,
|
||||||
_archetype: &'w Archetype,
|
_archetype: &'w Archetype,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
) {
|
) {
|
||||||
@ -989,9 +1002,9 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_table<'w>(
|
unsafe fn set_table<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
&component_id: &ComponentId,
|
&component_id: &'s ComponentId,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
) {
|
) {
|
||||||
let table_ticks = Some(
|
let table_ticks = Some(
|
||||||
@ -1034,7 +1047,7 @@ unsafe impl<T: Component> QueryFilter for Changed<T> {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn filter_fetch(
|
unsafe fn filter_fetch(
|
||||||
fetch: &mut Self::Fetch<'_>,
|
fetch: &mut Self::Fetch<'_, '_>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -1133,20 +1146,22 @@ pub struct SpawnedFetch<'w> {
|
|||||||
|
|
||||||
// SAFETY: WorldQuery impl accesses no components or component ticks
|
// SAFETY: WorldQuery impl accesses no components or component ticks
|
||||||
unsafe impl WorldQuery for Spawned {
|
unsafe impl WorldQuery for Spawned {
|
||||||
type Fetch<'w> = SpawnedFetch<'w>;
|
type Fetch<'w, 's> = SpawnedFetch<'w>;
|
||||||
type State = ();
|
type State = ();
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
fetch: Self::Fetch<'wlong, 's>,
|
||||||
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
fetch
|
fetch
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch<'w>(
|
unsafe fn init_fetch<'w, 's>(
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
_state: &(),
|
_state: &'s (),
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) -> Self::Fetch<'w> {
|
) -> Self::Fetch<'w, 's> {
|
||||||
SpawnedFetch {
|
SpawnedFetch {
|
||||||
entities: world.entities(),
|
entities: world.entities(),
|
||||||
last_run,
|
last_run,
|
||||||
@ -1157,16 +1172,21 @@ unsafe impl WorldQuery for Spawned {
|
|||||||
const IS_DENSE: bool = true;
|
const IS_DENSE: bool = true;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
_fetch: &mut Self::Fetch<'w>,
|
_fetch: &mut Self::Fetch<'w, 's>,
|
||||||
_state: &(),
|
_state: &'s (),
|
||||||
_archetype: &'w Archetype,
|
_archetype: &'w Archetype,
|
||||||
_table: &'w Table,
|
_table: &'w Table,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &(), _table: &'w Table) {}
|
unsafe fn set_table<'w, 's>(
|
||||||
|
_fetch: &mut Self::Fetch<'w, 's>,
|
||||||
|
_state: &'s (),
|
||||||
|
_table: &'w Table,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn update_component_access(_state: &(), _access: &mut FilteredAccess<ComponentId>) {}
|
fn update_component_access(_state: &(), _access: &mut FilteredAccess<ComponentId>) {}
|
||||||
@ -1188,7 +1208,7 @@ unsafe impl QueryFilter for Spawned {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn filter_fetch(
|
unsafe fn filter_fetch(
|
||||||
fetch: &mut Self::Fetch<'_>,
|
fetch: &mut Self::Fetch<'_, '_>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
_table_row: TableRow,
|
_table_row: TableRow,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
@ -140,7 +140,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
range: Option<Range<u32>>,
|
range: Option<Range<u32>>,
|
||||||
) -> B
|
) -> B
|
||||||
where
|
where
|
||||||
Func: FnMut(B, D::Item<'w>) -> B,
|
Func: FnMut(B, D::Item<'w, 's>) -> B,
|
||||||
{
|
{
|
||||||
if self.cursor.is_dense {
|
if self.cursor.is_dense {
|
||||||
// SAFETY: `self.cursor.is_dense` is true, so storage ids are guaranteed to be table ids.
|
// SAFETY: `self.cursor.is_dense` is true, so storage ids are guaranteed to be table ids.
|
||||||
@ -203,7 +203,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
rows: Range<u32>,
|
rows: Range<u32>,
|
||||||
) -> B
|
) -> B
|
||||||
where
|
where
|
||||||
Func: FnMut(B, D::Item<'w>) -> B,
|
Func: FnMut(B, D::Item<'w, 's>) -> B,
|
||||||
{
|
{
|
||||||
if table.is_empty() {
|
if table.is_empty() {
|
||||||
return accum;
|
return accum;
|
||||||
@ -255,7 +255,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
indices: Range<u32>,
|
indices: Range<u32>,
|
||||||
) -> B
|
) -> B
|
||||||
where
|
where
|
||||||
Func: FnMut(B, D::Item<'w>) -> B,
|
Func: FnMut(B, D::Item<'w, 's>) -> B,
|
||||||
{
|
{
|
||||||
if archetype.is_empty() {
|
if archetype.is_empty() {
|
||||||
return accum;
|
return accum;
|
||||||
@ -324,7 +324,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
rows: Range<u32>,
|
rows: Range<u32>,
|
||||||
) -> B
|
) -> B
|
||||||
where
|
where
|
||||||
Func: FnMut(B, D::Item<'w>) -> B,
|
Func: FnMut(B, D::Item<'w, 's>) -> B,
|
||||||
{
|
{
|
||||||
if archetype.is_empty() {
|
if archetype.is_empty() {
|
||||||
return accum;
|
return accum;
|
||||||
@ -492,7 +492,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
|
impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
for<'lw> L::Item<'lw>: Ord,
|
for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,
|
||||||
{
|
{
|
||||||
self.sort_impl::<L>(|keyed_query| keyed_query.sort())
|
self.sort_impl::<L>(|keyed_query| keyed_query.sort())
|
||||||
}
|
}
|
||||||
@ -549,7 +549,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
|
impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
for<'lw> L::Item<'lw>: Ord,
|
for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,
|
||||||
{
|
{
|
||||||
self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())
|
self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())
|
||||||
}
|
}
|
||||||
@ -605,7 +605,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn sort_by<L: ReadOnlyQueryData + 'w>(
|
pub fn sort_by<L: ReadOnlyQueryData + 'w>(
|
||||||
self,
|
self,
|
||||||
mut compare: impl FnMut(&L::Item<'_>, &L::Item<'_>) -> Ordering,
|
mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,
|
||||||
) -> QuerySortedIter<
|
) -> QuerySortedIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -637,7 +637,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
|
/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
|
||||||
pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(
|
pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(
|
||||||
self,
|
self,
|
||||||
mut compare: impl FnMut(&L::Item<'_>, &L::Item<'_>) -> Ordering,
|
mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,
|
||||||
) -> QuerySortedIter<
|
) -> QuerySortedIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -729,7 +729,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(
|
pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(
|
||||||
self,
|
self,
|
||||||
mut f: impl FnMut(&L::Item<'_>) -> K,
|
mut f: impl FnMut(&L::Item<'_, '_>) -> K,
|
||||||
) -> QuerySortedIter<
|
) -> QuerySortedIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -762,7 +762,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
|
/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
|
||||||
pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(
|
pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(
|
||||||
self,
|
self,
|
||||||
mut f: impl FnMut(&L::Item<'_>) -> K,
|
mut f: impl FnMut(&L::Item<'_, '_>) -> K,
|
||||||
) -> QuerySortedIter<
|
) -> QuerySortedIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -797,7 +797,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
|
/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
|
||||||
pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(
|
pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(
|
||||||
self,
|
self,
|
||||||
mut f: impl FnMut(&L::Item<'_>) -> K,
|
mut f: impl FnMut(&L::Item<'_, '_>) -> K,
|
||||||
) -> QuerySortedIter<
|
) -> QuerySortedIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -827,7 +827,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
|
/// This will panic if `next` has been called on `QueryIter` before, unless the underlying `Query` is empty.
|
||||||
fn sort_impl<L: ReadOnlyQueryData + 'w>(
|
fn sort_impl<L: ReadOnlyQueryData + 'w>(
|
||||||
self,
|
self,
|
||||||
f: impl FnOnce(&mut Vec<(L::Item<'_>, NeutralOrd<Entity>)>),
|
f: impl FnOnce(&mut Vec<(L::Item<'_, '_>, NeutralOrd<Entity>)>),
|
||||||
) -> QuerySortedIter<
|
) -> QuerySortedIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -856,7 +856,11 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
.map(|(key, entity)| (key, NeutralOrd(entity)))
|
.map(|(key, entity)| (key, NeutralOrd(entity)))
|
||||||
.collect();
|
.collect();
|
||||||
f(&mut keyed_query);
|
f(&mut keyed_query);
|
||||||
let entity_iter = keyed_query.into_iter().map(|(.., entity)| entity.0);
|
let entity_iter = keyed_query
|
||||||
|
.into_iter()
|
||||||
|
.map(|(.., entity)| entity.0)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into_iter();
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// `self.world` has permission to access the required components.
|
// `self.world` has permission to access the required components.
|
||||||
// Each lens query item is dropped before the respective actual query item is accessed.
|
// Each lens query item is dropped before the respective actual query item is accessed.
|
||||||
@ -873,7 +877,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, D, F> {
|
impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, D, F> {
|
||||||
type Item = D::Item<'w>;
|
type Item = D::Item<'w, 's>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@ -975,7 +979,7 @@ where
|
|||||||
entities: &'w Entities,
|
entities: &'w Entities,
|
||||||
tables: &'w Tables,
|
tables: &'w Tables,
|
||||||
archetypes: &'w Archetypes,
|
archetypes: &'w Archetypes,
|
||||||
fetch: D::Fetch<'w>,
|
fetch: D::Fetch<'w, 's>,
|
||||||
query_state: &'s QueryState<D, F>,
|
query_state: &'s QueryState<D, F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1010,7 +1014,7 @@ where
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
/// `entity` must stem from `self.entity_iter`, and not have been passed before.
|
/// `entity` must stem from `self.entity_iter`, and not have been passed before.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn fetch_next(&mut self, entity: Entity) -> D::Item<'w> {
|
unsafe fn fetch_next(&mut self, entity: Entity) -> D::Item<'w, 's> {
|
||||||
let (location, archetype, table);
|
let (location, archetype, table);
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// `tables` and `archetypes` belong to the same world that the [`QueryIter`]
|
// `tables` and `archetypes` belong to the same world that the [`QueryIter`]
|
||||||
@ -1048,7 +1052,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> Iterator
|
|||||||
where
|
where
|
||||||
I: Iterator<Item = Entity>,
|
I: Iterator<Item = Entity>,
|
||||||
{
|
{
|
||||||
type Item = D::Item<'w>;
|
type Item = D::Item<'w, 's>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@ -1119,8 +1123,8 @@ pub struct QueryManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item:
|
|||||||
entities: &'w Entities,
|
entities: &'w Entities,
|
||||||
tables: &'w Tables,
|
tables: &'w Tables,
|
||||||
archetypes: &'w Archetypes,
|
archetypes: &'w Archetypes,
|
||||||
fetch: D::Fetch<'w>,
|
fetch: D::Fetch<'w, 's>,
|
||||||
filter: F::Fetch<'w>,
|
filter: F::Fetch<'w, 's>,
|
||||||
query_state: &'s QueryState<D, F>,
|
query_state: &'s QueryState<D, F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1167,10 +1171,10 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
entities: &'w Entities,
|
entities: &'w Entities,
|
||||||
tables: &'w Tables,
|
tables: &'w Tables,
|
||||||
archetypes: &'w Archetypes,
|
archetypes: &'w Archetypes,
|
||||||
fetch: &mut D::Fetch<'w>,
|
fetch: &mut D::Fetch<'w, 's>,
|
||||||
filter: &mut F::Fetch<'w>,
|
filter: &mut F::Fetch<'w, 's>,
|
||||||
query_state: &'s QueryState<D, F>,
|
query_state: &'s QueryState<D, F>,
|
||||||
) -> Option<D::Item<'w>> {
|
) -> Option<D::Item<'w, 's>> {
|
||||||
for entity_borrow in entity_iter {
|
for entity_borrow in entity_iter {
|
||||||
let entity = entity_borrow.entity();
|
let entity = entity_borrow.entity();
|
||||||
let Some(location) = entities.get(entity) else {
|
let Some(location) = entities.get(entity) else {
|
||||||
@ -1212,7 +1216,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
|
|
||||||
/// Get next result from the query
|
/// Get next result from the query
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn fetch_next(&mut self) -> Option<D::Item<'_>> {
|
pub fn fetch_next(&mut self) -> Option<D::Item<'_, 's>> {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// All arguments stem from self.
|
// All arguments stem from self.
|
||||||
// We are limiting the returned reference to self,
|
// We are limiting the returned reference to self,
|
||||||
@ -1336,7 +1340,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
|
impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
for<'lw> L::Item<'lw>: Ord,
|
for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,
|
||||||
{
|
{
|
||||||
self.sort_impl::<L>(|keyed_query| keyed_query.sort())
|
self.sort_impl::<L>(|keyed_query| keyed_query.sort())
|
||||||
}
|
}
|
||||||
@ -1394,7 +1398,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
|
impl ExactSizeIterator<Item = Entity> + DoubleEndedIterator + FusedIterator + 'w,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
for<'lw> L::Item<'lw>: Ord,
|
for<'lw, 'ls> L::Item<'lw, 'ls>: Ord,
|
||||||
{
|
{
|
||||||
self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())
|
self.sort_impl::<L>(|keyed_query| keyed_query.sort_unstable())
|
||||||
}
|
}
|
||||||
@ -1451,7 +1455,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn sort_by<L: ReadOnlyQueryData + 'w>(
|
pub fn sort_by<L: ReadOnlyQueryData + 'w>(
|
||||||
self,
|
self,
|
||||||
mut compare: impl FnMut(&L::Item<'_>, &L::Item<'_>) -> Ordering,
|
mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,
|
||||||
) -> QuerySortedManyIter<
|
) -> QuerySortedManyIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -1482,7 +1486,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
/// called on [`QueryManyIter`] before.
|
/// called on [`QueryManyIter`] before.
|
||||||
pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(
|
pub fn sort_unstable_by<L: ReadOnlyQueryData + 'w>(
|
||||||
self,
|
self,
|
||||||
mut compare: impl FnMut(&L::Item<'_>, &L::Item<'_>) -> Ordering,
|
mut compare: impl FnMut(&L::Item<'_, '_>, &L::Item<'_, '_>) -> Ordering,
|
||||||
) -> QuerySortedManyIter<
|
) -> QuerySortedManyIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -1576,7 +1580,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(
|
pub fn sort_by_key<L: ReadOnlyQueryData + 'w, K>(
|
||||||
self,
|
self,
|
||||||
mut f: impl FnMut(&L::Item<'_>) -> K,
|
mut f: impl FnMut(&L::Item<'_, '_>) -> K,
|
||||||
) -> QuerySortedManyIter<
|
) -> QuerySortedManyIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -1608,7 +1612,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
/// called on [`QueryManyIter`] before.
|
/// called on [`QueryManyIter`] before.
|
||||||
pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(
|
pub fn sort_unstable_by_key<L: ReadOnlyQueryData + 'w, K>(
|
||||||
self,
|
self,
|
||||||
mut f: impl FnMut(&L::Item<'_>) -> K,
|
mut f: impl FnMut(&L::Item<'_, '_>) -> K,
|
||||||
) -> QuerySortedManyIter<
|
) -> QuerySortedManyIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -1642,7 +1646,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
/// called on [`QueryManyIter`] before.
|
/// called on [`QueryManyIter`] before.
|
||||||
pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(
|
pub fn sort_by_cached_key<L: ReadOnlyQueryData + 'w, K>(
|
||||||
self,
|
self,
|
||||||
mut f: impl FnMut(&L::Item<'_>) -> K,
|
mut f: impl FnMut(&L::Item<'_, '_>) -> K,
|
||||||
) -> QuerySortedManyIter<
|
) -> QuerySortedManyIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -1671,7 +1675,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>>
|
|||||||
/// called on [`QueryManyIter`] before.
|
/// called on [`QueryManyIter`] before.
|
||||||
fn sort_impl<L: ReadOnlyQueryData + 'w>(
|
fn sort_impl<L: ReadOnlyQueryData + 'w>(
|
||||||
self,
|
self,
|
||||||
f: impl FnOnce(&mut Vec<(L::Item<'_>, NeutralOrd<Entity>)>),
|
f: impl FnOnce(&mut Vec<(L::Item<'_, '_>, NeutralOrd<Entity>)>),
|
||||||
) -> QuerySortedManyIter<
|
) -> QuerySortedManyIter<
|
||||||
'w,
|
'w,
|
||||||
's,
|
's,
|
||||||
@ -1721,7 +1725,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item: EntityEq
|
|||||||
{
|
{
|
||||||
/// Get next result from the back of the query
|
/// Get next result from the back of the query
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn fetch_next_back(&mut self) -> Option<D::Item<'_>> {
|
pub fn fetch_next_back(&mut self) -> Option<D::Item<'_, 's>> {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// All arguments stem from self.
|
// All arguments stem from self.
|
||||||
// We are limiting the returned reference to self,
|
// We are limiting the returned reference to self,
|
||||||
@ -1745,7 +1749,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item: EntityEq
|
|||||||
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>> Iterator
|
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item: EntityEquivalent>> Iterator
|
||||||
for QueryManyIter<'w, 's, D, F, I>
|
for QueryManyIter<'w, 's, D, F, I>
|
||||||
{
|
{
|
||||||
type Item = D::Item<'w>;
|
type Item = D::Item<'w, 's>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@ -1861,7 +1865,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator>
|
|||||||
impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> Iterator
|
impl<'w, 's, D: QueryData, F: QueryFilter, I: EntitySetIterator> Iterator
|
||||||
for QueryManyUniqueIter<'w, 's, D, F, I>
|
for QueryManyUniqueIter<'w, 's, D, F, I>
|
||||||
{
|
{
|
||||||
type Item = D::Item<'w>;
|
type Item = D::Item<'w, 's>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@ -1915,7 +1919,7 @@ pub struct QuerySortedManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator
|
|||||||
entities: &'w Entities,
|
entities: &'w Entities,
|
||||||
tables: &'w Tables,
|
tables: &'w Tables,
|
||||||
archetypes: &'w Archetypes,
|
archetypes: &'w Archetypes,
|
||||||
fetch: D::Fetch<'w>,
|
fetch: D::Fetch<'w, 's>,
|
||||||
query_state: &'s QueryState<D, F>,
|
query_state: &'s QueryState<D, F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1954,7 +1958,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>>
|
|||||||
/// It is always safe for shared access.
|
/// It is always safe for shared access.
|
||||||
/// `entity` must stem from `self.entity_iter`, and not have been passed before.
|
/// `entity` must stem from `self.entity_iter`, and not have been passed before.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn fetch_next_aliased_unchecked(&mut self, entity: Entity) -> D::Item<'w> {
|
unsafe fn fetch_next_aliased_unchecked(&mut self, entity: Entity) -> D::Item<'w, 's> {
|
||||||
let (location, archetype, table);
|
let (location, archetype, table);
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// `tables` and `archetypes` belong to the same world that the [`QueryIter`]
|
// `tables` and `archetypes` belong to the same world that the [`QueryIter`]
|
||||||
@ -1988,7 +1992,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item = Entity>>
|
|||||||
|
|
||||||
/// Get next result from the query
|
/// Get next result from the query
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn fetch_next(&mut self) -> Option<D::Item<'_>> {
|
pub fn fetch_next(&mut self) -> Option<D::Item<'_, 's>> {
|
||||||
let entity = self.entity_iter.next()?;
|
let entity = self.entity_iter.next()?;
|
||||||
|
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
@ -2007,7 +2011,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item = Entity>
|
|||||||
{
|
{
|
||||||
/// Get next result from the query
|
/// Get next result from the query
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn fetch_next_back(&mut self) -> Option<D::Item<'_>> {
|
pub fn fetch_next_back(&mut self) -> Option<D::Item<'_, 's>> {
|
||||||
let entity = self.entity_iter.next_back()?;
|
let entity = self.entity_iter.next_back()?;
|
||||||
|
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
@ -2024,7 +2028,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: DoubleEndedIterator<Item = Entity>
|
|||||||
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item = Entity>> Iterator
|
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator<Item = Entity>> Iterator
|
||||||
for QuerySortedManyIter<'w, 's, D, F, I>
|
for QuerySortedManyIter<'w, 's, D, F, I>
|
||||||
{
|
{
|
||||||
type Item = D::Item<'w>;
|
type Item = D::Item<'w, 's>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@ -2185,7 +2189,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
|
|||||||
/// .
|
/// .
|
||||||
/// It is always safe for shared access.
|
/// It is always safe for shared access.
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<[D::Item<'w>; K]> {
|
unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<[D::Item<'w, 's>; K]> {
|
||||||
// PERF: can speed up the following code using `cursor.remaining()` instead of `next_item.is_none()`
|
// PERF: can speed up the following code using `cursor.remaining()` instead of `next_item.is_none()`
|
||||||
// when D::IS_ARCHETYPAL && F::IS_ARCHETYPAL
|
// when D::IS_ARCHETYPAL && F::IS_ARCHETYPAL
|
||||||
//
|
//
|
||||||
@ -2211,9 +2215,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut values = MaybeUninit::<[D::Item<'w>; K]>::uninit();
|
let mut values = MaybeUninit::<[D::Item<'w, 's>; K]>::uninit();
|
||||||
|
|
||||||
let ptr = values.as_mut_ptr().cast::<D::Item<'w>>();
|
let ptr = values.as_mut_ptr().cast::<D::Item<'w, 's>>();
|
||||||
for (offset, cursor) in self.cursors.iter_mut().enumerate() {
|
for (offset, cursor) in self.cursors.iter_mut().enumerate() {
|
||||||
ptr.add(offset).write(cursor.peek_last().unwrap());
|
ptr.add(offset).write(cursor.peek_last().unwrap());
|
||||||
}
|
}
|
||||||
@ -2223,7 +2227,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
|
|||||||
|
|
||||||
/// Get next combination of queried components
|
/// Get next combination of queried components
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fetch_next(&mut self) -> Option<[D::Item<'_>; K]> {
|
pub fn fetch_next(&mut self) -> Option<[D::Item<'_, 's>; K]> {
|
||||||
// SAFETY: we are limiting the returned reference to self,
|
// SAFETY: we are limiting the returned reference to self,
|
||||||
// making sure this method cannot be called multiple times without getting rid
|
// making sure this method cannot be called multiple times without getting rid
|
||||||
// of any previously returned unique references first, thus preventing aliasing.
|
// of any previously returned unique references first, thus preventing aliasing.
|
||||||
@ -2240,7 +2244,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
|
|||||||
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> Iterator
|
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> Iterator
|
||||||
for QueryCombinationIter<'w, 's, D, F, K>
|
for QueryCombinationIter<'w, 's, D, F, K>
|
||||||
{
|
{
|
||||||
type Item = [D::Item<'w>; K];
|
type Item = [D::Item<'w, 's>; K];
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@ -2309,8 +2313,8 @@ struct QueryIterationCursor<'w, 's, D: QueryData, F: QueryFilter> {
|
|||||||
storage_id_iter: core::slice::Iter<'s, StorageId>,
|
storage_id_iter: core::slice::Iter<'s, StorageId>,
|
||||||
table_entities: &'w [Entity],
|
table_entities: &'w [Entity],
|
||||||
archetype_entities: &'w [ArchetypeEntity],
|
archetype_entities: &'w [ArchetypeEntity],
|
||||||
fetch: D::Fetch<'w>,
|
fetch: D::Fetch<'w, 's>,
|
||||||
filter: F::Fetch<'w>,
|
filter: F::Fetch<'w, 's>,
|
||||||
// length of the table or length of the archetype, depending on whether both `D`'s and `F`'s fetches are dense
|
// length of the table or length of the archetype, depending on whether both `D`'s and `F`'s fetches are dense
|
||||||
current_len: u32,
|
current_len: u32,
|
||||||
// either table row or archetype index, depending on whether both `D`'s and `F`'s fetches are dense
|
// either table row or archetype index, depending on whether both `D`'s and `F`'s fetches are dense
|
||||||
@ -2390,7 +2394,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
|||||||
/// The result of `next` and any previous calls to `peek_last` with this row must have been
|
/// The result of `next` and any previous calls to `peek_last` with this row must have been
|
||||||
/// dropped to prevent aliasing mutable references.
|
/// dropped to prevent aliasing mutable references.
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn peek_last(&mut self) -> Option<D::Item<'w>> {
|
unsafe fn peek_last(&mut self) -> Option<D::Item<'w, 's>> {
|
||||||
if self.current_row > 0 {
|
if self.current_row > 0 {
|
||||||
let index = self.current_row - 1;
|
let index = self.current_row - 1;
|
||||||
if self.is_dense {
|
if self.is_dense {
|
||||||
@ -2457,7 +2461,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
|||||||
tables: &'w Tables,
|
tables: &'w Tables,
|
||||||
archetypes: &'w Archetypes,
|
archetypes: &'w Archetypes,
|
||||||
query_state: &'s QueryState<D, F>,
|
query_state: &'s QueryState<D, F>,
|
||||||
) -> Option<D::Item<'w>> {
|
) -> Option<D::Item<'w, 's>> {
|
||||||
if self.is_dense {
|
if self.is_dense {
|
||||||
loop {
|
loop {
|
||||||
// we are on the beginning of the query, or finished processing a table, so skip to the next
|
// we are on the beginning of the query, or finished processing a table, so skip to the next
|
||||||
|
@ -819,34 +819,37 @@ mod tests {
|
|||||||
/// SAFETY:
|
/// SAFETY:
|
||||||
/// `update_component_access` adds resource read access for `R`.
|
/// `update_component_access` adds resource read access for `R`.
|
||||||
unsafe impl WorldQuery for ReadsRData {
|
unsafe impl WorldQuery for ReadsRData {
|
||||||
type Fetch<'w> = ();
|
type Fetch<'w, 's> = ();
|
||||||
type State = ComponentId;
|
type State = ComponentId;
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
_: Self::Fetch<'wlong, 's>,
|
||||||
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn init_fetch<'w>(
|
unsafe fn init_fetch<'w, 's>(
|
||||||
_world: UnsafeWorldCell<'w>,
|
_world: UnsafeWorldCell<'w>,
|
||||||
_state: &Self::State,
|
_state: &'s Self::State,
|
||||||
_last_run: Tick,
|
_last_run: Tick,
|
||||||
_this_run: Tick,
|
_this_run: Tick,
|
||||||
) -> Self::Fetch<'w> {
|
) -> Self::Fetch<'w, 's> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const IS_DENSE: bool = true;
|
const IS_DENSE: bool = true;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
_fetch: &mut Self::Fetch<'w>,
|
_fetch: &mut Self::Fetch<'w, 's>,
|
||||||
_state: &Self::State,
|
_state: &'s Self::State,
|
||||||
_archetype: &'w Archetype,
|
_archetype: &'w Archetype,
|
||||||
_table: &Table,
|
_table: &Table,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_table<'w>(
|
unsafe fn set_table<'w, 's>(
|
||||||
_fetch: &mut Self::Fetch<'w>,
|
_fetch: &mut Self::Fetch<'w, 's>,
|
||||||
_state: &Self::State,
|
_state: &'s Self::State,
|
||||||
_table: &'w Table,
|
_table: &'w Table,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
@ -882,16 +885,19 @@ mod tests {
|
|||||||
unsafe impl QueryData for ReadsRData {
|
unsafe impl QueryData for ReadsRData {
|
||||||
const IS_READ_ONLY: bool = true;
|
const IS_READ_ONLY: bool = true;
|
||||||
type ReadOnly = Self;
|
type ReadOnly = Self;
|
||||||
type Item<'w> = ();
|
type Item<'w, 's> = ();
|
||||||
|
|
||||||
fn shrink<'wlong: 'wshort, 'wshort>(_item: Self::Item<'wlong>) -> Self::Item<'wshort> {}
|
fn shrink<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
_item: Self::Item<'wlong, 's>,
|
||||||
|
) -> Self::Item<'wshort, 's> {
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn fetch<'w>(
|
unsafe fn fetch<'w, 's>(
|
||||||
_fetch: &mut Self::Fetch<'w>,
|
_fetch: &mut Self::Fetch<'w, 's>,
|
||||||
_entity: Entity,
|
_entity: Entity,
|
||||||
_table_row: TableRow,
|
_table_row: TableRow,
|
||||||
) -> Self::Item<'w> {
|
) -> Self::Item<'w, 's> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryParIter<'w, 's, D, F> {
|
|||||||
///
|
///
|
||||||
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn for_each<FN: Fn(QueryItem<'w, D>) + Send + Sync + Clone>(self, func: FN) {
|
pub fn for_each<FN: Fn(QueryItem<'w, 's, D>) + Send + Sync + Clone>(self, func: FN) {
|
||||||
self.for_each_init(|| {}, |_, item| func(item));
|
self.for_each_init(|| {}, |_, item| func(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryParIter<'w, 's, D, F> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn for_each_init<FN, INIT, T>(self, init: INIT, func: FN)
|
pub fn for_each_init<FN, INIT, T>(self, init: INIT, func: FN)
|
||||||
where
|
where
|
||||||
FN: Fn(&mut T, QueryItem<'w, D>) + Send + Sync + Clone,
|
FN: Fn(&mut T, QueryItem<'w, 's, D>) + Send + Sync + Clone,
|
||||||
INIT: Fn() -> T + Sync + Send + Clone,
|
INIT: Fn() -> T + Sync + Send + Clone,
|
||||||
{
|
{
|
||||||
let func = |mut init, item| {
|
let func = |mut init, item| {
|
||||||
@ -190,7 +190,7 @@ impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, E: EntityEquivalent + Sync>
|
|||||||
///
|
///
|
||||||
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn for_each<FN: Fn(QueryItem<'w, D>) + Send + Sync + Clone>(self, func: FN) {
|
pub fn for_each<FN: Fn(QueryItem<'w, 's, D>) + Send + Sync + Clone>(self, func: FN) {
|
||||||
self.for_each_init(|| {}, |_, item| func(item));
|
self.for_each_init(|| {}, |_, item| func(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, E: EntityEquivalent + Sync>
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn for_each_init<FN, INIT, T>(self, init: INIT, func: FN)
|
pub fn for_each_init<FN, INIT, T>(self, init: INIT, func: FN)
|
||||||
where
|
where
|
||||||
FN: Fn(&mut T, QueryItem<'w, D>) + Send + Sync + Clone,
|
FN: Fn(&mut T, QueryItem<'w, 's, D>) + Send + Sync + Clone,
|
||||||
INIT: Fn() -> T + Sync + Send + Clone,
|
INIT: Fn() -> T + Sync + Send + Clone,
|
||||||
{
|
{
|
||||||
let func = |mut init, item| {
|
let func = |mut init, item| {
|
||||||
@ -345,7 +345,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, E: EntityEquivalent + Sync>
|
|||||||
///
|
///
|
||||||
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn for_each<FN: Fn(QueryItem<'w, D>) + Send + Sync + Clone>(self, func: FN) {
|
pub fn for_each<FN: Fn(QueryItem<'w, 's, D>) + Send + Sync + Clone>(self, func: FN) {
|
||||||
self.for_each_init(|| {}, |_, item| func(item));
|
self.for_each_init(|| {}, |_, item| func(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, E: EntityEquivalent + Sync>
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn for_each_init<FN, INIT, T>(self, init: INIT, func: FN)
|
pub fn for_each_init<FN, INIT, T>(self, init: INIT, func: FN)
|
||||||
where
|
where
|
||||||
FN: Fn(&mut T, QueryItem<'w, D>) + Send + Sync + Clone,
|
FN: Fn(&mut T, QueryItem<'w, 's, D>) + Send + Sync + Clone,
|
||||||
INIT: Fn() -> T + Sync + Send + Clone,
|
INIT: Fn() -> T + Sync + Send + Clone,
|
||||||
{
|
{
|
||||||
let func = |mut init, item| {
|
let func = |mut init, item| {
|
||||||
|
@ -845,13 +845,17 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
///
|
///
|
||||||
/// This can only be called for read-only queries, see [`Self::get_mut`] for write-queries.
|
/// This can only be called for read-only queries, see [`Self::get_mut`] for write-queries.
|
||||||
///
|
///
|
||||||
|
/// If you need to get multiple items at once but get borrowing errors,
|
||||||
|
/// consider using [`Self::update_archetypes`] followed by multiple [`Self::get_manual`] calls,
|
||||||
|
/// or making a single call with [`Self::get_many`] or [`Self::iter_many`].
|
||||||
|
///
|
||||||
/// This is always guaranteed to run in `O(1)` time.
|
/// This is always guaranteed to run in `O(1)` time.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get<'w>(
|
pub fn get<'w>(
|
||||||
&mut self,
|
&mut self,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> Result<ROQueryItem<'w, D>, QueryEntityError> {
|
) -> Result<ROQueryItem<'w, '_, D>, QueryEntityError> {
|
||||||
self.query(world).get_inner(entity)
|
self.query(world).get_inner(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,7 +896,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
entities: [Entity; N],
|
entities: [Entity; N],
|
||||||
) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError> {
|
) -> Result<[ROQueryItem<'w, '_, D>; N], QueryEntityError> {
|
||||||
self.query(world).get_many_inner(entities)
|
self.query(world).get_many_inner(entities)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,7 +934,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
entities: UniqueEntityArray<N>,
|
entities: UniqueEntityArray<N>,
|
||||||
) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError> {
|
) -> Result<[ROQueryItem<'w, '_, D>; N], QueryEntityError> {
|
||||||
self.query(world).get_many_unique_inner(entities)
|
self.query(world).get_many_unique_inner(entities)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,7 +946,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
world: &'w mut World,
|
world: &'w mut World,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> Result<D::Item<'w>, QueryEntityError> {
|
) -> Result<D::Item<'w, '_>, QueryEntityError> {
|
||||||
self.query_mut(world).get_inner(entity)
|
self.query_mut(world).get_inner(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,7 +993,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
world: &'w mut World,
|
world: &'w mut World,
|
||||||
entities: [Entity; N],
|
entities: [Entity; N],
|
||||||
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
) -> Result<[D::Item<'w, '_>; N], QueryEntityError> {
|
||||||
self.query_mut(world).get_many_mut_inner(entities)
|
self.query_mut(world).get_many_mut_inner(entities)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1034,7 +1038,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
world: &'w mut World,
|
world: &'w mut World,
|
||||||
entities: UniqueEntityArray<N>,
|
entities: UniqueEntityArray<N>,
|
||||||
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
) -> Result<[D::Item<'w, '_>; N], QueryEntityError> {
|
||||||
self.query_mut(world).get_many_unique_inner(entities)
|
self.query_mut(world).get_many_unique_inner(entities)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1056,7 +1060,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
&self,
|
&self,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> Result<ROQueryItem<'w, D>, QueryEntityError> {
|
) -> Result<ROQueryItem<'w, '_, D>, QueryEntityError> {
|
||||||
self.query_manual(world).get_inner(entity)
|
self.query_manual(world).get_inner(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1073,13 +1077,16 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> Result<D::Item<'w>, QueryEntityError> {
|
) -> Result<D::Item<'w, '_>, QueryEntityError> {
|
||||||
self.query_unchecked(world).get_inner(entity)
|
self.query_unchecked(world).get_inner(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an [`Iterator`] over the query results for the given [`World`].
|
/// Returns an [`Iterator`] over the query results for the given [`World`].
|
||||||
///
|
///
|
||||||
/// This can only be called for read-only queries, see [`Self::iter_mut`] for write-queries.
|
/// This can only be called for read-only queries, see [`Self::iter_mut`] for write-queries.
|
||||||
|
///
|
||||||
|
/// If you need to iterate multiple times at once but get borrowing errors,
|
||||||
|
/// consider using [`Self::update_archetypes`] followed by multiple [`Self::iter_manual`] calls.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter<'w, 's>(&'s mut self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {
|
pub fn iter<'w, 's>(&'s mut self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {
|
||||||
self.query(world).into_iter()
|
self.query(world).into_iter()
|
||||||
@ -1168,6 +1175,9 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
/// Items are returned in the order of the list of entities.
|
/// Items are returned in the order of the list of entities.
|
||||||
/// Entities that don't match the query are skipped.
|
/// Entities that don't match the query are skipped.
|
||||||
///
|
///
|
||||||
|
/// If you need to iterate multiple times at once but get borrowing errors,
|
||||||
|
/// consider using [`Self::update_archetypes`] followed by multiple [`Self::iter_many_manual`] calls.
|
||||||
|
///
|
||||||
/// # See also
|
/// # See also
|
||||||
///
|
///
|
||||||
/// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items.
|
/// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items.
|
||||||
@ -1387,8 +1397,8 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
///
|
///
|
||||||
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
|
||||||
pub(crate) unsafe fn par_fold_init_unchecked_manual<'w, T, FN, INIT>(
|
pub(crate) unsafe fn par_fold_init_unchecked_manual<'w, 's, T, FN, INIT>(
|
||||||
&self,
|
&'s self,
|
||||||
init_accum: INIT,
|
init_accum: INIT,
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
batch_size: u32,
|
batch_size: u32,
|
||||||
@ -1396,7 +1406,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) where
|
) where
|
||||||
FN: Fn(T, D::Item<'w>) -> T + Send + Sync + Clone,
|
FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,
|
||||||
INIT: Fn() -> T + Sync + Send + Clone,
|
INIT: Fn() -> T + Sync + Send + Clone,
|
||||||
{
|
{
|
||||||
// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
|
// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
|
||||||
@ -1501,8 +1511,8 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
///
|
///
|
||||||
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
|
||||||
pub(crate) unsafe fn par_many_unique_fold_init_unchecked_manual<'w, T, FN, INIT, E>(
|
pub(crate) unsafe fn par_many_unique_fold_init_unchecked_manual<'w, 's, T, FN, INIT, E>(
|
||||||
&self,
|
&'s self,
|
||||||
init_accum: INIT,
|
init_accum: INIT,
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
entity_list: &UniqueEntityEquivalentSlice<E>,
|
entity_list: &UniqueEntityEquivalentSlice<E>,
|
||||||
@ -1511,7 +1521,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) where
|
) where
|
||||||
FN: Fn(T, D::Item<'w>) -> T + Send + Sync + Clone,
|
FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,
|
||||||
INIT: Fn() -> T + Sync + Send + Clone,
|
INIT: Fn() -> T + Sync + Send + Clone,
|
||||||
E: EntityEquivalent + Sync,
|
E: EntityEquivalent + Sync,
|
||||||
{
|
{
|
||||||
@ -1564,8 +1574,8 @@ impl<D: ReadOnlyQueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
///
|
///
|
||||||
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
|
||||||
pub(crate) unsafe fn par_many_fold_init_unchecked_manual<'w, T, FN, INIT, E>(
|
pub(crate) unsafe fn par_many_fold_init_unchecked_manual<'w, 's, T, FN, INIT, E>(
|
||||||
&self,
|
&'s self,
|
||||||
init_accum: INIT,
|
init_accum: INIT,
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
entity_list: &[E],
|
entity_list: &[E],
|
||||||
@ -1574,7 +1584,7 @@ impl<D: ReadOnlyQueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) where
|
) where
|
||||||
FN: Fn(T, D::Item<'w>) -> T + Send + Sync + Clone,
|
FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,
|
||||||
INIT: Fn() -> T + Sync + Send + Clone,
|
INIT: Fn() -> T + Sync + Send + Clone,
|
||||||
E: EntityEquivalent + Sync,
|
E: EntityEquivalent + Sync,
|
||||||
{
|
{
|
||||||
@ -1686,7 +1696,10 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
///
|
///
|
||||||
/// Simply unwrapping the [`Result`] also works, but should generally be reserved for tests.
|
/// Simply unwrapping the [`Result`] also works, but should generally be reserved for tests.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn single<'w>(&mut self, world: &'w World) -> Result<ROQueryItem<'w, D>, QuerySingleError> {
|
pub fn single<'w>(
|
||||||
|
&mut self,
|
||||||
|
world: &'w World,
|
||||||
|
) -> Result<ROQueryItem<'w, '_, D>, QuerySingleError> {
|
||||||
self.query(world).single_inner()
|
self.query(world).single_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1703,7 +1716,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
pub fn single_mut<'w>(
|
pub fn single_mut<'w>(
|
||||||
&mut self,
|
&mut self,
|
||||||
world: &'w mut World,
|
world: &'w mut World,
|
||||||
) -> Result<D::Item<'w>, QuerySingleError> {
|
) -> Result<D::Item<'w, '_>, QuerySingleError> {
|
||||||
self.query_mut(world).single_inner()
|
self.query_mut(world).single_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1720,7 +1733,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
pub unsafe fn single_unchecked<'w>(
|
pub unsafe fn single_unchecked<'w>(
|
||||||
&mut self,
|
&mut self,
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
) -> Result<D::Item<'w>, QuerySingleError> {
|
) -> Result<D::Item<'w, '_>, QuerySingleError> {
|
||||||
self.query_unchecked(world).single_inner()
|
self.query_unchecked(world).single_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1742,7 +1755,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
|||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) -> Result<D::Item<'w>, QuerySingleError> {
|
) -> Result<D::Item<'w, '_>, QuerySingleError> {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// - The caller ensured we have the correct access to the world.
|
// - The caller ensured we have the correct access to the world.
|
||||||
// - The caller ensured that the world matches.
|
// - The caller ensured that the world matches.
|
||||||
|
@ -42,7 +42,7 @@ use variadics_please::all_tuples;
|
|||||||
/// [`QueryFilter`]: crate::query::QueryFilter
|
/// [`QueryFilter`]: crate::query::QueryFilter
|
||||||
pub unsafe trait WorldQuery {
|
pub unsafe trait WorldQuery {
|
||||||
/// Per archetype/table state retrieved by this [`WorldQuery`] to compute [`Self::Item`](crate::query::QueryData::Item) for each entity.
|
/// Per archetype/table state retrieved by this [`WorldQuery`] to compute [`Self::Item`](crate::query::QueryData::Item) for each entity.
|
||||||
type Fetch<'a>: Clone;
|
type Fetch<'w, 's>: Clone;
|
||||||
|
|
||||||
/// State used to construct a [`Self::Fetch`](WorldQuery::Fetch). This will be cached inside [`QueryState`](crate::query::QueryState),
|
/// State used to construct a [`Self::Fetch`](WorldQuery::Fetch). This will be cached inside [`QueryState`](crate::query::QueryState),
|
||||||
/// so it is best to move as much data / computation here as possible to reduce the cost of
|
/// so it is best to move as much data / computation here as possible to reduce the cost of
|
||||||
@ -50,7 +50,9 @@ pub unsafe trait WorldQuery {
|
|||||||
type State: Send + Sync + Sized;
|
type State: Send + Sync + Sized;
|
||||||
|
|
||||||
/// This function manually implements subtyping for the query fetches.
|
/// This function manually implements subtyping for the query fetches.
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort>;
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
fetch: Self::Fetch<'wlong, 's>,
|
||||||
|
) -> Self::Fetch<'wshort, 's>;
|
||||||
|
|
||||||
/// Creates a new instance of [`Self::Fetch`](WorldQuery::Fetch),
|
/// Creates a new instance of [`Self::Fetch`](WorldQuery::Fetch),
|
||||||
/// by combining data from the [`World`] with the cached [`Self::State`](WorldQuery::State).
|
/// by combining data from the [`World`] with the cached [`Self::State`](WorldQuery::State).
|
||||||
@ -62,12 +64,12 @@ pub unsafe trait WorldQuery {
|
|||||||
/// in to this function.
|
/// in to this function.
|
||||||
/// - `world` must have the **right** to access any access registered in `update_component_access`.
|
/// - `world` must have the **right** to access any access registered in `update_component_access`.
|
||||||
/// - There must not be simultaneous resource access conflicting with readonly resource access registered in [`WorldQuery::update_component_access`].
|
/// - There must not be simultaneous resource access conflicting with readonly resource access registered in [`WorldQuery::update_component_access`].
|
||||||
unsafe fn init_fetch<'w>(
|
unsafe fn init_fetch<'w, 's>(
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
state: &Self::State,
|
state: &'s Self::State,
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) -> Self::Fetch<'w>;
|
) -> Self::Fetch<'w, 's>;
|
||||||
|
|
||||||
/// Returns true if (and only if) every table of every archetype matched by this fetch contains
|
/// Returns true if (and only if) every table of every archetype matched by this fetch contains
|
||||||
/// all of the matched components.
|
/// all of the matched components.
|
||||||
@ -87,9 +89,9 @@ pub unsafe trait WorldQuery {
|
|||||||
/// - `archetype` and `tables` must be from the same [`World`] that [`WorldQuery::init_state`] was called on.
|
/// - `archetype` and `tables` must be from the same [`World`] that [`WorldQuery::init_state`] was called on.
|
||||||
/// - `table` must correspond to `archetype`.
|
/// - `table` must correspond to `archetype`.
|
||||||
/// - `state` must be the [`State`](Self::State) that `fetch` was initialized with.
|
/// - `state` must be the [`State`](Self::State) that `fetch` was initialized with.
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
state: &Self::State,
|
state: &'s Self::State,
|
||||||
archetype: &'w Archetype,
|
archetype: &'w Archetype,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
);
|
);
|
||||||
@ -101,7 +103,11 @@ pub unsafe trait WorldQuery {
|
|||||||
///
|
///
|
||||||
/// - `table` must be from the same [`World`] that [`WorldQuery::init_state`] was called on.
|
/// - `table` must be from the same [`World`] that [`WorldQuery::init_state`] was called on.
|
||||||
/// - `state` must be the [`State`](Self::State) that `fetch` was initialized with.
|
/// - `state` must be the [`State`](Self::State) that `fetch` was initialized with.
|
||||||
unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table);
|
unsafe fn set_table<'w, 's>(
|
||||||
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
|
state: &'s Self::State,
|
||||||
|
table: &'w Table,
|
||||||
|
);
|
||||||
|
|
||||||
/// Adds any component accesses used by this [`WorldQuery`] to `access`.
|
/// Adds any component accesses used by this [`WorldQuery`] to `access`.
|
||||||
///
|
///
|
||||||
@ -154,11 +160,11 @@ macro_rules! impl_tuple_world_query {
|
|||||||
/// `update_component_access` adds all `With` and `Without` filters from the subqueries.
|
/// `update_component_access` adds all `With` and `Without` filters from the subqueries.
|
||||||
/// This is sound because `matches_component_set` always returns `false` if any the subqueries' implementations return `false`.
|
/// This is sound because `matches_component_set` always returns `false` if any the subqueries' implementations return `false`.
|
||||||
unsafe impl<$($name: WorldQuery),*> WorldQuery for ($($name,)*) {
|
unsafe impl<$($name: WorldQuery),*> WorldQuery for ($($name,)*) {
|
||||||
type Fetch<'w> = ($($name::Fetch<'w>,)*);
|
type Fetch<'w, 's> = ($($name::Fetch<'w, 's>,)*);
|
||||||
type State = ($($name::State,)*);
|
type State = ($($name::State,)*);
|
||||||
|
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(fetch: Self::Fetch<'wlong, 's>) -> Self::Fetch<'wshort, 's> {
|
||||||
let ($($name,)*) = fetch;
|
let ($($name,)*) = fetch;
|
||||||
($(
|
($(
|
||||||
$name::shrink_fetch($name),
|
$name::shrink_fetch($name),
|
||||||
@ -166,7 +172,7 @@ macro_rules! impl_tuple_world_query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch<'w>(world: UnsafeWorldCell<'w>, state: &Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w> {
|
unsafe fn init_fetch<'w, 's>(world: UnsafeWorldCell<'w>, state: &'s Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w, 's> {
|
||||||
let ($($name,)*) = state;
|
let ($($name,)*) = state;
|
||||||
// SAFETY: The invariants are upheld by the caller.
|
// SAFETY: The invariants are upheld by the caller.
|
||||||
($(unsafe { $name::init_fetch(world, $name, last_run, this_run) },)*)
|
($(unsafe { $name::init_fetch(world, $name, last_run, this_run) },)*)
|
||||||
@ -175,9 +181,9 @@ macro_rules! impl_tuple_world_query {
|
|||||||
const IS_DENSE: bool = true $(&& $name::IS_DENSE)*;
|
const IS_DENSE: bool = true $(&& $name::IS_DENSE)*;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
state: &Self::State,
|
state: &'s Self::State,
|
||||||
archetype: &'w Archetype,
|
archetype: &'w Archetype,
|
||||||
table: &'w Table
|
table: &'w Table
|
||||||
) {
|
) {
|
||||||
@ -188,7 +194,7 @@ macro_rules! impl_tuple_world_query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
|
unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w, 's>, state: &'s Self::State, table: &'w Table) {
|
||||||
let ($($name,)*) = fetch;
|
let ($($name,)*) = fetch;
|
||||||
let ($($state,)*) = state;
|
let ($($state,)*) = state;
|
||||||
// SAFETY: The invariants are upheld by the caller.
|
// SAFETY: The invariants are upheld by the caller.
|
||||||
|
@ -14,7 +14,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
/// target entity of that relationship.
|
/// target entity of that relationship.
|
||||||
pub fn related<R: Relationship>(&'w self, entity: Entity) -> Option<Entity>
|
pub fn related<R: Relationship>(&'w self, entity: Entity) -> Option<Entity>
|
||||||
where
|
where
|
||||||
<D as QueryData>::ReadOnly: QueryData<Item<'w> = &'w R>,
|
<D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = &'w R>,
|
||||||
{
|
{
|
||||||
self.get(entity).map(R::get).ok()
|
self.get(entity).map(R::get).ok()
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> impl Iterator<Item = Entity> + 'w
|
) -> impl Iterator<Item = Entity> + 'w
|
||||||
where
|
where
|
||||||
<D as QueryData>::ReadOnly: QueryData<Item<'w> = &'w S>,
|
<D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
{
|
{
|
||||||
self.get(entity)
|
self.get(entity)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -42,7 +42,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
/// If your relationship is not a tree (like Bevy's hierarchy), be sure to stop if you encounter a duplicate entity.
|
/// If your relationship is not a tree (like Bevy's hierarchy), be sure to stop if you encounter a duplicate entity.
|
||||||
pub fn root_ancestor<R: Relationship>(&'w self, entity: Entity) -> Entity
|
pub fn root_ancestor<R: Relationship>(&'w self, entity: Entity) -> Entity
|
||||||
where
|
where
|
||||||
<D as QueryData>::ReadOnly: QueryData<Item<'w> = &'w R>,
|
<D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = &'w R>,
|
||||||
{
|
{
|
||||||
// Recursively search up the tree until we're out of parents
|
// Recursively search up the tree until we're out of parents
|
||||||
match self.get(entity) {
|
match self.get(entity) {
|
||||||
@ -60,9 +60,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn iter_leaves<S: RelationshipTarget>(
|
pub fn iter_leaves<S: RelationshipTarget>(
|
||||||
&'w self,
|
&'w self,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> impl Iterator<Item = Entity> + 'w
|
) -> impl Iterator<Item = Entity> + use<'w, 's, S, D, F>
|
||||||
where
|
where
|
||||||
<D as QueryData>::ReadOnly: QueryData<Item<'w> = &'w S>,
|
<D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
SourceIter<'w, S>: DoubleEndedIterator,
|
SourceIter<'w, S>: DoubleEndedIterator,
|
||||||
{
|
{
|
||||||
self.iter_descendants_depth_first(entity).filter(|entity| {
|
self.iter_descendants_depth_first(entity).filter(|entity| {
|
||||||
@ -80,7 +80,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> impl Iterator<Item = Entity> + 'w
|
) -> impl Iterator<Item = Entity> + 'w
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = (Option<&'w R>, Option<&'w R::RelationshipTarget>)>,
|
D::ReadOnly: QueryData<Item<'w, 's> = (Option<&'w R>, Option<&'w R::RelationshipTarget>)>,
|
||||||
{
|
{
|
||||||
self.get(entity)
|
self.get(entity)
|
||||||
.ok()
|
.ok()
|
||||||
@ -103,7 +103,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> DescendantIter<'w, 's, D, F, S>
|
) -> DescendantIter<'w, 's, D, F, S>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
{
|
{
|
||||||
DescendantIter::new(self, entity)
|
DescendantIter::new(self, entity)
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> DescendantDepthFirstIter<'w, 's, D, F, S>
|
) -> DescendantDepthFirstIter<'w, 's, D, F, S>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
SourceIter<'w, S>: DoubleEndedIterator,
|
SourceIter<'w, S>: DoubleEndedIterator,
|
||||||
{
|
{
|
||||||
DescendantDepthFirstIter::new(self, entity)
|
DescendantDepthFirstIter::new(self, entity)
|
||||||
@ -137,7 +137,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
) -> AncestorIter<'w, 's, D, F, R>
|
) -> AncestorIter<'w, 's, D, F, R>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w R>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w R>,
|
||||||
{
|
{
|
||||||
AncestorIter::new(self, entity)
|
AncestorIter::new(self, entity)
|
||||||
}
|
}
|
||||||
@ -148,7 +148,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
/// Traverses the hierarchy breadth-first.
|
/// Traverses the hierarchy breadth-first.
|
||||||
pub struct DescendantIter<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
pub struct DescendantIter<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
{
|
{
|
||||||
children_query: &'w Query<'w, 's, D, F>,
|
children_query: &'w Query<'w, 's, D, F>,
|
||||||
vecdeque: VecDeque<Entity>,
|
vecdeque: VecDeque<Entity>,
|
||||||
@ -156,7 +156,7 @@ where
|
|||||||
|
|
||||||
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> DescendantIter<'w, 's, D, F, S>
|
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> DescendantIter<'w, 's, D, F, S>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
{
|
{
|
||||||
/// Returns a new [`DescendantIter`].
|
/// Returns a new [`DescendantIter`].
|
||||||
pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
||||||
@ -174,7 +174,7 @@ where
|
|||||||
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> Iterator
|
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> Iterator
|
||||||
for DescendantIter<'w, 's, D, F, S>
|
for DescendantIter<'w, 's, D, F, S>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
{
|
{
|
||||||
type Item = Entity;
|
type Item = Entity;
|
||||||
|
|
||||||
@ -194,7 +194,7 @@ where
|
|||||||
/// Traverses the hierarchy depth-first.
|
/// Traverses the hierarchy depth-first.
|
||||||
pub struct DescendantDepthFirstIter<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
pub struct DescendantDepthFirstIter<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
{
|
{
|
||||||
children_query: &'w Query<'w, 's, D, F>,
|
children_query: &'w Query<'w, 's, D, F>,
|
||||||
stack: SmallVec<[Entity; 8]>,
|
stack: SmallVec<[Entity; 8]>,
|
||||||
@ -203,7 +203,7 @@ where
|
|||||||
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget>
|
||||||
DescendantDepthFirstIter<'w, 's, D, F, S>
|
DescendantDepthFirstIter<'w, 's, D, F, S>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
SourceIter<'w, S>: DoubleEndedIterator,
|
SourceIter<'w, S>: DoubleEndedIterator,
|
||||||
{
|
{
|
||||||
/// Returns a new [`DescendantDepthFirstIter`].
|
/// Returns a new [`DescendantDepthFirstIter`].
|
||||||
@ -220,7 +220,7 @@ where
|
|||||||
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> Iterator
|
impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> Iterator
|
||||||
for DescendantDepthFirstIter<'w, 's, D, F, S>
|
for DescendantDepthFirstIter<'w, 's, D, F, S>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w S>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w S>,
|
||||||
SourceIter<'w, S>: DoubleEndedIterator,
|
SourceIter<'w, S>: DoubleEndedIterator,
|
||||||
{
|
{
|
||||||
type Item = Entity;
|
type Item = Entity;
|
||||||
@ -239,7 +239,7 @@ where
|
|||||||
/// An [`Iterator`] of [`Entity`]s over the ancestors of an [`Entity`].
|
/// An [`Iterator`] of [`Entity`]s over the ancestors of an [`Entity`].
|
||||||
pub struct AncestorIter<'w, 's, D: QueryData, F: QueryFilter, R: Relationship>
|
pub struct AncestorIter<'w, 's, D: QueryData, F: QueryFilter, R: Relationship>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w R>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w R>,
|
||||||
{
|
{
|
||||||
parent_query: &'w Query<'w, 's, D, F>,
|
parent_query: &'w Query<'w, 's, D, F>,
|
||||||
next: Option<Entity>,
|
next: Option<Entity>,
|
||||||
@ -247,7 +247,7 @@ where
|
|||||||
|
|
||||||
impl<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> AncestorIter<'w, 's, D, F, R>
|
impl<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> AncestorIter<'w, 's, D, F, R>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w R>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w R>,
|
||||||
{
|
{
|
||||||
/// Returns a new [`AncestorIter`].
|
/// Returns a new [`AncestorIter`].
|
||||||
pub fn new(parent_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
pub fn new(parent_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
||||||
@ -261,7 +261,7 @@ where
|
|||||||
impl<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> Iterator
|
impl<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> Iterator
|
||||||
for AncestorIter<'w, 's, D, F, R>
|
for AncestorIter<'w, 's, D, F, R>
|
||||||
where
|
where
|
||||||
D::ReadOnly: QueryData<Item<'w> = &'w R>,
|
D::ReadOnly: QueryData<Item<'w, 's> = &'w R>,
|
||||||
{
|
{
|
||||||
type Item = Entity;
|
type Item = Entity;
|
||||||
|
|
||||||
|
@ -1185,7 +1185,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
/// [`par_iter_mut`]: Self::par_iter_mut
|
/// [`par_iter_mut`]: Self::par_iter_mut
|
||||||
/// [`World`]: crate::world::World
|
/// [`World`]: crate::world::World
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn par_iter(&self) -> QueryParIter<'_, '_, D::ReadOnly, F> {
|
pub fn par_iter(&self) -> QueryParIter<'_, 's, D::ReadOnly, F> {
|
||||||
self.as_readonly().par_iter_inner()
|
self.as_readonly().par_iter_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1220,7 +1220,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
/// [`par_iter`]: Self::par_iter
|
/// [`par_iter`]: Self::par_iter
|
||||||
/// [`World`]: crate::world::World
|
/// [`World`]: crate::world::World
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn par_iter_mut(&mut self) -> QueryParIter<'_, '_, D, F> {
|
pub fn par_iter_mut(&mut self) -> QueryParIter<'_, 's, D, F> {
|
||||||
self.reborrow().par_iter_inner()
|
self.reborrow().par_iter_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1280,7 +1280,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn par_iter_many<EntityList: IntoIterator<Item: EntityEquivalent>>(
|
pub fn par_iter_many<EntityList: IntoIterator<Item: EntityEquivalent>>(
|
||||||
&self,
|
&self,
|
||||||
entities: EntityList,
|
entities: EntityList,
|
||||||
) -> QueryParManyIter<'_, '_, D::ReadOnly, F, EntityList::Item> {
|
) -> QueryParManyIter<'_, 's, D::ReadOnly, F, EntityList::Item> {
|
||||||
QueryParManyIter {
|
QueryParManyIter {
|
||||||
world: self.world,
|
world: self.world,
|
||||||
state: self.state.as_readonly(),
|
state: self.state.as_readonly(),
|
||||||
@ -1309,7 +1309,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn par_iter_many_unique<EntityList: EntitySet<Item: Sync>>(
|
pub fn par_iter_many_unique<EntityList: EntitySet<Item: Sync>>(
|
||||||
&self,
|
&self,
|
||||||
entities: EntityList,
|
entities: EntityList,
|
||||||
) -> QueryParManyUniqueIter<'_, '_, D::ReadOnly, F, EntityList::Item> {
|
) -> QueryParManyUniqueIter<'_, 's, D::ReadOnly, F, EntityList::Item> {
|
||||||
QueryParManyUniqueIter {
|
QueryParManyUniqueIter {
|
||||||
world: self.world,
|
world: self.world,
|
||||||
state: self.state.as_readonly(),
|
state: self.state.as_readonly(),
|
||||||
@ -1338,7 +1338,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn par_iter_many_unique_mut<EntityList: EntitySet<Item: Sync>>(
|
pub fn par_iter_many_unique_mut<EntityList: EntitySet<Item: Sync>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
entities: EntityList,
|
entities: EntityList,
|
||||||
) -> QueryParManyUniqueIter<'_, '_, D, F, EntityList::Item> {
|
) -> QueryParManyUniqueIter<'_, 's, D, F, EntityList::Item> {
|
||||||
QueryParManyUniqueIter {
|
QueryParManyUniqueIter {
|
||||||
world: self.world,
|
world: self.world,
|
||||||
state: self.state,
|
state: self.state,
|
||||||
@ -1383,7 +1383,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
///
|
///
|
||||||
/// - [`get_mut`](Self::get_mut) to get a mutable query item.
|
/// - [`get_mut`](Self::get_mut) to get a mutable query item.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get(&self, entity: Entity) -> Result<ROQueryItem<'_, D>, QueryEntityError> {
|
pub fn get(&self, entity: Entity) -> Result<ROQueryItem<'_, 's, D>, QueryEntityError> {
|
||||||
self.as_readonly().get_inner(entity)
|
self.as_readonly().get_inner(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1434,7 +1434,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn get_many<const N: usize>(
|
pub fn get_many<const N: usize>(
|
||||||
&self,
|
&self,
|
||||||
entities: [Entity; N],
|
entities: [Entity; N],
|
||||||
) -> Result<[ROQueryItem<'_, D>; N], QueryEntityError> {
|
) -> Result<[ROQueryItem<'_, 's, D>; N], QueryEntityError> {
|
||||||
// Note that we call a separate `*_inner` method from `get_many_mut`
|
// Note that we call a separate `*_inner` method from `get_many_mut`
|
||||||
// because we don't need to check for duplicates.
|
// because we don't need to check for duplicates.
|
||||||
self.as_readonly().get_many_inner(entities)
|
self.as_readonly().get_many_inner(entities)
|
||||||
@ -1485,7 +1485,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn get_many_unique<const N: usize>(
|
pub fn get_many_unique<const N: usize>(
|
||||||
&self,
|
&self,
|
||||||
entities: UniqueEntityArray<N>,
|
entities: UniqueEntityArray<N>,
|
||||||
) -> Result<[ROQueryItem<'_, D>; N], QueryEntityError> {
|
) -> Result<[ROQueryItem<'_, 's, D>; N], QueryEntityError> {
|
||||||
self.as_readonly().get_many_unique_inner(entities)
|
self.as_readonly().get_many_unique_inner(entities)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1519,7 +1519,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
///
|
///
|
||||||
/// - [`get`](Self::get) to get a read-only query item.
|
/// - [`get`](Self::get) to get a read-only query item.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_mut(&mut self, entity: Entity) -> Result<D::Item<'_>, QueryEntityError> {
|
pub fn get_mut(&mut self, entity: Entity) -> Result<D::Item<'_, 's>, QueryEntityError> {
|
||||||
self.reborrow().get_inner(entity)
|
self.reborrow().get_inner(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1534,7 +1534,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
///
|
///
|
||||||
/// - [`get_mut`](Self::get_mut) to get the item using a mutable borrow of the [`Query`].
|
/// - [`get_mut`](Self::get_mut) to get the item using a mutable borrow of the [`Query`].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_inner(self, entity: Entity) -> Result<D::Item<'w>, QueryEntityError> {
|
pub fn get_inner(self, entity: Entity) -> Result<D::Item<'w, 's>, QueryEntityError> {
|
||||||
// SAFETY: system runs without conflicts with other systems.
|
// SAFETY: system runs without conflicts with other systems.
|
||||||
// same-system queries have runtime borrow checks when they conflict
|
// same-system queries have runtime borrow checks when they conflict
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -1662,7 +1662,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn get_many_mut<const N: usize>(
|
pub fn get_many_mut<const N: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
entities: [Entity; N],
|
entities: [Entity; N],
|
||||||
) -> Result<[D::Item<'_>; N], QueryEntityError> {
|
) -> Result<[D::Item<'_, 's>; N], QueryEntityError> {
|
||||||
self.reborrow().get_many_mut_inner(entities)
|
self.reborrow().get_many_mut_inner(entities)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1730,7 +1730,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn get_many_unique_mut<const N: usize>(
|
pub fn get_many_unique_mut<const N: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
entities: UniqueEntityArray<N>,
|
entities: UniqueEntityArray<N>,
|
||||||
) -> Result<[D::Item<'_>; N], QueryEntityError> {
|
) -> Result<[D::Item<'_, 's>; N], QueryEntityError> {
|
||||||
self.reborrow().get_many_unique_inner(entities)
|
self.reborrow().get_many_unique_inner(entities)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1749,7 +1749,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn get_many_mut_inner<const N: usize>(
|
pub fn get_many_mut_inner<const N: usize>(
|
||||||
self,
|
self,
|
||||||
entities: [Entity; N],
|
entities: [Entity; N],
|
||||||
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
) -> Result<[D::Item<'w, 's>; N], QueryEntityError> {
|
||||||
// Verify that all entities are unique
|
// Verify that all entities are unique
|
||||||
for i in 0..N {
|
for i in 0..N {
|
||||||
for j in 0..i {
|
for j in 0..i {
|
||||||
@ -1777,7 +1777,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn get_many_inner<const N: usize>(
|
pub fn get_many_inner<const N: usize>(
|
||||||
self,
|
self,
|
||||||
entities: [Entity; N],
|
entities: [Entity; N],
|
||||||
) -> Result<[D::Item<'w>; N], QueryEntityError>
|
) -> Result<[D::Item<'w, 's>; N], QueryEntityError>
|
||||||
where
|
where
|
||||||
D: ReadOnlyQueryData,
|
D: ReadOnlyQueryData,
|
||||||
{
|
{
|
||||||
@ -1799,7 +1799,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
pub fn get_many_unique_inner<const N: usize>(
|
pub fn get_many_unique_inner<const N: usize>(
|
||||||
self,
|
self,
|
||||||
entities: UniqueEntityArray<N>,
|
entities: UniqueEntityArray<N>,
|
||||||
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
) -> Result<[D::Item<'w, 's>; N], QueryEntityError> {
|
||||||
// SAFETY: All entities are unique, so the results don't alias.
|
// SAFETY: All entities are unique, so the results don't alias.
|
||||||
unsafe { self.get_many_impl(entities.into_inner()) }
|
unsafe { self.get_many_impl(entities.into_inner()) }
|
||||||
}
|
}
|
||||||
@ -1814,7 +1814,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
unsafe fn get_many_impl<const N: usize>(
|
unsafe fn get_many_impl<const N: usize>(
|
||||||
self,
|
self,
|
||||||
entities: [Entity; N],
|
entities: [Entity; N],
|
||||||
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
) -> Result<[D::Item<'w, 's>; N], QueryEntityError> {
|
||||||
let mut values = [(); N].map(|_| MaybeUninit::uninit());
|
let mut values = [(); N].map(|_| MaybeUninit::uninit());
|
||||||
|
|
||||||
for (value, entity) in core::iter::zip(&mut values, entities) {
|
for (value, entity) in core::iter::zip(&mut values, entities) {
|
||||||
@ -1842,7 +1842,10 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
///
|
///
|
||||||
/// - [`get_mut`](Self::get_mut) for the safe version.
|
/// - [`get_mut`](Self::get_mut) for the safe version.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn get_unchecked(&self, entity: Entity) -> Result<D::Item<'_>, QueryEntityError> {
|
pub unsafe fn get_unchecked(
|
||||||
|
&self,
|
||||||
|
entity: Entity,
|
||||||
|
) -> Result<D::Item<'_, 's>, QueryEntityError> {
|
||||||
// SAFETY: The caller promises that this will not result in multiple mutable references.
|
// SAFETY: The caller promises that this will not result in multiple mutable references.
|
||||||
unsafe { self.reborrow_unsafe() }.get_inner(entity)
|
unsafe { self.reborrow_unsafe() }.get_inner(entity)
|
||||||
}
|
}
|
||||||
@ -1878,7 +1881,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
///
|
///
|
||||||
/// - [`single_mut`](Self::single_mut) to get the mutable query item.
|
/// - [`single_mut`](Self::single_mut) to get the mutable query item.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn single(&self) -> Result<ROQueryItem<'_, D>, QuerySingleError> {
|
pub fn single(&self) -> Result<ROQueryItem<'_, 's, D>, QuerySingleError> {
|
||||||
self.as_readonly().single_inner()
|
self.as_readonly().single_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1907,7 +1910,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
///
|
///
|
||||||
/// - [`single`](Self::single) to get the read-only query item.
|
/// - [`single`](Self::single) to get the read-only query item.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn single_mut(&mut self) -> Result<D::Item<'_>, QuerySingleError> {
|
pub fn single_mut(&mut self) -> Result<D::Item<'_, 's>, QuerySingleError> {
|
||||||
self.reborrow().single_inner()
|
self.reborrow().single_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1939,7 +1942,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
/// - [`single_mut`](Self::single_mut) to get the mutable query item.
|
/// - [`single_mut`](Self::single_mut) to get the mutable query item.
|
||||||
/// - [`single_inner`](Self::single_inner) for the panicking version.
|
/// - [`single_inner`](Self::single_inner) for the panicking version.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn single_inner(self) -> Result<D::Item<'w>, QuerySingleError> {
|
pub fn single_inner(self) -> Result<D::Item<'w, 's>, QuerySingleError> {
|
||||||
let mut query = self.into_iter();
|
let mut query = self.into_iter();
|
||||||
let first = query.next();
|
let first = query.next();
|
||||||
let extra = query.next().is_some();
|
let extra = query.next().is_some();
|
||||||
@ -2451,7 +2454,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for Query<'w, 's, D, F> {
|
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for Query<'w, 's, D, F> {
|
||||||
type Item = D::Item<'w>;
|
type Item = D::Item<'w, 's>;
|
||||||
type IntoIter = QueryIter<'w, 's, D, F>;
|
type IntoIter = QueryIter<'w, 's, D, F>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
@ -2464,7 +2467,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for Query<'w, 's, D, F>
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w Query<'_, 's, D, F> {
|
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w Query<'_, 's, D, F> {
|
||||||
type Item = ROQueryItem<'w, D>;
|
type Item = ROQueryItem<'w, 's, D>;
|
||||||
type IntoIter = QueryIter<'w, 's, D::ReadOnly, F>;
|
type IntoIter = QueryIter<'w, 's, D::ReadOnly, F>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
@ -2473,7 +2476,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w Query<'_, 's, D,
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w mut Query<'_, 's, D, F> {
|
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w mut Query<'_, 's, D, F> {
|
||||||
type Item = D::Item<'w>;
|
type Item = D::Item<'w, 's>;
|
||||||
type IntoIter = QueryIter<'w, 's, D, F>;
|
type IntoIter = QueryIter<'w, 's, D, F>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
@ -2588,28 +2591,28 @@ impl<'w, 'q, Q: QueryData, F: QueryFilter> From<&'q mut Query<'w, '_, Q, F>>
|
|||||||
/// ```
|
/// ```
|
||||||
/// Note that because [`Single`] implements [`Deref`] and [`DerefMut`], methods and fields like `health` can be accessed directly.
|
/// Note that because [`Single`] implements [`Deref`] and [`DerefMut`], methods and fields like `health` can be accessed directly.
|
||||||
/// You can also access the underlying data manually, by calling `.deref`/`.deref_mut`, or by using the `*` operator.
|
/// You can also access the underlying data manually, by calling `.deref`/`.deref_mut`, or by using the `*` operator.
|
||||||
pub struct Single<'w, D: QueryData, F: QueryFilter = ()> {
|
pub struct Single<'w, 's, D: QueryData, F: QueryFilter = ()> {
|
||||||
pub(crate) item: D::Item<'w>,
|
pub(crate) item: D::Item<'w, 's>,
|
||||||
pub(crate) _filter: PhantomData<F>,
|
pub(crate) _filter: PhantomData<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'w, D: QueryData, F: QueryFilter> Deref for Single<'w, D, F> {
|
impl<'w, 's, D: QueryData, F: QueryFilter> Deref for Single<'w, 's, D, F> {
|
||||||
type Target = D::Item<'w>;
|
type Target = D::Item<'w, 's>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.item
|
&self.item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'w, D: QueryData, F: QueryFilter> DerefMut for Single<'w, D, F> {
|
impl<'w, 's, D: QueryData, F: QueryFilter> DerefMut for Single<'w, 's, D, F> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.item
|
&mut self.item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'w, D: QueryData, F: QueryFilter> Single<'w, D, F> {
|
impl<'w, 's, D: QueryData, F: QueryFilter> Single<'w, 's, D, F> {
|
||||||
/// Returns the inner item with ownership.
|
/// Returns the inner item with ownership.
|
||||||
pub fn into_inner(self) -> D::Item<'w> {
|
pub fn into_inner(self) -> D::Item<'w, 's> {
|
||||||
self.item
|
self.item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,9 +389,11 @@ fn assert_component_access_compatibility(
|
|||||||
|
|
||||||
// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
|
// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
|
||||||
// this Query conflicts with any prior access, a panic will occur.
|
// this Query conflicts with any prior access, a panic will occur.
|
||||||
unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Single<'a, D, F> {
|
unsafe impl<'a, 'b, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
|
||||||
|
for Single<'a, 'b, D, F>
|
||||||
|
{
|
||||||
type State = QueryState<D, F>;
|
type State = QueryState<D, F>;
|
||||||
type Item<'w, 's> = Single<'w, D, F>;
|
type Item<'w, 's> = Single<'w, 's, D, F>;
|
||||||
|
|
||||||
fn init_state(world: &mut World) -> Self::State {
|
fn init_state(world: &mut World) -> Self::State {
|
||||||
Query::init_state(world)
|
Query::init_state(world)
|
||||||
@ -451,8 +453,8 @@ unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam fo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
|
// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
|
||||||
unsafe impl<'a, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
|
unsafe impl<'a, 'b, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
|
||||||
for Single<'a, D, F>
|
for Single<'a, 'b, D, F>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
//! A trait for components that let you traverse the ECS.
|
//! A trait for components that let you traverse the ECS.
|
||||||
|
|
||||||
use crate::{entity::Entity, query::ReadOnlyQueryData, relationship::Relationship};
|
use crate::{
|
||||||
|
entity::Entity,
|
||||||
|
query::{ReadOnlyQueryData, ReleaseStateQueryData},
|
||||||
|
relationship::Relationship,
|
||||||
|
};
|
||||||
|
|
||||||
/// A component that can point to another entity, and which can be used to define a path through the ECS.
|
/// A component that can point to another entity, and which can be used to define a path through the ECS.
|
||||||
///
|
///
|
||||||
@ -20,13 +24,13 @@ use crate::{entity::Entity, query::ReadOnlyQueryData, relationship::Relationship
|
|||||||
/// [specify the direction]: crate::event::EntityEvent::Traversal
|
/// [specify the direction]: crate::event::EntityEvent::Traversal
|
||||||
/// [event propagation]: crate::observer::On::propagate
|
/// [event propagation]: crate::observer::On::propagate
|
||||||
/// [observers]: crate::observer::Observer
|
/// [observers]: crate::observer::Observer
|
||||||
pub trait Traversal<D: ?Sized>: ReadOnlyQueryData {
|
pub trait Traversal<D: ?Sized>: ReadOnlyQueryData + ReleaseStateQueryData {
|
||||||
/// Returns the next entity to visit.
|
/// Returns the next entity to visit.
|
||||||
fn traverse(item: Self::Item<'_>, data: &D) -> Option<Entity>;
|
fn traverse(item: Self::Item<'_, '_>, data: &D) -> Option<Entity>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> Traversal<D> for () {
|
impl<D> Traversal<D> for () {
|
||||||
fn traverse(_: Self::Item<'_>, _data: &D) -> Option<Entity> {
|
fn traverse(_: Self::Item<'_, '_>, _data: &D) -> Option<Entity> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,7 +43,7 @@ impl<D> Traversal<D> for () {
|
|||||||
///
|
///
|
||||||
/// [event propagation]: crate::observer::On::propagate
|
/// [event propagation]: crate::observer::On::propagate
|
||||||
impl<R: Relationship, D> Traversal<D> for &R {
|
impl<R: Relationship, D> Traversal<D> for &R {
|
||||||
fn traverse(item: Self::Item<'_>, _data: &D) -> Option<Entity> {
|
fn traverse(item: Self::Item<'_, '_>, _data: &D) -> Option<Entity> {
|
||||||
Some(item.get())
|
Some(item.get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ use crate::{
|
|||||||
event::EntityEvent,
|
event::EntityEvent,
|
||||||
lifecycle::{DESPAWN, REMOVE, REPLACE},
|
lifecycle::{DESPAWN, REMOVE, REPLACE},
|
||||||
observer::Observer,
|
observer::Observer,
|
||||||
query::{Access, DebugCheckedUnwrap, ReadOnlyQueryData},
|
query::{Access, DebugCheckedUnwrap, ReadOnlyQueryData, ReleaseStateQueryData},
|
||||||
relationship::RelationshipHookMode,
|
relationship::RelationshipHookMode,
|
||||||
resource::Resource,
|
resource::Resource,
|
||||||
system::IntoObserverSystem,
|
system::IntoObserverSystem,
|
||||||
@ -279,14 +279,16 @@ impl<'w> EntityRef<'w> {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// If the entity does not have the components required by the query `Q`.
|
/// If the entity does not have the components required by the query `Q`.
|
||||||
pub fn components<Q: ReadOnlyQueryData>(&self) -> Q::Item<'w> {
|
pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'w, 'static> {
|
||||||
self.get_components::<Q>()
|
self.get_components::<Q>()
|
||||||
.expect("Query does not match the current entity")
|
.expect("Query does not match the current entity")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns read-only components for the current entity that match the query `Q`,
|
/// Returns read-only components for the current entity that match the query `Q`,
|
||||||
/// or `None` if the entity does not have the components required by the query `Q`.
|
/// or `None` if the entity does not have the components required by the query `Q`.
|
||||||
pub fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'w>> {
|
pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(
|
||||||
|
&self,
|
||||||
|
) -> Option<Q::Item<'w, 'static>> {
|
||||||
// SAFETY: We have read-only access to all components of this entity.
|
// SAFETY: We have read-only access to all components of this entity.
|
||||||
unsafe { self.cell.get_components::<Q>() }
|
unsafe { self.cell.get_components::<Q>() }
|
||||||
}
|
}
|
||||||
@ -546,13 +548,15 @@ impl<'w> EntityMut<'w> {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// If the entity does not have the components required by the query `Q`.
|
/// If the entity does not have the components required by the query `Q`.
|
||||||
pub fn components<Q: ReadOnlyQueryData>(&self) -> Q::Item<'_> {
|
pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'_, 'static> {
|
||||||
self.as_readonly().components::<Q>()
|
self.as_readonly().components::<Q>()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns read-only components for the current entity that match the query `Q`,
|
/// Returns read-only components for the current entity that match the query `Q`,
|
||||||
/// or `None` if the entity does not have the components required by the query `Q`.
|
/// or `None` if the entity does not have the components required by the query `Q`.
|
||||||
pub fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'_>> {
|
pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(
|
||||||
|
&self,
|
||||||
|
) -> Option<Q::Item<'_, 'static>> {
|
||||||
self.as_readonly().get_components::<Q>()
|
self.as_readonly().get_components::<Q>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1310,7 +1314,7 @@ impl<'w> EntityWorldMut<'w> {
|
|||||||
/// If the entity does not have the components required by the query `Q` or if the entity
|
/// If the entity does not have the components required by the query `Q` or if the entity
|
||||||
/// has been despawned while this `EntityWorldMut` is still alive.
|
/// has been despawned while this `EntityWorldMut` is still alive.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn components<Q: ReadOnlyQueryData>(&self) -> Q::Item<'_> {
|
pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'_, 'static> {
|
||||||
self.as_readonly().components::<Q>()
|
self.as_readonly().components::<Q>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1321,7 +1325,9 @@ impl<'w> EntityWorldMut<'w> {
|
|||||||
///
|
///
|
||||||
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
|
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'_>> {
|
pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(
|
||||||
|
&self,
|
||||||
|
) -> Option<Q::Item<'_, 'static>> {
|
||||||
self.as_readonly().get_components::<Q>()
|
self.as_readonly().get_components::<Q>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
lifecycle::RemovedComponentEvents,
|
lifecycle::RemovedComponentEvents,
|
||||||
observer::Observers,
|
observer::Observers,
|
||||||
prelude::Component,
|
prelude::Component,
|
||||||
query::{DebugCheckedUnwrap, ReadOnlyQueryData},
|
query::{DebugCheckedUnwrap, ReadOnlyQueryData, ReleaseStateQueryData},
|
||||||
resource::Resource,
|
resource::Resource,
|
||||||
storage::{ComponentSparseSet, Storages, Table},
|
storage::{ComponentSparseSet, Storages, Table},
|
||||||
world::RawCommandQueue,
|
world::RawCommandQueue,
|
||||||
@ -998,7 +998,9 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
/// It is the caller's responsibility to ensure that
|
/// It is the caller's responsibility to ensure that
|
||||||
/// - the [`UnsafeEntityCell`] has permission to access the queried data immutably
|
/// - the [`UnsafeEntityCell`] has permission to access the queried data immutably
|
||||||
/// - no mutable references to the queried data exist at the same time
|
/// - no mutable references to the queried data exist at the same time
|
||||||
pub(crate) unsafe fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'w>> {
|
pub(crate) unsafe fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(
|
||||||
|
&self,
|
||||||
|
) -> Option<Q::Item<'w, 'static>> {
|
||||||
// SAFETY: World is only used to access query data and initialize query state
|
// SAFETY: World is only used to access query data and initialize query state
|
||||||
let state = unsafe {
|
let state = unsafe {
|
||||||
let world = self.world().world();
|
let world = self.world().world();
|
||||||
@ -1028,7 +1030,8 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
// Table corresponds to archetype. State is the same state used to init fetch above.
|
// Table corresponds to archetype. State is the same state used to init fetch above.
|
||||||
unsafe { Q::set_archetype(&mut fetch, &state, archetype, table) }
|
unsafe { Q::set_archetype(&mut fetch, &state, archetype, table) }
|
||||||
// SAFETY: Called after set_archetype above. Entity and location are guaranteed to exist.
|
// SAFETY: Called after set_archetype above. Entity and location are guaranteed to exist.
|
||||||
unsafe { Some(Q::fetch(&mut fetch, self.id(), location.table_row)) }
|
let item = unsafe { Q::fetch(&mut fetch, self.id(), location.table_row) };
|
||||||
|
Some(Q::release_state(item))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -631,8 +631,8 @@ impl<const I: usize, P: PhaseItem> RenderCommand<P> for SetLineGizmoBindGroup<I>
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
_item: &P,
|
_item: &P,
|
||||||
_view: ROQueryItem<'w, Self::ViewQuery>,
|
_view: ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
uniform_index: Option<ROQueryItem<'w, Self::ItemQuery>>,
|
uniform_index: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
|
||||||
bind_group: SystemParamItem<'w, '_, Self::Param>,
|
bind_group: SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
) -> RenderCommandResult {
|
) -> RenderCommandResult {
|
||||||
@ -662,8 +662,8 @@ impl<P: PhaseItem, const STRIP: bool> RenderCommand<P> for DrawLineGizmo<STRIP>
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
_item: &P,
|
_item: &P,
|
||||||
_view: ROQueryItem<'w, Self::ViewQuery>,
|
_view: ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
config: Option<ROQueryItem<'w, Self::ItemQuery>>,
|
config: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
|
||||||
line_gizmos: SystemParamItem<'w, '_, Self::Param>,
|
line_gizmos: SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
) -> RenderCommandResult {
|
) -> RenderCommandResult {
|
||||||
@ -725,8 +725,8 @@ impl<P: PhaseItem> RenderCommand<P> for DrawLineJointGizmo {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
_item: &P,
|
_item: &P,
|
||||||
_view: ROQueryItem<'w, Self::ViewQuery>,
|
_view: ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
config: Option<ROQueryItem<'w, Self::ItemQuery>>,
|
config: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
|
||||||
line_gizmos: SystemParamItem<'w, '_, Self::Param>,
|
line_gizmos: SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
) -> RenderCommandResult {
|
) -> RenderCommandResult {
|
||||||
|
@ -155,7 +155,7 @@ pub struct WindowTraversal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<E: BufferedEvent + Clone> Traversal<FocusedInput<E>> for WindowTraversal {
|
impl<E: BufferedEvent + Clone> Traversal<FocusedInput<E>> for WindowTraversal {
|
||||||
fn traverse(item: Self::Item<'_>, event: &FocusedInput<E>) -> Option<Entity> {
|
fn traverse(item: Self::Item<'_, '_>, event: &FocusedInput<E>) -> Option<Entity> {
|
||||||
let WindowTraversalItem { child_of, window } = item;
|
let WindowTraversalItem { child_of, window } = item;
|
||||||
|
|
||||||
// Send event to parent, if it has one.
|
// Send event to parent, if it has one.
|
||||||
|
@ -309,7 +309,7 @@ impl ExtractComponent for Atmosphere {
|
|||||||
|
|
||||||
type Out = Atmosphere;
|
type Out = Atmosphere;
|
||||||
|
|
||||||
fn extract_component(item: QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
|
fn extract_component(item: QueryItem<'_, '_, Self::QueryData>) -> Option<Self::Out> {
|
||||||
Some(item.clone())
|
Some(item.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,7 +405,7 @@ impl ExtractComponent for AtmosphereSettings {
|
|||||||
|
|
||||||
type Out = AtmosphereSettings;
|
type Out = AtmosphereSettings;
|
||||||
|
|
||||||
fn extract_component(item: QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
|
fn extract_component(item: QueryItem<'_, '_, Self::QueryData>) -> Option<Self::Out> {
|
||||||
Some(item.clone())
|
Some(item.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ impl ViewNode for RenderSkyNode {
|
|||||||
view_uniforms_offset,
|
view_uniforms_offset,
|
||||||
lights_uniforms_offset,
|
lights_uniforms_offset,
|
||||||
render_sky_pipeline_id,
|
render_sky_pipeline_id,
|
||||||
): QueryItem<'w, Self::ViewQuery>,
|
): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let pipeline_cache = world.resource::<PipelineCache>();
|
let pipeline_cache = world.resource::<PipelineCache>();
|
||||||
|
@ -192,7 +192,7 @@ impl ExtractInstance for EnvironmentMapIds {
|
|||||||
|
|
||||||
type QueryFilter = ();
|
type QueryFilter = ();
|
||||||
|
|
||||||
fn extract(item: QueryItem<'_, Self::QueryData>) -> Option<Self> {
|
fn extract(item: QueryItem<'_, '_, Self::QueryData>) -> Option<Self> {
|
||||||
Some(EnvironmentMapIds {
|
Some(EnvironmentMapIds {
|
||||||
diffuse: item.diffuse_map.id(),
|
diffuse: item.diffuse_map.id(),
|
||||||
specular: item.specular_map.id(),
|
specular: item.specular_map.id(),
|
||||||
|
@ -1540,7 +1540,7 @@ fn extract_mesh_for_gpu_building(
|
|||||||
not_shadow_caster,
|
not_shadow_caster,
|
||||||
no_automatic_batching,
|
no_automatic_batching,
|
||||||
visibility_range,
|
visibility_range,
|
||||||
): <GpuMeshExtractionQuery as QueryData>::Item<'_>,
|
): <GpuMeshExtractionQuery as QueryData>::Item<'_, '_>,
|
||||||
render_visibility_ranges: &RenderVisibilityRanges,
|
render_visibility_ranges: &RenderVisibilityRanges,
|
||||||
render_mesh_instances: &RenderMeshInstancesGpu,
|
render_mesh_instances: &RenderMeshInstancesGpu,
|
||||||
queue: &mut RenderMeshInstanceGpuQueue,
|
queue: &mut RenderMeshInstanceGpuQueue,
|
||||||
@ -2874,7 +2874,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetMeshViewBindGroup<I>
|
|||||||
view_environment_map,
|
view_environment_map,
|
||||||
mesh_view_bind_group,
|
mesh_view_bind_group,
|
||||||
maybe_oit_layers_count_offset,
|
maybe_oit_layers_count_offset,
|
||||||
): ROQueryItem<'w, Self::ViewQuery>,
|
): ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
_entity: Option<()>,
|
_entity: Option<()>,
|
||||||
_: SystemParamItem<'w, '_, Self::Param>,
|
_: SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
|
@ -280,7 +280,7 @@ impl ViewNode for ScreenSpaceReflectionsNode {
|
|||||||
view_environment_map_offset,
|
view_environment_map_offset,
|
||||||
view_bind_group,
|
view_bind_group,
|
||||||
ssr_pipeline_id,
|
ssr_pipeline_id,
|
||||||
): QueryItem<'w, Self::ViewQuery>,
|
): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
// Grab the render pipeline.
|
// Grab the render pipeline.
|
||||||
@ -498,7 +498,7 @@ impl ExtractComponent for ScreenSpaceReflections {
|
|||||||
|
|
||||||
type Out = ScreenSpaceReflectionsUniform;
|
type Out = ScreenSpaceReflectionsUniform;
|
||||||
|
|
||||||
fn extract_component(settings: QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
|
fn extract_component(settings: QueryItem<'_, '_, Self::QueryData>) -> Option<Self::Out> {
|
||||||
if !DEPTH_TEXTURE_SAMPLING_SUPPORTED {
|
if !DEPTH_TEXTURE_SAMPLING_SUPPORTED {
|
||||||
once!(info!(
|
once!(info!(
|
||||||
"Disabling screen-space reflections on this platform because depth textures \
|
"Disabling screen-space reflections on this platform because depth textures \
|
||||||
|
@ -347,7 +347,7 @@ impl ViewNode for VolumetricFogNode {
|
|||||||
view_ssr_offset,
|
view_ssr_offset,
|
||||||
msaa,
|
msaa,
|
||||||
view_environment_map_offset,
|
view_environment_map_offset,
|
||||||
): QueryItem<'w, Self::ViewQuery>,
|
): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let pipeline_cache = world.resource::<PipelineCache>();
|
let pipeline_cache = world.resource::<PipelineCache>();
|
||||||
|
@ -374,7 +374,7 @@ impl ViewNode for Wireframe3dNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
(camera, view, target, depth): QueryItem<'w, Self::ViewQuery>,
|
(camera, view, target, depth): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let Some(wireframe_phase) = world.get_resource::<ViewBinnedRenderPhases<Wireframe3d>>()
|
let Some(wireframe_phase) = world.get_resource::<ViewBinnedRenderPhases<Wireframe3d>>()
|
||||||
|
@ -86,7 +86,7 @@ impl<E> Traversal<Pointer<E>> for PointerTraversal
|
|||||||
where
|
where
|
||||||
E: Debug + Clone + Reflect,
|
E: Debug + Clone + Reflect,
|
||||||
{
|
{
|
||||||
fn traverse(item: Self::Item<'_>, pointer: &Pointer<E>) -> Option<Entity> {
|
fn traverse(item: Self::Item<'_, '_>, pointer: &Pointer<E>) -> Option<Entity> {
|
||||||
let PointerTraversalItem { child_of, window } = item;
|
let PointerTraversalItem { child_of, window } = item;
|
||||||
|
|
||||||
// Send event to parent, if it has one.
|
// Send event to parent, if it has one.
|
||||||
|
@ -43,7 +43,7 @@ pub fn derive_extract_component(input: TokenStream) -> TokenStream {
|
|||||||
type QueryFilter = #filter;
|
type QueryFilter = #filter;
|
||||||
type Out = Self;
|
type Out = Self;
|
||||||
|
|
||||||
fn extract_component(item: #bevy_ecs_path::query::QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
|
fn extract_component(item: #bevy_ecs_path::query::QueryItem<'_, '_, Self::QueryData>) -> Option<Self::Out> {
|
||||||
Some(item.clone())
|
Some(item.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ pub trait ExtractComponent: Component {
|
|||||||
// type Out: Component = Self;
|
// type Out: Component = Self;
|
||||||
|
|
||||||
/// Defines how the component is transferred into the "render world".
|
/// Defines how the component is transferred into the "render world".
|
||||||
fn extract_component(item: QueryItem<'_, Self::QueryData>) -> Option<Self::Out>;
|
fn extract_component(item: QueryItem<'_, '_, Self::QueryData>) -> Option<Self::Out>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This plugin prepares the components of the corresponding type for the GPU
|
/// This plugin prepares the components of the corresponding type for the GPU
|
||||||
|
@ -34,7 +34,7 @@ pub trait ExtractInstance: Send + Sync + Sized + 'static {
|
|||||||
type QueryFilter: QueryFilter;
|
type QueryFilter: QueryFilter;
|
||||||
|
|
||||||
/// Defines how the component is transferred into the "render world".
|
/// Defines how the component is transferred into the "render world".
|
||||||
fn extract(item: QueryItem<'_, Self::QueryData>) -> Option<Self>;
|
fn extract(item: QueryItem<'_, '_, Self::QueryData>) -> Option<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This plugin extracts one or more components into the "render world" as
|
/// This plugin extracts one or more components into the "render world" as
|
||||||
|
@ -366,7 +366,7 @@ pub trait ViewNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
view_query: QueryItem<'w, Self::ViewQuery>,
|
view_query: QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError>;
|
) -> Result<(), NodeRunError>;
|
||||||
}
|
}
|
||||||
|
@ -213,8 +213,8 @@ pub trait RenderCommand<P: PhaseItem> {
|
|||||||
/// issuing draw calls, etc.) via the [`TrackedRenderPass`].
|
/// issuing draw calls, etc.) via the [`TrackedRenderPass`].
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
item: &P,
|
item: &P,
|
||||||
view: ROQueryItem<'w, Self::ViewQuery>,
|
view: ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
entity: Option<ROQueryItem<'w, Self::ItemQuery>>,
|
entity: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
|
||||||
param: SystemParamItem<'w, '_, Self::Param>,
|
param: SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
) -> RenderCommandResult;
|
) -> RenderCommandResult;
|
||||||
@ -246,8 +246,8 @@ macro_rules! render_command_tuple_impl {
|
|||||||
)]
|
)]
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
_item: &P,
|
_item: &P,
|
||||||
($($view,)*): ROQueryItem<'w, Self::ViewQuery>,
|
($($view,)*): ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
maybe_entities: Option<ROQueryItem<'w, Self::ItemQuery>>,
|
maybe_entities: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
|
||||||
($($name,)*): SystemParamItem<'w, '_, Self::Param>,
|
($($name,)*): SystemParamItem<'w, '_, Self::Param>,
|
||||||
_pass: &mut TrackedRenderPass<'w>,
|
_pass: &mut TrackedRenderPass<'w>,
|
||||||
) -> RenderCommandResult {
|
) -> RenderCommandResult {
|
||||||
|
@ -281,7 +281,7 @@ mod render_entities_world_query_impls {
|
|||||||
archetype::Archetype,
|
archetype::Archetype,
|
||||||
component::{ComponentId, Components, Tick},
|
component::{ComponentId, Components, Tick},
|
||||||
entity::Entity,
|
entity::Entity,
|
||||||
query::{FilteredAccess, QueryData, ReadOnlyQueryData, WorldQuery},
|
query::{FilteredAccess, QueryData, ReadOnlyQueryData, ReleaseStateQueryData, WorldQuery},
|
||||||
storage::{Table, TableRow},
|
storage::{Table, TableRow},
|
||||||
world::{unsafe_world_cell::UnsafeWorldCell, World},
|
world::{unsafe_world_cell::UnsafeWorldCell, World},
|
||||||
};
|
};
|
||||||
@ -289,22 +289,22 @@ mod render_entities_world_query_impls {
|
|||||||
/// SAFETY: defers completely to `&RenderEntity` implementation,
|
/// SAFETY: defers completely to `&RenderEntity` implementation,
|
||||||
/// and then only modifies the output safely.
|
/// and then only modifies the output safely.
|
||||||
unsafe impl WorldQuery for RenderEntity {
|
unsafe impl WorldQuery for RenderEntity {
|
||||||
type Fetch<'w> = <&'static RenderEntity as WorldQuery>::Fetch<'w>;
|
type Fetch<'w, 's> = <&'static RenderEntity as WorldQuery>::Fetch<'w, 's>;
|
||||||
type State = <&'static RenderEntity as WorldQuery>::State;
|
type State = <&'static RenderEntity as WorldQuery>::State;
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
fetch: Self::Fetch<'wlong>,
|
fetch: Self::Fetch<'wlong, 's>,
|
||||||
) -> Self::Fetch<'wshort> {
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
fetch
|
fetch
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch<'w>(
|
unsafe fn init_fetch<'w, 's>(
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
component_id: &ComponentId,
|
component_id: &'s ComponentId,
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) -> Self::Fetch<'w> {
|
) -> Self::Fetch<'w, 's> {
|
||||||
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
||||||
unsafe {
|
unsafe {
|
||||||
<&RenderEntity as WorldQuery>::init_fetch(world, component_id, last_run, this_run)
|
<&RenderEntity as WorldQuery>::init_fetch(world, component_id, last_run, this_run)
|
||||||
@ -314,9 +314,9 @@ mod render_entities_world_query_impls {
|
|||||||
const IS_DENSE: bool = <&'static RenderEntity as WorldQuery>::IS_DENSE;
|
const IS_DENSE: bool = <&'static RenderEntity as WorldQuery>::IS_DENSE;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
component_id: &ComponentId,
|
component_id: &'s ComponentId,
|
||||||
archetype: &'w Archetype,
|
archetype: &'w Archetype,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
) {
|
) {
|
||||||
@ -327,9 +327,9 @@ mod render_entities_world_query_impls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_table<'w>(
|
unsafe fn set_table<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
&component_id: &ComponentId,
|
&component_id: &'s ComponentId,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
) {
|
) {
|
||||||
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
||||||
@ -364,18 +364,20 @@ mod render_entities_world_query_impls {
|
|||||||
unsafe impl QueryData for RenderEntity {
|
unsafe impl QueryData for RenderEntity {
|
||||||
const IS_READ_ONLY: bool = true;
|
const IS_READ_ONLY: bool = true;
|
||||||
type ReadOnly = RenderEntity;
|
type ReadOnly = RenderEntity;
|
||||||
type Item<'w> = Entity;
|
type Item<'w, 's> = Entity;
|
||||||
|
|
||||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Entity) -> Entity {
|
fn shrink<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
item: Self::Item<'wlong, 's>,
|
||||||
|
) -> Self::Item<'wshort, 's> {
|
||||||
item
|
item
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn fetch<'w>(
|
unsafe fn fetch<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> Self::Item<'w> {
|
) -> Self::Item<'w, 's> {
|
||||||
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
// SAFETY: defers to the `&T` implementation, with T set to `RenderEntity`.
|
||||||
let component =
|
let component =
|
||||||
unsafe { <&RenderEntity as QueryData>::fetch(fetch, entity, table_row) };
|
unsafe { <&RenderEntity as QueryData>::fetch(fetch, entity, table_row) };
|
||||||
@ -386,25 +388,31 @@ mod render_entities_world_query_impls {
|
|||||||
// SAFETY: the underlying `Entity` is copied, and no mutable access is provided.
|
// SAFETY: the underlying `Entity` is copied, and no mutable access is provided.
|
||||||
unsafe impl ReadOnlyQueryData for RenderEntity {}
|
unsafe impl ReadOnlyQueryData for RenderEntity {}
|
||||||
|
|
||||||
|
impl ReleaseStateQueryData for RenderEntity {
|
||||||
|
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
|
||||||
|
item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// SAFETY: defers completely to `&RenderEntity` implementation,
|
/// SAFETY: defers completely to `&RenderEntity` implementation,
|
||||||
/// and then only modifies the output safely.
|
/// and then only modifies the output safely.
|
||||||
unsafe impl WorldQuery for MainEntity {
|
unsafe impl WorldQuery for MainEntity {
|
||||||
type Fetch<'w> = <&'static MainEntity as WorldQuery>::Fetch<'w>;
|
type Fetch<'w, 's> = <&'static MainEntity as WorldQuery>::Fetch<'w, 's>;
|
||||||
type State = <&'static MainEntity as WorldQuery>::State;
|
type State = <&'static MainEntity as WorldQuery>::State;
|
||||||
|
|
||||||
fn shrink_fetch<'wlong: 'wshort, 'wshort>(
|
fn shrink_fetch<'wlong: 'wshort, 'wshort, 's>(
|
||||||
fetch: Self::Fetch<'wlong>,
|
fetch: Self::Fetch<'wlong, 's>,
|
||||||
) -> Self::Fetch<'wshort> {
|
) -> Self::Fetch<'wshort, 's> {
|
||||||
fetch
|
fetch
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_fetch<'w>(
|
unsafe fn init_fetch<'w, 's>(
|
||||||
world: UnsafeWorldCell<'w>,
|
world: UnsafeWorldCell<'w>,
|
||||||
component_id: &ComponentId,
|
component_id: &'s ComponentId,
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
this_run: Tick,
|
this_run: Tick,
|
||||||
) -> Self::Fetch<'w> {
|
) -> Self::Fetch<'w, 's> {
|
||||||
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
||||||
unsafe {
|
unsafe {
|
||||||
<&MainEntity as WorldQuery>::init_fetch(world, component_id, last_run, this_run)
|
<&MainEntity as WorldQuery>::init_fetch(world, component_id, last_run, this_run)
|
||||||
@ -414,8 +422,8 @@ mod render_entities_world_query_impls {
|
|||||||
const IS_DENSE: bool = <&'static MainEntity as WorldQuery>::IS_DENSE;
|
const IS_DENSE: bool = <&'static MainEntity as WorldQuery>::IS_DENSE;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_archetype<'w>(
|
unsafe fn set_archetype<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
component_id: &ComponentId,
|
component_id: &ComponentId,
|
||||||
archetype: &'w Archetype,
|
archetype: &'w Archetype,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
@ -427,9 +435,9 @@ mod render_entities_world_query_impls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn set_table<'w>(
|
unsafe fn set_table<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
&component_id: &ComponentId,
|
&component_id: &'s ComponentId,
|
||||||
table: &'w Table,
|
table: &'w Table,
|
||||||
) {
|
) {
|
||||||
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
||||||
@ -464,18 +472,20 @@ mod render_entities_world_query_impls {
|
|||||||
unsafe impl QueryData for MainEntity {
|
unsafe impl QueryData for MainEntity {
|
||||||
const IS_READ_ONLY: bool = true;
|
const IS_READ_ONLY: bool = true;
|
||||||
type ReadOnly = MainEntity;
|
type ReadOnly = MainEntity;
|
||||||
type Item<'w> = Entity;
|
type Item<'w, 's> = Entity;
|
||||||
|
|
||||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Entity) -> Entity {
|
fn shrink<'wlong: 'wshort, 'wshort, 's>(
|
||||||
|
item: Self::Item<'wlong, 's>,
|
||||||
|
) -> Self::Item<'wshort, 's> {
|
||||||
item
|
item
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn fetch<'w>(
|
unsafe fn fetch<'w, 's>(
|
||||||
fetch: &mut Self::Fetch<'w>,
|
fetch: &mut Self::Fetch<'w, 's>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> Self::Item<'w> {
|
) -> Self::Item<'w, 's> {
|
||||||
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
// SAFETY: defers to the `&T` implementation, with T set to `MainEntity`.
|
||||||
let component = unsafe { <&MainEntity as QueryData>::fetch(fetch, entity, table_row) };
|
let component = unsafe { <&MainEntity as QueryData>::fetch(fetch, entity, table_row) };
|
||||||
component.id()
|
component.id()
|
||||||
@ -484,6 +494,12 @@ mod render_entities_world_query_impls {
|
|||||||
|
|
||||||
// SAFETY: the underlying `Entity` is copied, and no mutable access is provided.
|
// SAFETY: the underlying `Entity` is copied, and no mutable access is provided.
|
||||||
unsafe impl ReadOnlyQueryData for MainEntity {}
|
unsafe impl ReadOnlyQueryData for MainEntity {}
|
||||||
|
|
||||||
|
impl ReleaseStateQueryData for MainEntity {
|
||||||
|
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
|
||||||
|
item
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -778,7 +778,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetMesh2dViewBindGroup<I
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
_item: &P,
|
_item: &P,
|
||||||
(view_uniform, mesh2d_view_bind_group): ROQueryItem<'w, Self::ViewQuery>,
|
(view_uniform, mesh2d_view_bind_group): ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
_view: Option<()>,
|
_view: Option<()>,
|
||||||
_param: SystemParamItem<'w, '_, Self::Param>,
|
_param: SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
|
@ -372,7 +372,7 @@ impl ViewNode for Wireframe2dNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
(camera, view, target, depth): QueryItem<'w, Self::ViewQuery>,
|
(camera, view, target, depth): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
let Some(wireframe_phase) =
|
let Some(wireframe_phase) =
|
||||||
|
@ -908,7 +908,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetSpriteViewBindGroup<I
|
|||||||
|
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
_item: &P,
|
_item: &P,
|
||||||
(view_uniform, sprite_view_bind_group): ROQueryItem<'w, Self::ViewQuery>,
|
(view_uniform, sprite_view_bind_group): ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
_entity: Option<()>,
|
_entity: Option<()>,
|
||||||
_param: SystemParamItem<'w, '_, Self::Param>,
|
_param: SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
@ -925,7 +925,7 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetSpriteTextureBindGrou
|
|||||||
|
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
item: &P,
|
item: &P,
|
||||||
view: ROQueryItem<'w, Self::ViewQuery>,
|
view: ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
_entity: Option<()>,
|
_entity: Option<()>,
|
||||||
(image_bind_groups, batches): SystemParamItem<'w, '_, Self::Param>,
|
(image_bind_groups, batches): SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
@ -955,7 +955,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawSpriteBatch {
|
|||||||
|
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
item: &P,
|
item: &P,
|
||||||
view: ROQueryItem<'w, Self::ViewQuery>,
|
view: ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
_entity: Option<()>,
|
_entity: Option<()>,
|
||||||
(sprite_meta, batches): SystemParamItem<'w, '_, Self::Param>,
|
(sprite_meta, batches): SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
|
@ -276,7 +276,7 @@ impl<P: PhaseItem, M: UiMaterial, const I: usize> RenderCommand<P>
|
|||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
_item: &P,
|
_item: &P,
|
||||||
_view: (),
|
_view: (),
|
||||||
material_handle: Option<ROQueryItem<'_, Self::ItemQuery>>,
|
material_handle: Option<ROQueryItem<'_, '_, Self::ItemQuery>>,
|
||||||
materials: SystemParamItem<'w, '_, Self::Param>,
|
materials: SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
) -> RenderCommandResult {
|
) -> RenderCommandResult {
|
||||||
|
@ -137,7 +137,7 @@ fn print_components_iter_mut(
|
|||||||
println!("Print components (iter_mut):");
|
println!("Print components (iter_mut):");
|
||||||
for e in &mut query {
|
for e in &mut query {
|
||||||
// Re-declaring the variable to illustrate the type of the actual iterator item.
|
// Re-declaring the variable to illustrate the type of the actual iterator item.
|
||||||
let e: CustomQueryItem<'_, _, _> = e;
|
let e: CustomQueryItem<'_, '_, _, _> = e;
|
||||||
println!("Entity: {}", e.entity);
|
println!("Entity: {}", e.entity);
|
||||||
println!("A: {:?}", e.a);
|
println!("A: {:?}", e.a);
|
||||||
println!("B: {:?}", e.b);
|
println!("B: {:?}", e.b);
|
||||||
@ -155,7 +155,7 @@ fn print_components_iter(
|
|||||||
println!("Print components (iter):");
|
println!("Print components (iter):");
|
||||||
for e in &query {
|
for e in &query {
|
||||||
// Re-declaring the variable to illustrate the type of the actual iterator item.
|
// Re-declaring the variable to illustrate the type of the actual iterator item.
|
||||||
let e: CustomQueryReadOnlyItem<'_, _, _> = e;
|
let e: CustomQueryReadOnlyItem<'_, '_, _, _> = e;
|
||||||
println!("Entity: {}", e.entity);
|
println!("Entity: {}", e.entity);
|
||||||
println!("A: {:?}", e.a);
|
println!("A: {:?}", e.a);
|
||||||
println!("B: {:?}", e.b);
|
println!("B: {:?}", e.b);
|
||||||
|
@ -73,8 +73,8 @@ where
|
|||||||
|
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
_: &P,
|
_: &P,
|
||||||
_: ROQueryItem<'w, Self::ViewQuery>,
|
_: ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
_: Option<ROQueryItem<'w, Self::ItemQuery>>,
|
_: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
|
||||||
custom_phase_item_buffers: SystemParamItem<'w, '_, Self::Param>,
|
custom_phase_item_buffers: SystemParamItem<'w, '_, Self::Param>,
|
||||||
pass: &mut TrackedRenderPass<'w>,
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
) -> RenderCommandResult {
|
) -> RenderCommandResult {
|
||||||
|
@ -588,7 +588,7 @@ impl ViewNode for CustomDrawNode {
|
|||||||
&self,
|
&self,
|
||||||
graph: &mut RenderGraphContext,
|
graph: &mut RenderGraphContext,
|
||||||
render_context: &mut RenderContext<'w>,
|
render_context: &mut RenderContext<'w>,
|
||||||
(camera, view, target): QueryItem<'w, Self::ViewQuery>,
|
(camera, view, target): QueryItem<'w, '_, Self::ViewQuery>,
|
||||||
world: &'w World,
|
world: &'w World,
|
||||||
) -> Result<(), NodeRunError> {
|
) -> Result<(), NodeRunError> {
|
||||||
// First, we need to get our phases resource
|
// First, we need to get our phases resource
|
||||||
|
@ -88,7 +88,7 @@ impl ExtractComponent for InstanceMaterialData {
|
|||||||
type QueryFilter = ();
|
type QueryFilter = ();
|
||||||
type Out = Self;
|
type Out = Self;
|
||||||
|
|
||||||
fn extract_component(item: QueryItem<'_, Self::QueryData>) -> Option<Self> {
|
fn extract_component(item: QueryItem<'_, '_, Self::QueryData>) -> Option<Self> {
|
||||||
Some(InstanceMaterialData(item.0.clone()))
|
Some(InstanceMaterialData(item.0.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
title: Query items can borrow from query state
|
||||||
|
pull_requests: [15396]
|
||||||
|
---
|
||||||
|
|
||||||
|
The `QueryData::Item` and `WorldQuery::Fetch` associated types and the `QueryItem` and `ROQueryItem` type aliases now have an additional lifetime parameter corresponding to the `'s` lifetime in `Query`.
|
||||||
|
Manual implementations of `WorldQuery` and `QueryData` will need to update the method signatures to include the new lifetimes.
|
||||||
|
Other uses of the types will need to be updated to include a lifetime parameter, although it can usually be passed as `'_`.
|
||||||
|
In particular, `ROQueryItem` is used when implementing `RenderCommand`.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// 0.16
|
||||||
|
fn render<'w>(
|
||||||
|
item: &P,
|
||||||
|
view: ROQueryItem<'w, Self::ViewQuery>,
|
||||||
|
entity: Option<ROQueryItem<'w, Self::ItemQuery>>,
|
||||||
|
param: SystemParamItem<'w, '_, Self::Param>,
|
||||||
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
|
) -> RenderCommandResult;
|
||||||
|
|
||||||
|
// 0.17
|
||||||
|
fn render<'w>(
|
||||||
|
item: &P,
|
||||||
|
view: ROQueryItem<'w, '_, Self::ViewQuery>,
|
||||||
|
entity: Option<ROQueryItem<'w, '_, Self::ItemQuery>>,
|
||||||
|
param: SystemParamItem<'w, '_, Self::Param>,
|
||||||
|
pass: &mut TrackedRenderPass<'w>,
|
||||||
|
) -> RenderCommandResult;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Methods on `QueryState` that take `&mut self` may now result in conflicting borrows if the query items capture the lifetime of the mutable reference.
|
||||||
|
This affects `get()`, `iter()`, and others.
|
||||||
|
To fix the errors, first call `QueryState::update_archetypes()`, and then replace a call `state.foo(world, param)` with `state.query_manual(world).foo_inner(param)`.
|
||||||
|
Alternately, you may be able to restructure the code to call `state.query(world)` once and then make multiple calls using the `Query`.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let mut state: QueryState<_, _> = ...;
|
||||||
|
|
||||||
|
// 0.16
|
||||||
|
let d1 = state.get(world, e1);
|
||||||
|
let d2 = state.get(world, e2); // Error: cannot borrow `state` as mutable more than once at a time
|
||||||
|
|
||||||
|
println!("{d1:?}");
|
||||||
|
println!("{d2:?}");
|
||||||
|
|
||||||
|
// 0.17
|
||||||
|
state.update_archetypes(world);
|
||||||
|
let d1 = state.get_manual(world, e1);
|
||||||
|
let d2 = state.get_manual(world, e2);
|
||||||
|
// OR
|
||||||
|
state.update_archetypes(world);
|
||||||
|
let d1 = state.query_manual(world).get_inner(e1);
|
||||||
|
let d2 = state.query_manual(world).get_inner(e2);
|
||||||
|
// OR
|
||||||
|
let query = state.query(world);
|
||||||
|
let d1 = query.get_inner(e1);
|
||||||
|
let d1 = query.get_inner(e2);
|
||||||
|
|
||||||
|
println!("{d1:?}");
|
||||||
|
println!("{d2:?}");
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user