edict/query/modified/mod.rs
1mod alt;
2// mod any_of;
3mod copied;
4mod read;
5mod with;
6mod write;
7
8use crate::epoch::EpochId;
9
10pub use self::{
11 alt::ModifiedFetchAlt, copied::ModifiedFetchCopied, read::ModifiedFetchRead,
12 with::ModifiedFetchWith, write::ModifiedFetchWrite,
13};
14
15/// Query over modified component.
16///
17/// Should be used as either [`Modified<&T>`], [`Modified<&mut T>`]
18/// or [`Modified<Alt<T>>`].
19///
20/// This is tracking query that uses epoch lower bound to filter out entities with unmodified components.
21#[derive(Clone, Copy, Debug)]
22pub struct Modified<T> {
23 after_epoch: EpochId,
24 query: T,
25}
26
27impl<T> Modified<T> {
28 /// Creates new `Modified` query.
29 /// Uses provided `after_epoch` id to skip components that are last modified not after this epoch.
30 pub fn new(after_epoch: EpochId) -> Self
31 where
32 T: Default,
33 {
34 Modified {
35 after_epoch,
36 query: T::default(),
37 }
38 }
39
40 /// Epoch id threshold for this query.
41 pub fn after_epoch(&self) -> EpochId {
42 self.after_epoch
43 }
44}
45
46// /// Query that concerns exactly one specific component.
47// pub trait ComponentQuery: Query {
48// /// Returns archetype component for this query.
49// fn archetype_component(&self, archetype: &Archetype) -> &ArchetypeComponent;
50// }
51
52// /// Query that concerns exactly one specific component.
53// pub trait ComponentFetch<'a>: Fetch<'a> {
54// /// Returns epoch id of the specified chunk
55// fn chunk_epoch(&self, chunk_idx: u32) -> EpochId;
56
57// /// Returns epoch id of the specified item.
58// fn item_epoch(&self, idx: u32) -> EpochId;
59// }
60
61// pub struct ModifiedFetch<'a, F> {
62// fetch: F,
63// after_epoch: EpochId,
64// epoch: EpochId,
65// entity_epochs: NonNull<EpochId>,
66// chunk_epochs: NonNull<Cell<EpochId>>,
67// archetype_epoch: NonNull<Cell<EpochId>>,
68// }
69
70// unsafe impl<'a, F> Fetch<'a> for ModifiedFetch<'a, F>
71// where
72// F: Fetch<'a>,
73// {
74// type Item = F::Item;
75
76// fn dangling() -> Self {}
77// }
78
79// unsafe impl<Q> Query for Modified<Q>
80// where
81// Q: ComponentQuery,
82// {
83// type Item<'a> = Q::Item<'a>;
84// type Fetch<'a> = Q::Fetch<'a>;
85
86// const MUTABLE: bool = true;
87
88// #[inline(always)]
89// fn component_access(&self, comp: &ComponentInfo) -> Result<Option<Access>, WriteAlias> {
90// self.query.component_access(ty)
91// }
92
93// #[inline(always)]
94// fn visit_archetype(&self, archetype: &Archetype) -> bool {
95// self.query.visit_archetype(archetype)
96// }
97
98// #[inline(always)]
99// unsafe fn access_archetype(&self, archetype: &Archetype, mut f: impl FnMut(TypeId, Access)) {
100// self.query.access_archetype(archetype, f);
101// }
102
103// #[inline(always)]
104// fn visit_archetype_late(&self, archetype: &Archetype) -> bool {
105// if !self.query.visit_archetype_late(archetype) {
106// return false;
107// }
108
109// let component = self.query.archetype_component(archetype);
110// unsafe {
111// let data = component.data();
112// data.epoch.after(self.after_epoch)
113// }
114// }
115
116// #[inline(always)]
117// unsafe fn fetch<'a>(
118// &self,
119// _arch_idx: u32,
120// archetype: &'a Archetype,
121// epoch: EpochId,
122// ) -> Option<ModifiedFetch<'a, T>> {
123// match archetype.component(type_id::<T>()) {
124// None => None,
125// Some(component) => {
126// let data = component.data_mut();
127
128// debug_assert!(data.epoch.after(self.after_epoch));
129
130// Some(ModifiedFetchAlt {
131// after_epoch: self.after_epoch,
132// epoch,
133// ptr: data.ptr.cast(),
134// entity_epochs: NonNull::new_unchecked(
135// data.entity_epochs.as_ptr() as *mut EpochId
136// ),
137// chunk_epochs: NonNull::new_unchecked(data.chunk_epochs.as_mut_ptr()).cast(),
138// archetype_epoch: NonNull::from(&mut data.epoch).cast(),
139// marker: PhantomData,
140// })
141// }
142// }
143// }
144// }