bevy_ecs/
removal_detection.rs1use crate::{
4 component::{Component, ComponentId, ComponentIdFor, Tick},
5 entity::Entity,
6 event::{Event, EventCursor, EventId, EventIterator, EventIteratorWithId, Events},
7 prelude::Local,
8 storage::SparseSet,
9 system::{ReadOnlySystemParam, SystemMeta, SystemParam},
10 world::{unsafe_world_cell::UnsafeWorldCell, World},
11};
12
13use derive_more::derive::Into;
14
15#[cfg(feature = "bevy_reflect")]
16use bevy_reflect::Reflect;
17use core::{
18 fmt::Debug,
19 iter,
20 marker::PhantomData,
21 ops::{Deref, DerefMut},
22 option,
23};
24
25#[derive(Event, Debug, Clone, Into)]
28#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
29#[cfg_attr(feature = "bevy_reflect", reflect(Debug, Clone))]
30pub struct RemovedComponentEntity(Entity);
31
32#[derive(Debug)]
35pub struct RemovedComponentReader<T>
36where
37 T: Component,
38{
39 reader: EventCursor<RemovedComponentEntity>,
40 marker: PhantomData<T>,
41}
42
43impl<T: Component> Default for RemovedComponentReader<T> {
44 fn default() -> Self {
45 Self {
46 reader: Default::default(),
47 marker: PhantomData,
48 }
49 }
50}
51
52impl<T: Component> Deref for RemovedComponentReader<T> {
53 type Target = EventCursor<RemovedComponentEntity>;
54 fn deref(&self) -> &Self::Target {
55 &self.reader
56 }
57}
58
59impl<T: Component> DerefMut for RemovedComponentReader<T> {
60 fn deref_mut(&mut self) -> &mut Self::Target {
61 &mut self.reader
62 }
63}
64
65#[derive(Default, Debug)]
67pub struct RemovedComponentEvents {
68 event_sets: SparseSet<ComponentId, Events<RemovedComponentEntity>>,
69}
70
71impl RemovedComponentEvents {
72 pub fn new() -> Self {
74 Self::default()
75 }
76
77 pub fn update(&mut self) {
80 for (_component_id, events) in self.event_sets.iter_mut() {
81 events.update();
82 }
83 }
84
85 pub fn iter(&self) -> impl Iterator<Item = (&ComponentId, &Events<RemovedComponentEntity>)> {
87 self.event_sets.iter()
88 }
89
90 pub fn get(
92 &self,
93 component_id: impl Into<ComponentId>,
94 ) -> Option<&Events<RemovedComponentEntity>> {
95 self.event_sets.get(component_id.into())
96 }
97
98 pub fn send(&mut self, component_id: impl Into<ComponentId>, entity: Entity) {
100 self.event_sets
101 .get_or_insert_with(component_id.into(), Default::default)
102 .send(RemovedComponentEntity(entity));
103 }
104}
105
106#[derive(SystemParam)]
141pub struct RemovedComponents<'w, 's, T: Component> {
142 component_id: ComponentIdFor<'s, T>,
143 reader: Local<'s, RemovedComponentReader<T>>,
144 event_sets: &'w RemovedComponentEvents,
145}
146
147pub type RemovedIter<'a> = iter::Map<
151 iter::Flatten<option::IntoIter<iter::Cloned<EventIterator<'a, RemovedComponentEntity>>>>,
152 fn(RemovedComponentEntity) -> Entity,
153>;
154
155pub type RemovedIterWithId<'a> = iter::Map<
159 iter::Flatten<option::IntoIter<EventIteratorWithId<'a, RemovedComponentEntity>>>,
160 fn(
161 (&RemovedComponentEntity, EventId<RemovedComponentEntity>),
162 ) -> (Entity, EventId<RemovedComponentEntity>),
163>;
164
165fn map_id_events(
166 (entity, id): (&RemovedComponentEntity, EventId<RemovedComponentEntity>),
167) -> (Entity, EventId<RemovedComponentEntity>) {
168 (entity.clone().into(), id)
169}
170
171impl<'w, 's, T: Component> RemovedComponents<'w, 's, T> {
174 pub fn reader(&self) -> &EventCursor<RemovedComponentEntity> {
176 &self.reader
177 }
178
179 pub fn reader_mut(&mut self) -> &mut EventCursor<RemovedComponentEntity> {
181 &mut self.reader
182 }
183
184 pub fn events(&self) -> Option<&Events<RemovedComponentEntity>> {
186 self.event_sets.get(self.component_id.get())
187 }
188
189 pub fn reader_mut_with_events(
195 &mut self,
196 ) -> Option<(
197 &mut RemovedComponentReader<T>,
198 &Events<RemovedComponentEntity>,
199 )> {
200 self.event_sets
201 .get(self.component_id.get())
202 .map(|events| (&mut *self.reader, events))
203 }
204
205 pub fn read(&mut self) -> RemovedIter<'_> {
209 self.reader_mut_with_events()
210 .map(|(reader, events)| reader.read(events).cloned())
211 .into_iter()
212 .flatten()
213 .map(RemovedComponentEntity::into)
214 }
215
216 pub fn read_with_id(&mut self) -> RemovedIterWithId<'_> {
218 self.reader_mut_with_events()
219 .map(|(reader, events)| reader.read_with_id(events))
220 .into_iter()
221 .flatten()
222 .map(map_id_events)
223 }
224
225 pub fn len(&self) -> usize {
227 self.events()
228 .map(|events| self.reader.len(events))
229 .unwrap_or(0)
230 }
231
232 pub fn is_empty(&self) -> bool {
234 self.events()
235 .is_none_or(|events| self.reader.is_empty(events))
236 }
237
238 pub fn clear(&mut self) {
243 if let Some((reader, events)) = self.reader_mut_with_events() {
244 reader.clear(events);
245 }
246 }
247}
248
249unsafe impl<'a> ReadOnlySystemParam for &'a RemovedComponentEvents {}
251
252unsafe impl<'a> SystemParam for &'a RemovedComponentEvents {
254 type State = ();
255 type Item<'w, 's> = &'w RemovedComponentEvents;
256
257 fn init_state(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
258
259 #[inline]
260 unsafe fn get_param<'w, 's>(
261 _state: &'s mut Self::State,
262 _system_meta: &SystemMeta,
263 world: UnsafeWorldCell<'w>,
264 _change_tick: Tick,
265 ) -> Self::Item<'w, 's> {
266 world.removed_components()
267 }
268}