1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use atomic_refcell::AtomicRefMut;
use crate::{
archetype::{Archetype, Change, Changes, Slice, Slot, StorageBorrow, StorageBorrowMut},
Component, ComponentValue,
};
use super::*;
pub struct PreparedComponentMut<'a, T> {
borrow: StorageBorrowMut<'a, T>,
changes: AtomicRefMut<'a, Changes>,
}
pub struct PreparedComponent<'a, T> {
borrow: StorageBorrow<'a, T>,
}
unsafe impl<'a, T: 'a> PreparedFetch<'a> for PreparedComponent<'a, T> {
type Item = &'a T;
unsafe fn fetch(&mut self, slot: Slot) -> Self::Item {
&*(self.borrow.at(slot) as *const T)
}
}
impl<'a, T> Fetch<'a> for Component<T>
where
T: ComponentValue,
{
const MUTABLE: bool = false;
type Item = &'a T;
type Prepared = PreparedComponent<'a, T>;
fn prepare(&self, archetype: &'a Archetype) -> Option<Self::Prepared> {
let borrow = archetype.storage(*self)?;
Some(PreparedComponent { borrow })
}
fn matches(&self, archetype: &'a Archetype) -> bool {
archetype.has(self.id())
}
}
pub struct Mutable<T>(pub(crate) Component<T>);
impl<'a, T> Fetch<'a> for Mutable<T>
where
T: ComponentValue,
{
const MUTABLE: bool = true;
type Item = &'a mut T;
type Prepared = PreparedComponentMut<'a, T>;
fn prepare(&self, archetype: &'a Archetype) -> Option<Self::Prepared> {
let borrow = archetype.storage_mut(self.0)?;
let changes = archetype.changes_mut(self.0.id())?;
Some(PreparedComponentMut { borrow, changes })
}
fn matches(&self, archetype: &'a Archetype) -> bool {
archetype.has(self.0.id())
}
}
unsafe impl<'a, T: 'a> PreparedFetch<'a> for PreparedComponentMut<'a, T> {
type Item = &'a mut T;
unsafe fn fetch(&mut self, slot: Slot) -> Self::Item {
&mut *(self.borrow.at(slot) as *const T as *mut T)
}
fn set_visited(&mut self, slots: Slice, change_tick: u32) {
eprintln!("Setting changes for {slots:?}: {change_tick}");
self.changes.set(Change::modified(slots, change_tick));
}
}