|
1 | 1 | use super::{
|
2 |
| - super::event::{EventReader, EventWriter, Events, ManualEventReader}, |
3 |
| - Access, Fetch, FetchState, FilteredAccess, WorldQuery, |
| 2 | + super::event::{EventWriter, Events}, |
| 3 | + Access, Fetch, FetchState, FilteredAccess, WorldQuery, WriteFetch, WriteState, |
4 | 4 | };
|
5 | 5 | use crate::{
|
6 | 6 | archetype::{Archetype, ArchetypeComponentId},
|
7 |
| - component::{Component, ComponentId}, |
| 7 | + component::{Component, ComponentId, StorageType}, |
8 | 8 | prelude::World,
|
9 | 9 | storage::{Table, Tables},
|
10 | 10 | };
|
11 |
| -use std::marker::PhantomData; |
| 11 | +use std::any::TypeId; |
12 | 12 |
|
13 | 13 | impl<'a, T: Component> WorldQuery for EventWriter<'a, T> {
|
14 |
| - type Fetch = EventWriterFetch<T>; |
| 14 | + type Fetch = EventWriterFetch<'a, T>; |
15 | 15 | type State = EventWriterState<T>;
|
16 | 16 | }
|
17 | 17 |
|
18 |
| -struct EventWriterFetch<T> { |
19 |
| - marker: PhantomData<T>, |
| 18 | +struct EventWriterFetch<'s, T> { |
| 19 | + /// EventWriter query parameters require write access to &mut Events<T> |
| 20 | + write_fetch: WriteFetch<Events<T>>, |
| 21 | + state: &'s EventWriterState<T>, |
20 | 22 | }
|
21 | 23 |
|
22 |
| -impl<'a, T: Component> Fetch<'a> for EventWriterFetch<T> { |
23 |
| - // EventWriter queries return an EventWriter<T> in each item |
| 24 | +impl<'a, T: Component> Fetch<'a> for EventWriterFetch<'a, T> { |
| 25 | + /// EventWriter queries return an EventWriter<T> in each item |
24 | 26 | type Item = EventWriter<'a, T>;
|
25 |
| - // This is the corresponding S: FetchState type |
| 27 | + /// This is the corresponding S: FetchState type |
26 | 28 | type State = EventWriterState<T>;
|
27 | 29 |
|
| 30 | + /// Checks the storage type of the corresponding Events<T> component |
| 31 | + fn is_dense(&self) -> bool { |
| 32 | + match self.state.event_storage_type { |
| 33 | + StorageType::SparseSet => false, |
| 34 | + StorageType::Table => true, |
| 35 | + } |
| 36 | + } |
| 37 | + |
28 | 38 | unsafe fn init(
|
29 | 39 | world: &World,
|
30 | 40 | state: &Self::State,
|
31 | 41 | last_change_tick: u32,
|
32 | 42 | change_tick: u32,
|
33 | 43 | ) -> Self {
|
| 44 | + EventWriterFetch { |
| 45 | + write_fetch: WriteFetch::<Events<T>>::init( |
| 46 | + world, |
| 47 | + &state.write_state, |
| 48 | + last_change_tick, |
| 49 | + change_tick, |
| 50 | + ), |
| 51 | + state, |
| 52 | + } |
34 | 53 | }
|
35 | 54 |
|
36 |
| - fn is_dense(&self) -> bool {} |
37 |
| - |
38 | 55 | unsafe fn set_archetype(
|
39 | 56 | &mut self,
|
40 | 57 | state: &Self::State,
|
41 | 58 | archetype: &Archetype,
|
42 | 59 | tables: &Tables,
|
43 | 60 | ) {
|
| 61 | + self.write_fetch |
| 62 | + .set_archetype(&state.write_state, archetype, tables); |
44 | 63 | }
|
45 | 64 |
|
46 |
| - unsafe fn set_table(&mut self, state: &Self::State, table: &Table) {} |
| 65 | + unsafe fn set_table(&mut self, state: &Self::State, table: &Table) { |
| 66 | + self.write_fetch.set_table(&state.write_state, table); |
| 67 | + } |
47 | 68 |
|
48 |
| - unsafe fn archetype_fetch(&mut self, archetype_index: usize) -> Self::Item {} |
| 69 | + /// Returns the EventWriter<T> of the next entity when the storage type of the query is sparse |
| 70 | + unsafe fn archetype_fetch(&mut self, archetype_index: usize) -> Self::Item { |
| 71 | + let events = *self.write_fetch.archetype_fetch(archetype_index); |
| 72 | + EventWriter { |
| 73 | + events: &mut events, |
| 74 | + } |
| 75 | + } |
49 | 76 |
|
50 |
| - unsafe fn table_fetch(&mut self, table_row: usize) -> Self::Item {} |
| 77 | + /// Returns the EventWriter<T> of the next entity when the storage type of the query is dense |
| 78 | + unsafe fn table_fetch(&mut self, table_row: usize) -> Self::Item { |
| 79 | + let events = *self.write_fetch.archetype_fetch(table_row); |
| 80 | + EventWriter { |
| 81 | + events: &mut events, |
| 82 | + } |
| 83 | + } |
51 | 84 | }
|
52 | 85 | struct EventWriterState<T> {
|
53 |
| - marker: PhantomData<T>, |
| 86 | + event_component_id: ComponentId, |
| 87 | + event_storage_type: StorageType, |
| 88 | + /// EventWriter query parameters require write access to &mut Events<T> |
| 89 | + write_state: WriteState<Events<T>>, |
54 | 90 | }
|
55 | 91 |
|
56 | 92 | unsafe impl<T: Component> FetchState for EventWriterState<T> {
|
57 |
| - fn init(world: &mut World) -> Self {} |
| 93 | + fn init(world: &mut World) -> Self { |
| 94 | + let event_component_id = world.components.get_id(TypeId::of::<Events<T>>()).unwrap(); |
| 95 | + EventWriterState { |
| 96 | + event_component_id, |
| 97 | + event_storage_type: world |
| 98 | + .components |
| 99 | + .get_info(event_component_id) |
| 100 | + .unwrap() |
| 101 | + .storage_type(), |
| 102 | + write_state: WriteState::<Events<T>>::init(world), |
| 103 | + } |
| 104 | + } |
58 | 105 |
|
59 |
| - fn update_component_access(&self, access: &mut FilteredAccess<ComponentId>) {} |
| 106 | + /// Access is based on &Events<T> |
| 107 | + fn update_component_access(&self, access: &mut FilteredAccess<ComponentId>) { |
| 108 | + if access.access().has_write(self.event_component_id) { |
| 109 | + panic!("&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.", |
| 110 | + std::any::type_name::<Events<T>>()); |
| 111 | + } |
| 112 | + access.add_read(self.event_component_id) |
| 113 | + } |
60 | 114 |
|
| 115 | + /// Access is based on &Events<T> |
61 | 116 | fn update_archetype_component_access(
|
62 | 117 | &self,
|
63 | 118 | archetype: &Archetype,
|
64 | 119 | access: &mut Access<ArchetypeComponentId>,
|
65 | 120 | ) {
|
| 121 | + if let Some(archetype_component_id) = |
| 122 | + archetype.get_archetype_component_id(self.event_component_id) |
| 123 | + { |
| 124 | + access.add_read(archetype_component_id); |
| 125 | + } |
66 | 126 | }
|
67 | 127 |
|
68 |
| - fn matches_archetype(&self, archetype: &Archetype) -> bool {} |
| 128 | + /// Matches based on &Events<T> |
| 129 | + fn matches_archetype(&self, archetype: &Archetype) -> bool { |
| 130 | + archetype.contains(self.event_component_id) |
| 131 | + } |
69 | 132 |
|
70 |
| - fn matches_table(&self, table: &Table) -> bool {} |
| 133 | + /// Matches based on &Events<T> |
| 134 | + fn matches_table(&self, table: &Table) -> bool { |
| 135 | + table.has_column(self.event_component_id) |
| 136 | + } |
71 | 137 | }
|
| 138 | + |
| 139 | +// TODO: add tests |
| 140 | +mod tests {} |
0 commit comments