Implement IntoIterator for ECS wrapper types. (#5096)

# Objective

Improve ergonomics by passing on the `IntoIterator` impl of the underlying type to wrapper types.

## Solution

Implement `IntoIterator` for ECS wrapper types (Mut, Local, Res, etc.).

Co-authored-by: devil-ira <justthecooldude@gmail.com>
This commit is contained in:
ira 2022-10-24 21:01:08 +00:00
parent 6aa2dce0d1
commit b291223e34
3 changed files with 88 additions and 2 deletions

View File

@ -245,6 +245,31 @@ pub struct ResMut<'a, T: ?Sized + Resource> {
pub(crate) ticks: Ticks<'a>,
}
impl<'w, 'a, T: Resource> IntoIterator for &'a ResMut<'w, T>
where
&'a T: IntoIterator,
{
type Item = <&'a T as IntoIterator>::Item;
type IntoIter = <&'a T as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.value.into_iter()
}
}
impl<'w, 'a, T: Resource> IntoIterator for &'a mut ResMut<'w, T>
where
&'a mut T: IntoIterator,
{
type Item = <&'a mut T as IntoIterator>::Item;
type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.set_changed();
self.value.into_iter()
}
}
change_detection_impl!(ResMut<'a, T>, T, Resource);
impl_methods!(ResMut<'a, T>, T, Resource);
impl_debug!(ResMut<'a, T>, Resource);
@ -298,6 +323,31 @@ pub struct Mut<'a, T: ?Sized> {
pub(crate) ticks: Ticks<'a>,
}
impl<'w, 'a, T> IntoIterator for &'a Mut<'w, T>
where
&'a T: IntoIterator,
{
type Item = <&'a T as IntoIterator>::Item;
type IntoIter = <&'a T as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.value.into_iter()
}
}
impl<'w, 'a, T> IntoIterator for &'a mut Mut<'w, T>
where
&'a mut T: IntoIterator,
{
type Item = <&'a mut T as IntoIterator>::Item;
type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.set_changed();
self.value.into_iter()
}
}
change_detection_impl!(Mut<'a, T>, T,);
impl_methods!(Mut<'a, T>, T,);
impl_debug!(Mut<'a, T>,);

View File

@ -344,6 +344,18 @@ impl<'w, T: Resource> From<ResMut<'w, T>> for Res<'w, T> {
}
}
impl<'w, 'a, T: Resource> IntoIterator for &'a Res<'w, T>
where
&'a T: IntoIterator,
{
type Item = <&'a T as IntoIterator>::Item;
type IntoIter = <&'a T as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.value.into_iter()
}
}
/// The [`SystemParamState`] of [`Res<T>`].
#[doc(hidden)]
pub struct ResState<T> {
@ -719,6 +731,30 @@ impl<'a, T: FromWorld + Send + Sync + 'static> DerefMut for Local<'a, T> {
}
}
impl<'w, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a Local<'w, T>
where
&'a T: IntoIterator,
{
type Item = <&'a T as IntoIterator>::Item;
type IntoIter = <&'a T as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'w, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a mut Local<'w, T>
where
&'a mut T: IntoIterator,
{
type Item = <&'a mut T as IntoIterator>::Item;
type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
/// The [`SystemParamState`] of [`Local<T>`].
#[doc(hidden)]
pub struct LocalState<T: Send + 'static>(pub(crate) SyncCell<T>);

View File

@ -971,7 +971,7 @@ pub(crate) fn assign_lights_to_clusters(
if config.dynamic_resizing() {
let mut cluster_index_estimate = 0.0;
for light in lights.iter() {
for light in &lights {
let light_sphere = light.sphere();
// Check if the light is within the view frustum
@ -1126,7 +1126,7 @@ pub(crate) fn assign_lights_to_clusters(
}
let mut update_from_light_intersections = |visible_lights: &mut Vec<Entity>| {
for light in lights.iter() {
for light in &lights {
let light_sphere = light.sphere();
// Check if the light is within the view frustum