ecs: use Mut<T> tracking pointer everywhere

This commit is contained in:
Carter Anderson 2020-07-18 02:09:55 -07:00
parent bf164a5936
commit 19fe299f5a
24 changed files with 268 additions and 312 deletions

View File

@ -38,7 +38,7 @@ impl Timer {
}
pub fn timer_system(time: Res<Time>, mut query: Query<&mut Timer>) {
for timer in &mut query.iter() {
for mut timer in &mut query.iter() {
timer.tick(time.delta_seconds);
}
}

View File

@ -68,7 +68,7 @@ fn iterate_100k(b: &mut Bencher) {
world.spawn((Position(-(i as f32)), Velocity(i as f32)));
}
b.iter(|| {
for (pos, vel) in &mut world.query::<(&mut Position, &Velocity)>() {
for (mut pos, vel) in &mut world.query::<(&mut Position, &Velocity)>() {
pos.0 += vel.0;
}
})

View File

@ -80,7 +80,7 @@ pub use borrow::{EntityRef, Ref, RefMut};
pub use bundle::{Bundle, DynamicBundle, MissingComponent};
pub use entities::{Entity, Location, NoSuchEntity};
pub use entity_builder::{BuiltEntity, EntityBuilder};
pub use query::{Access, BatchedIter, Query, QueryBorrow, QueryIter, With, Without};
pub use query::{Access, BatchedIter, Query, QueryBorrow, QueryIter, With, Without, Mut, Changed};
pub use query_one::QueryOne;
pub use world::{ArchetypesGeneration, Component, ComponentError, Iter, SpawnBatchIter, World};

View File

@ -14,7 +14,7 @@
// modified by Bevy contributors
use core::{marker::PhantomData, ptr::NonNull};
use core::{marker::PhantomData, ptr::NonNull, ops::{Deref, DerefMut}};
use crate::{archetype::Archetype, Component, Entity};
@ -140,40 +140,7 @@ impl<'a, T: Component> Fetch<'a> for FetchRead<T> {
}
impl<'a, T: Component> Query for &'a mut T {
type Fetch = FetchWrite<T>;
}
#[doc(hidden)]
pub struct FetchWrite<T>(NonNull<T>);
impl<'a, T: Component> Fetch<'a> for FetchWrite<T> {
type Item = &'a mut T;
fn access(archetype: &Archetype) -> Option<Access> {
if archetype.has::<T>() {
Some(Access::Write)
} else {
None
}
}
fn borrow(archetype: &Archetype) {
archetype.borrow_mut::<T>();
}
unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option<Self> {
archetype
.get::<T>()
.map(|x| Self(NonNull::new_unchecked(x.as_ptr().add(offset))))
}
fn release(archetype: &Archetype) {
archetype.release_mut::<T>();
}
unsafe fn next(&mut self) -> &'a mut T {
let x = self.0.as_ptr();
self.0 = NonNull::new_unchecked(x.add(1));
&mut *x
}
type Fetch = FetchMut<T>;
}
impl<T: Query> Query for Option<T> {
@ -665,8 +632,129 @@ macro_rules! tuple_impl {
//smaller_tuples_too!(tuple_impl, B, A);
smaller_tuples_too!(tuple_impl, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A);
/// Unique borrow of an entity's component
pub struct Mut<'a, T: Component> {
value: &'a mut T,
modified: &'a mut bool,
}
unsafe impl<T: Component> Send for Mut<'_, T> {}
unsafe impl<T: Component> Sync for Mut<'_, T> {}
impl<'a, T: Component> Deref for Mut<'a, T> {
type Target = T;
fn deref(&self) -> &T {
self.value
}
}
impl<'a, T: Component> DerefMut for Mut<'a, T> {
fn deref_mut(&mut self) -> &mut T {
*self.modified = true;
self.value
}
}
impl<'a, T: Component> Query for Mut<'a, T> {
type Fetch = FetchMut<T>;
}
#[doc(hidden)]
pub struct FetchMut<T>(NonNull<T>, NonNull<bool>);
impl<'a, T: Component> Fetch<'a> for FetchMut<T> {
type Item = Mut<'a, T>;
fn access(archetype: &Archetype) -> Option<Access> {
if archetype.has::<T>() {
Some(Access::Write)
} else {
None
}
}
fn borrow(archetype: &Archetype) {
archetype.borrow_mut::<T>();
}
unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option<Self> {
archetype
.get_with_modified::<T>()
.map(|(components, modified)| {
Self(
NonNull::new_unchecked(components.as_ptr().add(offset)),
NonNull::new_unchecked(modified.as_ptr().add(offset)),
)
})
}
fn release(archetype: &Archetype) {
archetype.release_mut::<T>();
}
unsafe fn next(&mut self) -> Mut<'a, T> {
let component = self.0.as_ptr();
let modified = self.1.as_ptr();
self.0 = NonNull::new_unchecked(component.add(1));
self.1 = NonNull::new_unchecked(modified.add(1));
Mut {
value: &mut *component,
modified: &mut *modified,
}
}
}
#[allow(missing_docs)]
pub struct Changed<T, Q>(PhantomData<(Q, fn(T))>);
impl<T: Component, Q: Query> Query for Changed<T, Q> {
type Fetch = FetchChanged<T, Q::Fetch>;
}
#[doc(hidden)]
pub struct FetchChanged<T, F>(F, PhantomData<fn(T)>, NonNull<bool>);
impl<'a, T: Component, F: Fetch<'a>> Fetch<'a> for FetchChanged<T, F> {
type Item = F::Item;
fn access(archetype: &Archetype) -> Option<Access> {
if archetype.has::<T>() {
F::access(archetype)
} else {
None
}
}
fn borrow(archetype: &Archetype) {
F::borrow(archetype)
}
unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option<Self> {
if !archetype.has::<T>() {
return None;
}
Some(Self(
F::get(archetype, offset)?,
PhantomData,
NonNull::new_unchecked(archetype.get_modified::<T>()?.as_ptr().add(offset)),
))
}
fn release(archetype: &Archetype) {
F::release(archetype)
}
unsafe fn should_skip(&self) -> bool {
// skip if the current item wasn't changed
!*self.2.as_ref() || self.0.should_skip()
}
unsafe fn next(&mut self) -> F::Item {
self.2 = NonNull::new_unchecked(self.2.as_ptr().add(1));
self.0.next()
}
}
#[cfg(test)]
mod tests {
use crate::{Entity, World, Mut, Changed};
use std::{vec::Vec, vec};
use super::*;
#[test]
@ -675,4 +763,98 @@ mod tests {
assert!(Access::Read > Access::Iterate);
assert!(Some(Access::Iterate) > None);
}
}
struct A(usize);
struct B(usize);
struct C;
#[test]
fn modified_trackers() {
let mut world = World::default();
let e1 = world.spawn((A(0), B(0)));
let e2 = world.spawn((A(0), B(0)));
let e3 = world.spawn((A(0), B(0)));
world.spawn((A(0), B));
for (i, mut a) in world.query::<Mut<A>>().iter().enumerate() {
if i % 2 == 0 {
a.0 += 1;
}
}
fn get_changed_a(world: &World) -> Vec<Entity> {
world
.query::<Changed<A, Entity>>()
.iter()
.collect::<Vec<Entity>>()
};
assert_eq!(get_changed_a(&world), vec![e1, e3]);
// ensure changing an entity's archetypes also moves its modified state
world.insert(e1, (C,)).unwrap();
assert_eq!(get_changed_a(&world), vec![e3, e1], "changed entities list should not change (although the order will due to archetype moves)");
// spawning a new A entity should not change existing modified state
world.insert(e1, (A(0), B)).unwrap();
assert_eq!(
get_changed_a(&world),
vec![e3, e1],
"changed entities list should not change"
);
// removing an unchanged entity should not change modified state
world.despawn(e2).unwrap();
assert_eq!(
get_changed_a(&world),
vec![e3, e1],
"changed entities list should not change"
);
// removing a changed entity should remove it from enumeration
world.despawn(e1).unwrap();
assert_eq!(
get_changed_a(&world),
vec![e3],
"e1 should no longer be returned"
);
world.clear_trackers();
assert!(world
.query::<Changed<A, Entity>>()
.iter()
.collect::<Vec<Entity>>()
.is_empty());
}
#[test]
fn nested_changed_query() {
let mut world = World::default();
world.spawn((A(0), B(0)));
let e2 = world.spawn((A(0), B(0)));
world.spawn((A(0), B(0)));
for mut a in world.query::<Mut<A>>().iter() {
a.0 += 1;
}
for mut b in world.query::<Mut<B>>().iter().skip(1).take(1) {
b.0 += 1;
}
let a_b_changed = world
.query::<Changed<A, Changed<B, Entity>>>()
.iter()
.collect::<Vec<Entity>>();
assert_eq!(a_b_changed, vec![e2]);
let a_b_changed_tuple = world
.query::<(Changed<A, Entity>, Changed<B, &B>)>()
.iter()
.map(|(e, _b)| e)
.collect::<Vec<Entity>>();
assert_eq!(a_b_changed_tuple, vec![e2]);
}
}

