jagua_rs/collision_detection/hazards/
collector.rs1use crate::collision_detection::hazards::{BasicHazardEntity, HazKey, HazardEntity};
2use slotmap::{Key, SecondaryMap};
3
4pub trait HazardCollector {
7 type Entity: HazardEntity;
9
10 fn contains_key(&self, hkey: HazKey) -> bool;
11
12 fn contains_entity(&self, entity: &Self::Entity) -> bool {
13 self.iter().any(|(_, e)| e == entity)
14 }
15
16 fn insert(&mut self, hkey: HazKey, entity: Self::Entity);
17
18 fn remove_by_key(&mut self, hkey: HazKey);
19
20 fn remove_by_entity(&mut self, entity: &Self::Entity) {
21 let hkey = self
22 .iter()
23 .find(|(_, v)| *v == entity)
24 .map(|(hkey, _)| hkey)
25 .expect("entity not found in collector");
26 self.remove_by_key(hkey);
27 }
28
29 fn is_empty(&self) -> bool {
30 self.len() == 0
31 }
32
33 fn len(&self) -> usize;
34
35 fn iter(&self) -> impl Iterator<Item = (HazKey, &Self::Entity)>;
36
37 fn keys(&self) -> impl Iterator<Item = HazKey> {
38 self.iter().map(|(k, _)| k)
39 }
40
41 fn entities(&self) -> impl Iterator<Item = &Self::Entity> {
42 self.iter().map(|(_, e)| e)
43 }
44}
45
46#[derive(Clone, Debug)]
48pub struct BasicHazardCollector<E = BasicHazardEntity> {
49 detected: SecondaryMap<HazKey, E>,
50 detected_key_bits: u64,
55}
56
57impl<E: HazardEntity> BasicHazardCollector<E> {
58 #[must_use]
59 pub fn new() -> Self {
60 Self::with_capacity(0)
61 }
62
63 #[must_use]
64 pub fn with_capacity(capacity: usize) -> Self {
65 Self {
66 detected: SecondaryMap::with_capacity(capacity),
67 detected_key_bits: 0,
68 }
69 }
70
71 pub fn clear(&mut self) {
72 self.detected.clear();
73 self.detected_key_bits = 0;
74 }
75
76 #[must_use]
77 pub fn contains_key(&self, hkey: HazKey) -> bool {
78 self.detected_key_bits & Self::key_bit(hkey) != 0 && self.detected.contains_key(hkey)
79 }
80
81 pub fn insert(&mut self, hkey: HazKey, entity: E) -> Option<E> {
82 self.detected_key_bits |= Self::key_bit(hkey);
83 self.detected.insert(hkey, entity)
84 }
85
86 pub fn remove(&mut self, hkey: HazKey) -> Option<E> {
87 self.detected.remove(hkey)
88 }
89
90 pub fn retain(&mut self, mut predicate: impl FnMut(HazKey, &mut E) -> bool) {
91 self.detected.retain(|key, entity| predicate(key, entity));
92 }
93
94 #[must_use]
95 pub fn is_empty(&self) -> bool {
96 self.detected.is_empty()
97 }
98
99 #[must_use]
100 pub fn len(&self) -> usize {
101 self.detected.len()
102 }
103
104 pub fn iter(&self) -> impl Iterator<Item = (HazKey, &E)> {
105 self.detected.iter()
106 }
107
108 fn key_bit(hkey: HazKey) -> u64 {
109 1 << (hkey.data().as_ffi() & 63)
110 }
111}
112
113impl<E: HazardEntity> Default for BasicHazardCollector<E> {
114 fn default() -> Self {
115 Self::new()
116 }
117}
118
119impl<E: HazardEntity> HazardCollector for BasicHazardCollector<E> {
120 type Entity = E;
121
122 fn contains_key(&self, hkey: HazKey) -> bool {
123 self.contains_key(hkey)
124 }
125
126 fn insert(&mut self, hkey: HazKey, entity: E) {
127 self.insert(hkey, entity);
128 }
129
130 fn remove_by_key(&mut self, hkey: HazKey) {
131 self.remove(hkey);
132 }
133
134 fn len(&self) -> usize {
135 self.len()
136 }
137
138 fn iter(&self) -> impl Iterator<Item = (HazKey, &E)> {
139 self.iter()
140 }
141}
142
143impl<'a, E> IntoIterator for &'a BasicHazardCollector<E> {
144 type Item = (HazKey, &'a E);
145 type IntoIter = slotmap::secondary::Iter<'a, HazKey, E>;
146
147 fn into_iter(self) -> Self::IntoIter {
148 self.detected.iter()
149 }
150}