jagua_rs/collision_detection/hazards/
detector.rs1use crate::collision_detection::hazards::HazardEntity;
2use crate::collision_detection::hazards::filter::HazardFilter;
3use crate::entities::PItemKey;
4use slotmap::SecondaryMap;
5
6pub trait HazardDetector: HazardFilter {
9 fn contains(&self, haz: &HazardEntity) -> bool;
10
11 fn push(&mut self, haz: HazardEntity);
12
13 fn remove(&mut self, haz: &HazardEntity);
14
15 fn is_empty(&self) -> bool {
16 self.len() == 0
17 }
18
19 fn len(&self) -> usize;
20
21 fn iter(&self) -> impl Iterator<Item = &HazardEntity>;
22}
23
24impl<T> HazardFilter for T
27where
28 T: HazardDetector,
29{
30 fn is_irrelevant(&self, haz: &HazardEntity) -> bool {
31 self.contains(haz)
32 }
33}
34
35#[derive(Debug, Clone, Default)]
38pub struct BasicHazardDetector {
39 pi_hazards: SecondaryMap<PItemKey, HazardEntity>,
40 other: Vec<HazardEntity>,
41}
42
43impl BasicHazardDetector {
44 pub fn new() -> Self {
45 Self::default()
46 }
47
48 pub fn clear(&mut self) {
49 self.pi_hazards.clear();
50 self.other.clear();
51 }
52}
53
54impl HazardDetector for BasicHazardDetector {
55 fn contains(&self, haz: &HazardEntity) -> bool {
56 match haz {
57 HazardEntity::PlacedItem { pk, .. } => self.pi_hazards.contains_key(*pk),
58 _ => self.other.iter().any(|h| h == haz),
59 }
60 }
61
62 fn push(&mut self, haz: HazardEntity) {
63 debug_assert!(!self.contains(&haz));
64 match haz {
65 HazardEntity::PlacedItem { pk, .. } => {
66 self.pi_hazards.insert(pk, haz);
67 }
68 _ => self.other.push(haz),
69 }
70 }
71
72 fn remove(&mut self, haz: &HazardEntity) {
73 match haz {
74 HazardEntity::PlacedItem { pk, .. } => {
75 self.pi_hazards.remove(*pk);
76 }
77 _ => self.other.retain(|h| h != haz),
78 }
79 }
80
81 fn len(&self) -> usize {
82 self.pi_hazards.len() + self.other.len()
83 }
84
85 fn iter(&self) -> impl Iterator<Item = &HazardEntity> {
86 self.pi_hazards
87 .iter()
88 .map(|(_, h)| h)
89 .chain(self.other.iter())
90 }
91}