use parking_lot::RwLock;
use super::{DummyMap, Map};
lazy_static! {
pub static ref MAPS: RwLock<Vec<RwLock<Box<dyn Map>>>> = RwLock::new(Vec::new());
pub(crate) static ref VALID_MAPS: RwLock<Vec<RwLock<bool>>> = RwLock::new(Vec::new());
pub(crate) static ref LOWEST_POSSIBLY_INVALID_MAP: RwLock<MapId> = RwLock::new(0);
}
pub fn register_map<TMap>(map: TMap) -> MapId
where
TMap: 'static + Map,
{
let output = map.map_id();
let mut maps = MAPS.write();
let mut valid_maps = VALID_MAPS.write();
if output >= maps.len() {
maps.resize_with(output + 1, || RwLock::new(Box::new(DummyMap::new())));
valid_maps.resize_with(output + 1, || RwLock::new(false));
}
let mut lowest_possibly_invalid_map = LOWEST_POSSIBLY_INVALID_MAP.write();
maps[output] = RwLock::new(Box::new(map));
*valid_maps[output].write() = true;
if output == *lowest_possibly_invalid_map {
*lowest_possibly_invalid_map += 1;
}
output
}
pub type MapId = usize;
pub fn invalidate_map(map_id: MapId) {
let maps = MAPS.read();
let valid_maps = VALID_MAPS.read();
let map = &mut maps[map_id].write();
let valid_map = &mut valid_maps[map_id].write();
let mut lowest_possibly_invalid_map = LOWEST_POSSIBLY_INVALID_MAP.write();
**map = Box::new(DummyMap::new());
**valid_map = false;
if map_id < *lowest_possibly_invalid_map {
*lowest_possibly_invalid_map = map_id;
}
}