Skip to content

Commit f25aa9c

Browse files
committed
state_entity
1 parent 74d9040 commit f25aa9c

File tree

15 files changed

+114
-104
lines changed

15 files changed

+114
-104
lines changed

crates/bevy_audio/src/audio_output.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ pub struct PlaybackDespawnMarker;
5454
pub struct PlaybackRemoveMarker;
5555

5656
#[derive(SystemParam)]
57-
pub(crate) struct EarPositions<'w, 's> {
58-
pub(crate) query: Query<'w, 's, (Entity, &'static GlobalTransform, &'static SpatialListener)>,
57+
pub(crate) struct EarPositions<'w> {
58+
pub(crate) query: Query<'w, 'w, (Entity, &'static GlobalTransform, &'static SpatialListener)>,
5959
}
60-
impl<'w, 's> EarPositions<'w, 's> {
60+
impl<'w> EarPositions<'w> {
6161
/// Gets a set of transformed ear positions.
6262
///
6363
/// If there are no listeners, use the default values. If a user has added multiple

crates/bevy_ecs/compile_fail/tests/ui/system_param_derive_readonly.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@ use bevy_ecs::system::{ReadOnlySystemParam, SystemParam, SystemState};
55
struct Foo;
66

77
#[derive(SystemParam)]
8-
struct Mutable<'w, 's> {
9-
a: Query<'w, 's, &'static mut Foo>,
8+
struct Mutable<'w> {
9+
a: Query<'w, &'static mut Foo>,
1010
}
1111

1212
fn main() {
13-
1413
let mut world = World::default();
1514
let state = SystemState::<Mutable>::new(&mut world);
1615
state.get(&world);

crates/bevy_ecs/src/query/state.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
component::{ComponentId, Tick},
44
entity::{Entity, EntityEquivalent, EntitySet, UniqueEntityArray},
55
entity_disabling::DefaultQueryFilters,
6-
prelude::FromWorld,
6+
prelude::{Component, FromWorld},
77
query::{FilteredAccess, QueryCombinationIter, QueryIter, QueryParIter, WorldQuery},
88
storage::{SparseSetIndex, TableId},
99
system::Query,
@@ -60,6 +60,8 @@ pub(super) union StorageId {
6060
/// [`Fetch`]: crate::query::world_query::WorldQuery::Fetch
6161
/// [`Table`]: crate::storage::Table
6262
#[repr(C)]
63+
#[derive(Component)]
64+
#[component(storage = "SparseSet")]
6365
// SAFETY NOTE:
6466
// Do not add any new fields that use the `D` or `F` generic parameters as this may
6567
// make `QueryState::as_transmuted_state` unsound if not done with care.

crates/bevy_ecs/src/system/builder.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use bevy_platform::cell::SyncCell;
33
use variadics_please::all_tuples;
44

55
use crate::{
6+
component::ComponentId,
7+
entity::Entity,
68
prelude::QueryBuilder,
79
query::{QueryData, QueryFilter, QueryState},
810
resource::Resource,
@@ -212,10 +214,12 @@ impl ParamBuilder {
212214
unsafe impl<'w, 's, D: QueryData + 'static, F: QueryFilter + 'static>
213215
SystemParamBuilder<Query<'w, 's, D, F>> for QueryState<D, F>
214216
{
215-
fn build(self, world: &mut World, system_meta: &mut SystemMeta) -> QueryState<D, F> {
217+
fn build(self, world: &mut World, system_meta: &mut SystemMeta) -> (Entity, ComponentId) {
216218
self.validate_world(world.id());
217219
init_query_param(world, system_meta, &self);
218-
self
220+
let id = world.register_component::<QueryState<D, F>>();
221+
let e = world.spawn(self).id();
222+
(e, id)
219223
}
220224
}
221225

@@ -291,12 +295,14 @@ unsafe impl<
291295
T: FnOnce(&mut QueryBuilder<D, F>),
292296
> SystemParamBuilder<Query<'w, 's, D, F>> for QueryParamBuilder<T>
293297
{
294-
fn build(self, world: &mut World, system_meta: &mut SystemMeta) -> QueryState<D, F> {
298+
fn build(self, world: &mut World, system_meta: &mut SystemMeta) -> (Entity, ComponentId) {
295299
let mut builder = QueryBuilder::new(world);
296300
(self.0)(&mut builder);
297301
let state = builder.build();
298302
init_query_param(world, system_meta, &state);
299-
state
303+
let id = world.register_component::<QueryState<D, F>>();
304+
let e = world.spawn(state).id();
305+
(e, id)
300306
}
301307
}
302308

@@ -965,9 +971,9 @@ mod tests {
965971

966972
#[derive(SystemParam)]
967973
#[system_param(builder)]
968-
struct CustomParam<'w, 's> {
969-
query: Query<'w, 's, ()>,
970-
local: Local<'s, usize>,
974+
struct CustomParam<'w> {
975+
query: Query<'w, 'w, ()>,
976+
local: Local<usize>,
971977
}
972978

973979
#[test]

crates/bevy_ecs/src/system/system_param.rs

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use crate::{
44
bundle::Bundles,
55
change_detection::{MaybeLocation, Ticks, TicksMut},
66
component::{ComponentId, ComponentTicks, Components, Tick},
7-
entity::Entities,
7+
entity::{Entities, Entity},
88
query::{
9-
Access, FilteredAccess, FilteredAccessSet, QueryData, QueryFilter, QuerySingleError,
10-
QueryState, ReadOnlyQueryData,
9+
Access, DebugCheckedUnwrap, FilteredAccess, FilteredAccessSet, QueryData, QueryFilter,
10+
QuerySingleError, QueryState, ReadOnlyQueryData,
1111
},
1212
resource::Resource,
1313
storage::ResourceData,
@@ -65,7 +65,7 @@ use variadics_please::{all_tuples, all_tuples_enumerated};
6565
/// # #[derive(SystemParam)]
6666
/// # struct ParamsExample<'w, 's> {
6767
/// # query:
68-
/// Query<'w, 's, Entity>,
68+
/// Query<'w, 'w, Entity>,
6969
/// # res:
7070
/// Res<'w, SomeResource>,
7171
/// # res_mut:
@@ -171,7 +171,7 @@ use variadics_please::{all_tuples, all_tuples_enumerated};
171171
/// #[derive(SystemParam)]
172172
/// #[system_param(builder)]
173173
/// pub struct CustomParam<'w, 's> {
174-
/// query: Query<'w, 's, ()>,
174+
/// query: Query<'w, 'w, ()>,
175175
/// local: Local<'s, usize>,
176176
/// }
177177
///
@@ -321,13 +321,15 @@ unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> Re
321321
// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
322322
// this Query conflicts with any prior access, a panic will occur.
323323
unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Query<'_, '_, D, F> {
324-
type State = QueryState<D, F>;
325-
type Item<'w, 's> = Query<'w, 's, D, F>;
324+
type State = (Entity, ComponentId);
325+
type Item<'w, 's> = Query<'w, 'w, D, F>;
326326

327327
fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
328-
let state = QueryState::new(world);
328+
let state: QueryState<D, F> = QueryState::new(world);
329329
init_query_param(world, system_meta, &state);
330-
state
330+
let e = world.spawn(state).id();
331+
let id = world.register_component::<QueryState<D, F>>();
332+
(e, id)
331333
}
332334

333335
#[inline]
@@ -336,11 +338,21 @@ unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Qu
336338
system_meta: &SystemMeta,
337339
world: UnsafeWorldCell<'w>,
338340
change_tick: Tick,
339-
) -> Self::Item<'w, 's> {
341+
) -> Self::Item<'w, 'w> {
342+
let state = world
343+
.storages()
344+
.sparse_sets
345+
.get(state.1)
346+
.debug_checked_unwrap()
347+
.get(state.0)
348+
.debug_checked_unwrap()
349+
.assert_unique()
350+
.deref_mut::<QueryState<D, F>>();
340351
// SAFETY: We have registered all of the query's world accesses,
341352
// so the caller ensures that `world` has permission to access any
342353
// world data that the query needs.
343354
// The caller ensures the world matches the one used in init_state.
355+
344356
unsafe { state.query_unchecked_with_ticks(world, system_meta.last_run, change_tick) }
345357
}
346358
}
@@ -386,11 +398,11 @@ fn assert_component_access_compatibility(
386398
// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
387399
// this Query conflicts with any prior access, a panic will occur.
388400
unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Single<'a, D, F> {
389-
type State = QueryState<D, F>;
401+
type State = (Entity, ComponentId);
390402
type Item<'w, 's> = Single<'w, D, F>;
391403

392404
fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
393-
Query::init_state(world, system_meta)
405+
Query::<D, F>::init_state(world, system_meta)
394406
}
395407

396408
#[inline]
@@ -400,10 +412,8 @@ unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam fo
400412
world: UnsafeWorldCell<'w>,
401413
change_tick: Tick,
402414
) -> Self::Item<'w, 's> {
403-
// SAFETY: State ensures that the components it accesses are not accessible somewhere elsewhere.
404-
// The caller ensures the world matches the one used in init_state.
405-
let query =
406-
unsafe { state.query_unchecked_with_ticks(world, system_meta.last_run, change_tick) };
415+
let query: Query<'_, '_, D, F> = Query::get_param(state, system_meta, world, change_tick);
416+
407417
let single = query
408418
.single_inner()
409419
.expect("The query was expected to contain exactly one matching entity.");
@@ -419,12 +429,9 @@ unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam fo
419429
system_meta: &SystemMeta,
420430
world: UnsafeWorldCell,
421431
) -> Result<(), SystemParamValidationError> {
422-
// SAFETY: State ensures that the components it accesses are not mutably accessible elsewhere
423-
// and the query is read only.
424-
// The caller ensures the world matches the one used in init_state.
425-
let query = unsafe {
426-
state.query_unchecked_with_ticks(world, system_meta.last_run, world.change_tick())
427-
};
432+
let query: Query<'_, '_, D, F> =
433+
Query::get_param(state, system_meta, world, world.change_tick());
434+
428435
match query.single_inner() {
429436
Ok(_) => Ok(()),
430437
Err(QuerySingleError::NoEntities(_)) => Err(
@@ -448,11 +455,11 @@ unsafe impl<'a, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOn
448455
unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
449456
for Populated<'_, '_, D, F>
450457
{
451-
type State = QueryState<D, F>;
452-
type Item<'w, 's> = Populated<'w, 's, D, F>;
458+
type State = (Entity, ComponentId);
459+
type Item<'w, 's> = Populated<'w, 'w, D, F>;
453460

454461
fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
455-
Query::init_state(world, system_meta)
462+
Query::<D, F>::init_state(world, system_meta)
456463
}
457464

458465
#[inline]
@@ -461,7 +468,7 @@ unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
461468
system_meta: &SystemMeta,
462469
world: UnsafeWorldCell<'w>,
463470
change_tick: Tick,
464-
) -> Self::Item<'w, 's> {
471+
) -> Self::Item<'w, 'w> {
465472
// SAFETY: Delegate to existing `SystemParam` implementations.
466473
let query = unsafe { Query::get_param(state, system_meta, world, change_tick) };
467474
Populated(query)
@@ -473,12 +480,9 @@ unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
473480
system_meta: &SystemMeta,
474481
world: UnsafeWorldCell,
475482
) -> Result<(), SystemParamValidationError> {
476-
// SAFETY:
477-
// - We have read-only access to the components accessed by query.
478-
// - The caller ensures the world matches the one used in init_state.
479-
let query = unsafe {
480-
state.query_unchecked_with_ticks(world, system_meta.last_run, world.change_tick())
481-
};
483+
// SAFETY: Delegate to existing `SystemParam` implementations.
484+
let query: Query<'_, '_, D, F> =
485+
unsafe { Query::get_param(state, system_meta, world, world.change_tick()) };
482486
if query.is_empty() {
483487
Err(SystemParamValidationError::skipped::<Self>(
484488
"No matching entities",
@@ -2573,11 +2577,10 @@ mod tests {
25732577
#[derive(SystemParam)]
25742578
pub struct SpecialQuery<
25752579
'w,
2576-
's,
25772580
D: QueryData + Send + Sync + 'static,
25782581
F: QueryFilter + Send + Sync + 'static = (),
25792582
> {
2580-
_query: Query<'w, 's, D, F>,
2583+
_query: Query<'w, 'w, D, F>,
25812584
}
25822585

25832586
fn my_system(_: SpecialQuery<(), ()>) {}
@@ -2706,11 +2709,11 @@ mod tests {
27062709
#[test]
27072710
fn system_param_where_clause() {
27082711
#[derive(SystemParam)]
2709-
pub struct WhereParam<'w, 's, D>
2712+
pub struct WhereParam<'w, D>
27102713
where
27112714
D: 'static + QueryData,
27122715
{
2713-
_q: Query<'w, 's, D, ()>,
2716+
_q: Query<'w, 'w, D, ()>,
27142717
}
27152718

27162719
fn my_system(_: WhereParam<()>) {}

crates/bevy_input_focus/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,13 @@ pub trait IsFocused {
293293
///
294294
/// When working with the entire [`World`], consider using the [`IsFocused`] instead.
295295
#[derive(SystemParam)]
296-
pub struct IsFocusedHelper<'w, 's> {
297-
parent_query: Query<'w, 's, &'static ChildOf>,
296+
pub struct IsFocusedHelper<'w> {
297+
parent_query: Query<'w, 'w, &'static ChildOf>,
298298
input_focus: Option<Res<'w, InputFocus>>,
299299
input_focus_visible: Option<Res<'w, InputFocusVisible>>,
300300
}
301301

302-
impl IsFocused for IsFocusedHelper<'_, '_> {
302+
impl IsFocused for IsFocusedHelper<'_> {
303303
fn is_focused(&self, entity: Entity) -> bool {
304304
self.input_focus
305305
.as_deref()

crates/bevy_input_focus/src/tab_navigation.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,21 +150,21 @@ pub enum TabNavigationError {
150150
/// An injectable helper object that provides tab navigation functionality.
151151
#[doc(hidden)]
152152
#[derive(SystemParam)]
153-
pub struct TabNavigation<'w, 's> {
153+
pub struct TabNavigation<'w> {
154154
// Query for tab groups.
155-
tabgroup_query: Query<'w, 's, (Entity, &'static TabGroup, &'static Children)>,
155+
tabgroup_query: Query<'w, 'w, (Entity, &'static TabGroup, &'static Children)>,
156156
// Query for tab indices.
157157
tabindex_query: Query<
158158
'w,
159-
's,
159+
'w,
160160
(Entity, Option<&'static TabIndex>, Option<&'static Children>),
161161
Without<TabGroup>,
162162
>,
163163
// Query for parents.
164-
parent_query: Query<'w, 's, &'static ChildOf>,
164+
parent_query: Query<'w, 'w, &'static ChildOf>,
165165
}
166166

167-
impl TabNavigation<'_, '_> {
167+
impl TabNavigation<'_> {
168168
/// Navigate to the desired focusable entity.
169169
///
170170
/// Change the [`NavAction`] to navigate in a different direction.

crates/bevy_picking/src/mesh_picking/ray_cast/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ pub struct MeshRayCast<'w, 's> {
179179
#[doc(hidden)]
180180
pub culling_query: Query<
181181
'w,
182-
's,
182+
'w,
183183
(
184184
Read<InheritedVisibility>,
185185
Read<ViewVisibility>,
@@ -192,7 +192,7 @@ pub struct MeshRayCast<'w, 's> {
192192
#[doc(hidden)]
193193
pub mesh_query: Query<
194194
'w,
195-
's,
195+
'w,
196196
(
197197
Option<Read<Mesh2d>>,
198198
Option<Read<Mesh3d>>,

crates/bevy_text/src/text2d.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl From<String> for Text2d {
131131
pub type Text2dReader<'w, 's> = TextReader<'w, 's, Text2d>;
132132

133133
/// 2d alias for [`TextWriter`].
134-
pub type Text2dWriter<'w, 's> = TextWriter<'w, 's, Text2d>;
134+
pub type Text2dWriter<'w> = TextWriter<'w, Text2d>;
135135

136136
/// This system extracts the sprites from the 2D text components and adds them to the
137137
/// "render world".

0 commit comments

Comments
 (0)