From 941da4ed7d0ac98b798e3a1756cd36aee04e3856 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 17 Nov 2021 22:32:31 +0100
Subject: [PATCH] add grid/buffer

---
 nested/src/grid/buffer.rs | 90 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 nested/src/grid/buffer.rs

diff --git a/nested/src/grid/buffer.rs b/nested/src/grid/buffer.rs
new file mode 100644
index 0000000..613c858
--- /dev/null
+++ b/nested/src/grid/buffer.rs
@@ -0,0 +1,90 @@
+
+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 ]));
+    }
+}
+