View File

@ -6,7 +6,7 @@ mod world;
pub use resource::*;
pub use schedule::*;
pub use system::{*, Query};
pub use system::{Query, *};
pub use world::*;
pub mod prelude {
@ -15,7 +15,7 @@ pub mod prelude {
system::{
Commands, IntoForEachSystem, IntoQuerySystem, IntoThreadLocalSystem, Query, System,
},
world::{WorldBuilderSource, Track},
world::WorldBuilderSource,
Bundle, Component, Entity, Ref, RefMut, With, Without, World,
};
}

View File

@ -1,224 +0,0 @@
use crate::{Archetype, Component, HecsQuery};
use hecs::{Access, Fetch};
use std::{
marker::PhantomData,
ops::{Deref, DerefMut},
ptr::NonNull,
};
/// Unique borrow of an entity's component
pub struct Track<'a, T: Component> {
value: &'a mut T,
modified: &'a mut bool,
}
unsafe impl<T: Component> Send for Track<'_, T> {}
unsafe impl<T: Component> Sync for Track<'_, T> {}
impl<'a, T: Component> Deref for Track<'a, T> {
type Target = T;
fn deref(&self) -> &T {
self.value
}
}
impl<'a, T: Component> DerefMut for Track<'a, T> {
fn deref_mut(&mut self) -> &mut T {
*self.modified = true;
self.value
}
}
impl<'a, T: Component> HecsQuery for Track<'a, T> {
type Fetch = FetchTrack<T>;
}
#[doc(hidden)]
pub struct FetchTrack<T>(NonNull<T>, NonNull<bool>);
impl<'a, T: Component> Fetch<'a> for FetchTrack<T> {
type Item = Track<'a, T>;
fn access(archetype: &Archetype) -> Option<Access> {
if archetype.has::<T>() {
Some(Access::Write)
} else {
None
}
}
fn borrow(archetype: &Archetype) {
archetype.borrow_mut::<T>();
}
unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option<Self> {
archetype
.get_with_modified::<T>()
.map(|(components, modified)| {
Self(
NonNull::new_unchecked(components.as_ptr().add(offset)),
NonNull::new_unchecked(modified.as_ptr().add(offset)),
)
})
}
fn release(archetype: &Archetype) {
archetype.release_mut::<T>();
}
unsafe fn next(&mut self) -> Track<'a, T> {
let component = self.0.as_ptr();
let modified = self.1.as_ptr();
self.0 = NonNull::new_unchecked(component.add(1));
self.1 = NonNull::new_unchecked(modified.add(1));
Track {
value: &mut *component,
modified: &mut *modified,
}
}
}
pub struct Changed<T, Q>(PhantomData<(Q, fn(T))>);
impl<T: Component, Q: HecsQuery> HecsQuery for Changed<T, Q> {
type Fetch = FetchChanged<T, Q::Fetch>;
}
#[doc(hidden)]
pub struct FetchChanged<T, F>(F, PhantomData<fn(T)>, NonNull<bool>);
impl<'a, T: Component, F: Fetch<'a>> Fetch<'a> for FetchChanged<T, F> {
type Item = F::Item;
fn access(archetype: &Archetype) -> Option<Access> {
if archetype.has::<T>() {
F::access(archetype)
} else {
None
}
}
fn borrow(archetype: &Archetype) {
F::borrow(archetype)
}
unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option<Self> {
if !archetype.has::<T>() {
return None;
}
Some(Self(
F::get(archetype, offset)?,
PhantomData,
NonNull::new_unchecked(archetype.get_modified::<T>()?.as_ptr().add(offset)),
))
}
fn release(archetype: &Archetype) {
F::release(archetype)
}
unsafe fn should_skip(&self) -> bool {
// skip if the current item wasn't changed
!*self.2.as_ref() || self.0.should_skip()
}
unsafe fn next(&mut self) -> F::Item {
self.2 = NonNull::new_unchecked(self.2.as_ptr().add(1));
self.0.next()
}
}
#[cfg(test)]
mod tests {
use crate::{Changed, Track};
use hecs::{Entity, World};
struct A(usize);
struct B(usize);
struct C;
#[test]
fn modified_trackers() {
let mut world = World::default();
let e1 = world.spawn((A(0), B(0)));
let e2 = world.spawn((A(0), B(0)));
let e3 = world.spawn((A(0), B(0)));
world.spawn((A(0), B));
for (i, mut a) in world.query::<Track<A>>().iter().enumerate() {
if i % 2 == 0 {
a.0 += 1;
}
}
fn get_changed_a(world: &World) -> Vec<Entity> {
world
.query::<Changed<A, Entity>>()
.iter()
.collect::<Vec<Entity>>()
};
assert_eq!(get_changed_a(&world), vec![e1, e3]);
// ensure changing an entity's archetypes also moves its modified state
world.insert(e1, (C,)).unwrap();
assert_eq!(get_changed_a(&world), vec![e3, e1], "changed entities list should not change (although the order will due to archetype moves)");
// spawning a new A entity should not change existing modified state
world.insert(e1, (A(0), B)).unwrap();
assert_eq!(
get_changed_a(&world),
vec![e3, e1],
"changed entities list should not change"
);
// removing an unchanged entity should not change modified state
world.despawn(e2).unwrap();
assert_eq!(
get_changed_a(&world),
vec![e3, e1],
"changed entities list should not change"
);
// removing a changed entity should remove it from enumeration
world.despawn(e1).unwrap();
assert_eq!(
get_changed_a(&world),
vec![e3],
"e1 should no longer be returned"
);
world.clear_trackers();
assert!(world
.query::<Changed<A, Entity>>()
.iter()
.collect::<Vec<Entity>>()
.is_empty());
}
#[test]
fn nested_changed_query() {
let mut world = World::default();
world.spawn((A(0), B(0)));
let e2 = world.spawn((A(0), B(0)));
world.spawn((A(0), B(0)));
for mut a in world.query::<Track<A>>().iter() {
a.0 += 1;
}
for mut b in world.query::<Track<B>>().iter().skip(1).take(1) {
b.0 += 1;
}
let a_b_changed = world
.query::<Changed<A, Changed<B, Entity>>>()
.iter()
.collect::<Vec<Entity>>();
assert_eq!(a_b_changed, vec![e2]);
let a_b_changed_tuple = world
.query::<(Changed<A, Entity>, Changed<B, &B>)>()
.iter()
.map(|(e, _b)| e)
.collect::<Vec<Entity>>();
assert_eq!(a_b_changed_tuple, vec![e2]);
}
}

