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// }