lib-r3vi/src/buffer/grid_hashmap.rs
2023-02-11 23:03:28 +01:00

90 lines
2.1 KiB
Rust

use {
std::{
sync::Arc,
collections::HashMap,
hash::Hash
},
std::sync::RwLock,
crate::{
core::{
Observer,
ObserverBroadcast,
View,
InnerViewPort
},
index::{IndexArea, IndexView}
}
};
struct GridBuffer<Item> {
data: HashMap<Point2<i16>, Item>,
limit: Point2<i16>
}
impl<Item> View for GridBuffer<Item>
where Item: Clone + Send + Sync + 'static
{
type Msg = IndexArea<Point2<i16>>;
}
impl<Item> IndexView<Point2<i16>> for GridBufferView<Item>
where Item: Clone + Send + Sync + 'static
{
type Item = Item;
fn get(&self, key: &Point2<i16>) -> Option<Self::Item> {
self.data.get(key).cloned()
}
fn area(&self) -> IndexArea<Point2<i16>> {
IndexArea::Range(
Point2::new(0, 0)
..= self.limit
)
}
}
pub struct GridBufferController<Item>
where Item: Clone + Send + Sync + 'static
{
data: Arc<RwLock<HashMap<Point2<i16>, Item>>>,
cast: Arc<RwLock<ObserverBroadcast<dyn IndexView<Point2<i16>, Item = Item>>>>
}
impl<Key, Item> GridBuffer<Key, Item>
where Key: Clone + Hash + Eq + Send + Sync + 'static,
Item: Clone + Send + Sync + 'static
{
pub fn new(port: InnerViewPort<dyn IndexView<Point2<i16>, Item = Item>>) -> Self {
let data = Arc::new(RwLock::new(HashMap::<Point2<i16>, Item>::new()));
port.set_view(Some(Arc::new(GridBufferView(data.clone()))));
GridBuffer {
data,
cast: port.get_broadcast()
}
}
pub fn insert(&mut self, key: Point2<i16>, item: Item) {
self.data.write().unwrap().insert(key.clone(), item);
if
self.cast.notify(&IndexArea::Set(vec![ key ]));
}
pub fn insert_iter<T>(&mut self, iter: T)
where T: IntoIterator<Item = (Point2<i16>, Item)> {
for (key, item) in iter {
self.insert(key, item);
}
}
pub fn remove(&mut self, key: Point2<i16>) {
self.data.write().unwrap().remove(&key);
self.cast.notify(&IndexArea::Set(vec![ key ]));
}
}