View File

@ -1,5 +1,3 @@
mod component;
mod world_builder;
pub use world_builder::*;
pub use component::*;
pub use world_builder::*;

View File

@ -62,7 +62,7 @@ pub fn camera_system<T: CameraProjection + Component>(
}
}
for (mut camera, camera_projection) in &mut query.iter() {
for (mut camera, mut camera_projection) in &mut query.iter() {
if let Some(window) = match camera.window {
WindowReference::Id(id) => {
if changed_window_ids.contains(&id) {

View File

@ -26,7 +26,7 @@ pub fn visible_entities_system(
mut draw_query: Query<(Entity, &Draw)>,
draw_transform_query: Query<(&Draw, &Transform)>,
) {
for (_camera, camera_transform, visible_entities) in &mut camera_query.iter() {
for (_camera, camera_transform, mut visible_entities) in &mut camera_query.iter() {
visible_entities.value.clear();
let camera_position = camera_transform.value.w_axis().truncate();

View File

@ -392,7 +392,7 @@ pub trait Drawable {
}
pub fn clear_draw_system(mut query: Query<&mut Draw>) {
for draw in &mut query.iter() {
for mut draw in &mut query.iter() {
draw.clear_render_commands();
}
}

View File

@ -479,7 +479,7 @@ pub fn mesh_resource_provider_system(
}
// TODO: remove this once batches are pipeline specific and deprecate assigned_meshes draw target
for (handle, render_pipelines) in &mut query.iter() {
for (handle, mut render_pipelines) in &mut query.iter() {
if let Some(mesh) = meshes.get(&handle) {
for render_pipeline in render_pipelines.pipelines.iter_mut() {
render_pipeline.specialization.primitive_topology = mesh.primitive_topology;

View File

@ -438,7 +438,7 @@ fn render_resources_node_system<T: RenderResources>(
.uniform_buffer_arrays
.update_staging_buffer(render_resource_context);
for (uniforms, draw, render_pipelines) in &mut query.iter() {
for (uniforms, draw, mut render_pipelines) in &mut query.iter() {
if !draw.is_visible {
return;
}
@ -456,7 +456,7 @@ fn render_resources_node_system<T: RenderResources>(
staging_buffer,
0..state.uniform_buffer_arrays.staging_buffer_size as u64,
&mut |mut staging_buffer, _render_resource_context| {
for (uniforms, draw, render_pipelines) in &mut query.iter() {
for (uniforms, draw, mut render_pipelines) in &mut query.iter() {
if !draw.is_visible {
return;
}
@ -479,7 +479,7 @@ fn render_resources_node_system<T: RenderResources>(
} else {
// TODO: can we just remove this?
let mut staging_buffer: [u8; 0] = [];
for (uniforms, draw, render_pipelines) in &mut query.iter() {
for (uniforms, draw, mut render_pipelines) in &mut query.iter() {
if !draw.is_visible {
return;
}
@ -657,7 +657,7 @@ fn asset_render_resources_node_system<T: RenderResources>(
}
}
for (asset_handle, _draw, render_pipelines) in &mut query.iter() {
for (asset_handle, _draw, mut render_pipelines) in &mut query.iter() {
if let Some(asset_bindings) = asset_render_resource_bindings.get(*asset_handle) {
render_pipelines.bindings.extend(asset_bindings);
}

View File

@ -59,7 +59,7 @@ pub fn shader_defs_system<T>(mut query: Query<(&T, &mut RenderPipelines)>)
where
T: ShaderDefs + Send + Sync + 'static,
{
for (shader_defs, render_pipelines) in &mut query.iter() {
for (shader_defs, mut render_pipelines) in &mut query.iter() {
for shader_def in shader_defs.iter_shader_defs() {
for render_pipeline in render_pipelines.pipelines.iter_mut() {
render_pipeline
@ -73,7 +73,7 @@ where
}
pub fn clear_shader_defs_system(mut query: Query<&mut RenderPipelines>) {
for render_pipelines in &mut query.iter() {
for mut render_pipelines in &mut query.iter() {
for render_pipeline in render_pipelines.pipelines.iter_mut() {
render_pipeline
.specialization
@ -90,7 +90,7 @@ pub fn asset_shader_defs_system<T>(
) where
T: ShaderDefs + Send + Sync + 'static,
{
for (asset_handle, render_pipelines) in &mut query.iter() {
for (asset_handle, mut render_pipelines) in &mut query.iter() {
let shader_defs = assets.get(&asset_handle).unwrap();
for shader_def in shader_defs.iter_shader_defs() {
for render_pipeline in render_pipelines.pipelines.iter_mut() {

View File

@ -23,7 +23,7 @@ pub fn sprite_system(
textures: Res<Assets<Texture>>,
mut query: Query<(&mut Sprite, &Handle<ColorMaterial>)>,
) {
for (sprite, handle) in &mut query.iter() {
for (mut sprite, handle) in &mut query.iter() {
let material = materials.get(&handle).unwrap();
if let Some(texture_handle) = material.texture {
if let Some(texture) = textures.get(&texture_handle) {

View File

@ -40,7 +40,7 @@ pub fn parent_update_system(
let mut children_additions = HashMap::<Entity, SmallVec<[Entity; 8]>>::with_capacity(16);
// Entities with a changed Parent (that also have a PreviousParent, even if None)
for (entity, parent, previous_parent) in &mut changed_parent_query.iter() {
for (entity, parent, mut previous_parent) in &mut changed_parent_query.iter() {
log::trace!("Parent changed for {:?}", entity);
// If the `PreviousParent` is not None.

View File

@ -13,7 +13,7 @@ pub fn local_transform_translation_system(
>,
>,
) {
for (local, translation) in &mut query.iter() {
for (mut local, translation) in &mut query.iter() {
*local = LocalTransform(Mat4::from_translation(translation.0));
}
}
@ -26,7 +26,7 @@ pub fn local_transform_rotation_system(
>,
>,
) {
for (local, rotation) in &mut query.iter() {
for (mut local, rotation) in &mut query.iter() {
*local = LocalTransform(Mat4::from_quat(rotation.0));
}
}
@ -39,7 +39,7 @@ pub fn local_transform_scale_system(
>,
>,
) {
for (local, scale) in &mut query.iter() {
for (mut local, scale) in &mut query.iter() {
*local = LocalTransform(Mat4::from_scale(Vec3::new(scale.0, scale.0, scale.0)));
}
}
@ -52,7 +52,7 @@ pub fn local_transform_non_uniform_scale_system(
>,
>,
) {
for (local, non_uniform_scale) in &mut query.iter() {
for (mut local, non_uniform_scale) in &mut query.iter() {
*local = LocalTransform(Mat4::from_scale(non_uniform_scale.0));
}
}
@ -62,7 +62,7 @@ pub fn local_transform_translation_rotation_system(
Without<Scale, Without<NonUniformScale, (&mut LocalTransform, &Translation, &Rotation)>>,
>,
) {
for (local, translation, rotation) in &mut query.iter() {
for (mut local, translation, rotation) in &mut query.iter() {
*local = LocalTransform(Mat4::from_rotation_translation(rotation.0, translation.0));
}
}
@ -72,7 +72,7 @@ pub fn local_transform_translation_scale_system(
Without<Rotation, Without<NonUniformScale, (&mut LocalTransform, &Translation, &Scale)>>,
>,
) {
for (local, translation, scale) in &mut query.iter() {
for (mut local, translation, scale) in &mut query.iter() {
*local = LocalTransform(Mat4::from_scale_rotation_translation(
Vec3::new(scale.0, scale.0, scale.0),
Quat::default(),
@ -86,7 +86,7 @@ pub fn local_transform_translation_non_uniform_scale_system(
Without<Rotation, Without<Scale, (&mut LocalTransform, &Translation, &NonUniformScale)>>,
>,
) {
for (local, translation, non_uniform_scale) in &mut query.iter() {
for (mut local, translation, non_uniform_scale) in &mut query.iter() {
*local = LocalTransform(Mat4::from_scale_rotation_translation(
non_uniform_scale.0,
Quat::default(),
@ -100,7 +100,7 @@ pub fn local_transform_rotation_scale_system(
Without<Translation, Without<NonUniformScale, (&mut LocalTransform, &Rotation, &Scale)>>,
>,
) {
for (local, rotation, scale) in &mut query.iter() {
for (mut local, rotation, scale) in &mut query.iter() {
*local = LocalTransform(Mat4::from_scale_rotation_translation(
Vec3::new(scale.0, scale.0, scale.0),
rotation.0,
@ -114,7 +114,7 @@ pub fn local_transform_rotation_non_uniform_scale_system(
Without<Translation, Without<Scale, (&mut LocalTransform, &Rotation, &NonUniformScale)>>,
>,
) {
for (local, rotation, non_uniform_scale) in &mut query.iter() {
for (mut local, rotation, non_uniform_scale) in &mut query.iter() {
*local = LocalTransform(Mat4::from_scale_rotation_translation(
non_uniform_scale.0,
rotation.0,
@ -128,7 +128,7 @@ pub fn local_transform_translation_rotation_scale_system(
Without<NonUniformScale, (&mut LocalTransform, &Translation, &Rotation, &Scale)>,
>,
) {
for (local, translation, rotation, scale) in &mut query.iter() {
for (mut local, translation, rotation, scale) in &mut query.iter() {
*local = LocalTransform(Mat4::from_scale_rotation_translation(
Vec3::new(scale.0, scale.0, scale.0),
rotation.0,
@ -150,7 +150,7 @@ pub fn local_transform_translation_rotation_non_uniform_scale_system(
>,
>,
) {
for (local, translation, rotation, non_uniform_scale) in &mut query.iter() {
for (mut local, translation, rotation, non_uniform_scale) in &mut query.iter() {
*local = LocalTransform(Mat4::from_scale_rotation_translation(
non_uniform_scale.0,
rotation.0,

View File

@ -10,7 +10,7 @@ pub fn transform_translation_system(
Without<Rotation, Without<Scale, Without<NonUniformScale, (&mut Transform, &Translation)>>>,
>,
) {
for (transform, translation) in &mut query.iter() {
for (mut transform, translation) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -24,7 +24,7 @@ pub fn transform_rotation_system(
Without<Translation, Without<Scale, Without<NonUniformScale, (&mut Transform, &Rotation)>>>,
>,
) {
for (transform, rotation) in &mut query.iter() {
for (mut transform, rotation) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -38,7 +38,7 @@ pub fn transform_scale_system(
Without<Translation, Without<Rotation, Without<NonUniformScale, (&mut Transform, &Scale)>>>,
>,
) {
for (transform, scale) in &mut query.iter() {
for (mut transform, scale) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -52,7 +52,7 @@ pub fn transform_non_uniform_scale_system(
Without<Translation, Without<Rotation, Without<Scale, (&mut Transform, &NonUniformScale)>>>,
>,
) {
for (transform, non_uniform_scale) in &mut query.iter() {
for (mut transform, non_uniform_scale) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -66,7 +66,7 @@ pub fn transform_translation_rotation_system(
Without<Scale, Without<NonUniformScale, (&mut Transform, &Translation, &Rotation)>>,
>,
) {
for (transform, translation, rotation) in &mut query.iter() {
for (mut transform, translation, rotation) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -80,7 +80,7 @@ pub fn transform_translation_scale_system(
Without<Rotation, Without<NonUniformScale, (&mut Transform, &Translation, &Scale)>>,
>,
) {
for (transform, translation, scale) in &mut query.iter() {
for (mut transform, translation, scale) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -98,7 +98,7 @@ pub fn transform_translation_non_uniform_scale_system(
Without<Rotation, Without<Scale, (&mut Transform, &Translation, &NonUniformScale)>>,
>,
) {
for (transform, translation, non_uniform_scale) in &mut query.iter() {
for (mut transform, translation, non_uniform_scale) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -116,7 +116,7 @@ pub fn transform_rotation_scale_system(
Without<Translation, Without<NonUniformScale, (&mut Transform, &Rotation, &Scale)>>,
>,
) {
for (transform, rotation, scale) in &mut query.iter() {
for (mut transform, rotation, scale) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -134,7 +134,7 @@ pub fn transform_rotation_non_uniform_scale_system(
Without<Translation, Without<Scale, (&mut Transform, &Rotation, &NonUniformScale)>>,
>,
) {
for (transform, rotation, non_uniform_scale) in &mut query.iter() {
for (mut transform, rotation, non_uniform_scale) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -150,7 +150,7 @@ pub fn transform_rotation_non_uniform_scale_system(
pub fn transform_translation_rotation_scale_system(
mut query: Query<Without<NonUniformScale, (&mut Transform, &Translation, &Rotation, &Scale)>>,
) {
for (transform, translation, rotation, scale) in &mut query.iter() {
for (mut transform, translation, rotation, scale) in &mut query.iter() {
if !transform.sync {
continue;
}
@ -166,7 +166,7 @@ pub fn transform_translation_rotation_scale_system(
pub fn transform_translation_rotation_non_uniform_scale_system(
mut query: Query<Without<Scale, (&mut Transform, &Translation, &Rotation, &NonUniformScale)>>,
) {
for (transform, translation, rotation, non_uniform_scale) in &mut query.iter() {
for (mut transform, translation, rotation, non_uniform_scale) in &mut query.iter() {
if !transform.sync {
continue;
}

View File

@ -12,7 +12,7 @@ fn animate_sprite_system(
texture_atlases: Res<Assets<TextureAtlas>>,
mut query: Query<(&mut Timer, &mut TextureAtlasSprite, &Handle<TextureAtlas>)>,
) {
for (timer, sprite, texture_atlas_handle) in &mut query.iter() {
for (mut timer, mut sprite, texture_atlas_handle) in &mut query.iter() {
if timer.finished {
let texture_atlas = texture_atlases.get(&texture_atlas_handle).unwrap();
sprite.index = ((sprite.index as usize + 1) % texture_atlas.textures.len()) as u32;

View File

@ -12,7 +12,7 @@ fn main() {
/// rotates the parent, which will result in the child also rotating
fn rotator_system(time: Res<Time>, mut query: Query<(&Rotator, &mut Rotation)>) {
for (_rotator, rotation) in &mut query.iter() {
for (_rotator, mut rotation) in &mut query.iter() {
rotation.0 = rotation.0 * Quat::from_rotation_x(3.0 * time.delta_seconds);
}
}

View File

@ -19,7 +19,7 @@ fn move_cubes(
mut materials: ResMut<Assets<StandardMaterial>>,
mut query: Query<(&mut Translation, &Handle<StandardMaterial>)>,
) {
for (translation, material_handle) in &mut query.iter() {
for (mut translation, material_handle) in &mut query.iter() {
let material = materials.get_mut(&material_handle).unwrap();
translation.0 += Vec3::new(1.0, 0.0, 0.0) * time.delta_seconds;
material.albedo += Color::rgb(-time.delta_seconds, -time.delta_seconds, time.delta_seconds);

View File

@ -85,7 +85,7 @@ fn new_round_system(game_rules: Res<GameRules>, mut game_state: ResMut<GameState
// This system updates the score for each entity with the "Player" and "Score" component.
fn score_system(mut query: Query<(&Player, &mut Score)>) {
for (player, score) in &mut query.iter() {
for (player, mut score) in &mut query.iter() {
let scored_a_point = random::<bool>();
if scored_a_point {
score.value += 1;

View File

@ -159,7 +159,7 @@ fn paddle_movement_system(
keyboard_input: Res<Input<KeyCode>>,
mut query: Query<(&Paddle, &mut Translation)>,
) {
for (paddle, translation) in &mut query.iter() {
for (paddle, mut translation) in &mut query.iter() {
let mut direction = 0.0;
if keyboard_input.pressed(KeyCode::Left) {
direction -= 1.0;
@ -174,7 +174,7 @@ fn paddle_movement_system(
}
fn ball_movement_system(time: Res<Time>, mut ball_query: Query<(&Ball, &mut Translation)>) {
for (ball, translation) in &mut ball_query.iter() {
for (ball, mut translation) in &mut ball_query.iter() {
translation.0 += ball.velocity * time.delta_seconds;
}
}
@ -193,7 +193,7 @@ fn ball_collision_system(
mut brick_query: Query<(Entity, &Brick, &Translation, &Sprite)>,
mut wall_query: Query<(&Wall, &Translation, &Sprite)>,
) {
for (ball, translation, sprite) in &mut ball_query.iter() {
for (mut ball, translation, sprite) in &mut ball_query.iter() {
let ball_position = translation.0;
let ball_size = sprite.size;
let velocity = &mut ball.velocity;

View File

@ -13,7 +13,7 @@ fn main() {
}
fn text_update_system(diagnostics: Res<Diagnostics>, mut query: Query<&mut Label>) {
for label in &mut query.iter() {
for mut label in &mut query.iter() {
if let Some(fps) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS) {
if let Some(average) = fps.average() {
label.text = format!("FPS: {:.2}", average);

View File

@ -13,7 +13,7 @@ fn placement_system(
materials: Res<Assets<ColorMaterial>>,
mut query: Query<(&mut Node, &Handle<ColorMaterial>)>,
) {
for (node, material_handle) in &mut query.iter() {
for (mut node, material_handle) in &mut query.iter() {
let material = materials.get(&material_handle).unwrap();
if material.color.r > 0.2 {
node.position += Vec2::new(0.1 * time.delta_seconds, 0.0);