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