1use broccoli::{aabb::pin::HasInner, aabb::Aabb, Tree};
2
3pub unsafe trait TrustedCollisionPairs {
11 type T;
12 fn for_every_pair(&mut self, func: impl FnMut(&mut Self::T, &mut Self::T));
13}
14
15pub unsafe trait TrustedIterAll {
23 type T;
24 fn for_every(&mut self, func: impl FnMut(&mut Self::T));
25}
26
27pub struct IndTree<'a, 'b, T: Aabb>(pub &'b mut Tree<'a, T>);
31
32unsafe impl<T: Aabb + HasInner> TrustedCollisionPairs for IndTree<'_, '_, T> {
33 type T = T::Inner;
34 fn for_every_pair(&mut self, mut func: impl FnMut(&mut Self::T, &mut Self::T)) {
35 self.0.find_colliding_pairs(|a, b| {
36 func(a.unpack_inner(), b.unpack_inner());
37 })
38 }
39}
40
41unsafe impl<T: Aabb + HasInner> TrustedIterAll for IndTree<'_, '_, T> {
42 type T = T::Inner;
43 fn for_every(&mut self, mut func: impl FnMut(&mut Self::T)) {
44 for a in self
45 .0
46 .get_nodes_mut()
47 .iter_mut()
48 .flat_map(|x| x.into_range())
49 {
50 func(a.unpack_inner());
51 }
52 }
53}
54
55pub struct CacheSession<'a, C> {
59 inner: &'a mut C,
60}
61
62impl<'a, C> CacheSession<'a, C> {
63 pub fn new(a: &'a mut C) -> Self {
64 CacheSession { inner: a }
65 }
66}
67
68pub struct FilterCache<'a, C: TrustedIterAll, D> {
72 inner: *const CacheSession<'a, C>,
73 _p: std::marker::PhantomData<&'a C>,
74 data: Vec<(*mut C::T, D)>,
75}
76unsafe impl<'a, C: TrustedIterAll, D> Send for FilterCache<'a, C, D> {}
77unsafe impl<'a, C: TrustedIterAll, D> Sync for FilterCache<'a, C, D> {}
78
79impl<'a, C: TrustedIterAll, D> FilterCache<'a, C, D> {
80 pub fn handle(&mut self, c: &mut CacheSession<'a, C>) -> &mut [(&mut C::T, D)] {
81 assert_eq!(c as *const _, self.inner);
82
83 let data = self.data.as_mut_slice();
84 unsafe { &mut *(data as *mut _ as *mut _) }
85 }
86}
87
88unsafe impl<'a, C: TrustedCollisionPairs, D> Send for CollidingPairsCache<'a, C, D> {}
89unsafe impl<'a, C: TrustedCollisionPairs, D> Sync for CollidingPairsCache<'a, C, D> {}
90
91pub struct CollidingPairsCache<'a, C: TrustedCollisionPairs, D> {
95 inner: *const CacheSession<'a, C>,
96 _p: std::marker::PhantomData<&'a C>,
97 pairs: Vec<(*mut C::T, *mut C::T, D)>,
98}
99
100impl<'a, C: TrustedCollisionPairs, D> CollidingPairsCache<'a, C, D> {
101 pub fn handle(
102 &mut self,
103 c: &mut CacheSession<'a, C>,
104 mut func: impl FnMut(&mut C::T, &mut C::T, &mut D),
105 ) {
106 assert_eq!(c as *const _, self.inner);
107
108 for (a, b, c) in self.pairs.iter_mut() {
109 let a = unsafe { &mut **a };
110 let b = unsafe { &mut **b };
111 func(a, b, c);
112 }
113 }
114}
115use std::marker::PhantomData;
116
117impl<'a, C: TrustedIterAll> CacheSession<'a, C> {
118 pub fn cache_elems<D>(
119 &mut self,
120 mut func: impl FnMut(&mut C::T) -> Option<D>,
121 ) -> FilterCache<'a, C, D> {
122 let mut data = vec![];
123 self.inner.for_every(|a| {
124 if let Some(d) = func(a) {
125 data.push((a as *mut _, d));
126 }
127 });
128 FilterCache {
129 inner: self as *const _,
130 _p: PhantomData,
131 data,
132 }
133 }
134}
135
136impl<'a, C: TrustedCollisionPairs> CacheSession<'a, C> {
137 pub fn cache_colliding_pairs<D>(
138 &mut self,
139 mut func: impl FnMut(&mut C::T, &mut C::T) -> Option<D>,
140 ) -> CollidingPairsCache<'a, C, D> {
141 let mut pairs = vec![];
142 self.inner.for_every_pair(|a, b| {
143 if let Some(res) = func(a, b) {
144 pairs.push((a as *mut _, b as *mut _, res));
145 }
146 });
147
148 CollidingPairsCache {
149 inner: self as *mut _,
150 _p: PhantomData,
151 pairs,
152 }
153 }
154
155 pub fn finish(self) -> &'a mut C {
156 self.inner
157 }
158}