
# Objective - Provide a generic and _reflectable_ way to iterate over contained entities ## Solution Adds two new traits: * `VisitEntities`: Reflectable iteration, accepts a closure rather than producing an iterator. Implemented by default for `IntoIterator` implementing types. A proc macro is also provided. * A `Mut` variant of the above. Its derive macro uses the same field attribute to avoid repetition. ## Testing Added a test for `VisitEntities` that also transitively tests its derive macro as well as the default `MapEntities` impl.
63 lines
1.9 KiB
Rust
63 lines
1.9 KiB
Rust
use crate::entity::{Entity, VisitEntities, VisitEntitiesMut};
|
|
use bevy_reflect::{FromReflect, FromType, PartialReflect};
|
|
|
|
/// For a reflected value, apply an operation to all contained entities.
|
|
///
|
|
/// See [`VisitEntities`] for more details.
|
|
#[derive(Clone)]
|
|
pub struct ReflectVisitEntities {
|
|
visit_entities: fn(&dyn PartialReflect, &mut dyn FnMut(Entity)),
|
|
}
|
|
|
|
impl ReflectVisitEntities {
|
|
/// A general method for applying an operation to all entities in a
|
|
/// reflected component.
|
|
pub fn visit_entities(&self, component: &dyn PartialReflect, f: &mut dyn FnMut(Entity)) {
|
|
(self.visit_entities)(component, f);
|
|
}
|
|
}
|
|
|
|
impl<C: FromReflect + VisitEntities> FromType<C> for ReflectVisitEntities {
|
|
fn from_type() -> Self {
|
|
ReflectVisitEntities {
|
|
visit_entities: |component, f| {
|
|
let concrete = C::from_reflect(component).unwrap();
|
|
concrete.visit_entities(f);
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
/// For a reflected value, apply an operation to mutable references to all
|
|
/// contained entities.
|
|
///
|
|
/// See [`VisitEntitiesMut`] for more details.
|
|
#[derive(Clone)]
|
|
pub struct ReflectVisitEntitiesMut {
|
|
visit_entities_mut: fn(&mut dyn PartialReflect, &mut dyn FnMut(&mut Entity)),
|
|
}
|
|
|
|
impl ReflectVisitEntitiesMut {
|
|
/// A general method for applying an operation to all entities in a
|
|
/// reflected component.
|
|
pub fn visit_entities(
|
|
&self,
|
|
component: &mut dyn PartialReflect,
|
|
f: &mut dyn FnMut(&mut Entity),
|
|
) {
|
|
(self.visit_entities_mut)(component, f);
|
|
}
|
|
}
|
|
|
|
impl<C: FromReflect + VisitEntitiesMut> FromType<C> for ReflectVisitEntitiesMut {
|
|
fn from_type() -> Self {
|
|
ReflectVisitEntitiesMut {
|
|
visit_entities_mut: |component, f| {
|
|
let mut concrete = C::from_reflect(component).unwrap();
|
|
concrete.visit_entities_mut(f);
|
|
component.apply(&concrete);
|
|
},
|
|
}
|
|
}
|
|
}
|