extern crate alloc;
use alloc::boxed::Box;
use alloc::vec;
use alloc::vec::Vec;
use crate::zone::ZoneShape;
pub struct ZoneStoreEmbed {
zones: Vec<(u32, Box<dyn ZoneShape>)>,
}
impl ZoneStoreEmbed {
pub fn new() -> Self {
Self { zones: vec![] }
}
pub fn add(&mut self, id: u32, shape: Box<dyn ZoneShape>) {
self.zones.retain(|(i, _)| *i != id);
self.zones.push((id, shape));
}
pub fn remove(&mut self, id: u32) {
self.zones.retain(|(i, _)| *i != id);
}
pub fn query_enu(&self, p: [f64; 3]) -> Vec<u32> {
self.zones
.iter()
.filter(|(_, s)| s.contains_enu(p))
.map(|(id, _)| *id)
.collect()
}
pub fn len(&self) -> usize {
self.zones.len()
}
pub fn is_empty(&self) -> bool {
self.zones.is_empty()
}
}
impl Default for ZoneStoreEmbed {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::zone::Zone;
use crate::coord::EnuConverter;
use crate::zone::zone_to_shape;
#[test]
fn embed_add_query_remove() {
let conv = EnuConverter::new(0.0, 0.0, 0.0);
let mut store = ZoneStoreEmbed::new();
let shape = zone_to_shape(
&Zone::Cylinder {
center: [0.0, 0.0],
radius_m: 10.0,
z_min: 0.0,
z_max: 5.0,
},
&conv,
);
store.add(1, shape);
assert_eq!(store.query_enu([0.0, 0.0, 2.5]), vec![1]);
assert!(store.query_enu([20.0, 0.0, 2.5]).is_empty());
store.remove(1);
assert!(store.is_empty());
}
}