diff --git a/math/radix_transform/src/main.rs b/math/radix_transform/src/main.rs index 97aef98..9f1c050 100644 --- a/math/radix_transform/src/main.rs +++ b/math/radix_transform/src/main.rs @@ -5,7 +5,7 @@ use { ViewPort, TypeDict }, - sequence::{VecBuffer}, + vec::{VecBuffer}, integer::{RadixProjection} } }; diff --git a/nested/src/core/port.rs b/nested/src/core/port.rs index e36db56..11fbf3e 100644 --- a/nested/src/core/port.rs +++ b/nested/src/core/port.rs @@ -100,7 +100,7 @@ where V::Msg: Clone { impl UpdateTask for ViewPort where V::Msg: Clone + Send + Sync{ fn update(&self) { - let mut v = { + let v = { let t = self.update_hooks.read().unwrap(); t.iter().cloned().collect::>() }; diff --git a/nested/src/grid/flatten.rs b/nested/src/grid/flatten.rs index 6ba62f4..ecc6625 100644 --- a/nested/src/grid/flatten.rs +++ b/nested/src/grid/flatten.rs @@ -1,8 +1,7 @@ use { - async_std::stream::StreamExt, std::{ - sync::{Arc}, - collections::{HashMap, HashSet} + sync::Arc, + collections::HashMap }, std::sync::RwLock, cgmath::{Point2, Vector2}, @@ -10,7 +9,6 @@ use { core::{ View, Observer, ObserverBroadcast, ObserverExt, ViewPort, InnerViewPort, OuterViewPort, - channel::{ChannelSender, ChannelReceiver}, port::UpdateTask }, grid::{GridView, GridWindowIterator}, @@ -21,7 +19,7 @@ use { impl OuterViewPort>>> where Item: 'static{ - pub fn flatten(&self) -> OuterViewPort> { + pub fn flatten(&self) -> OuterViewPort + 'static> { let port = ViewPort::new(); port.add_update_hook(Arc::new(self.0.clone())); Flatten::new(self.clone(), port.inner()); @@ -177,7 +175,7 @@ where Item: 'static } } - let old_limit = self.limit; + //let old_limit = self.limit; self.limit = Point2::new( (0 .. top_range.end.x as usize).map(|x| col_widths[x]).sum(), (0 .. top_range.end.y as usize).map(|y| row_heights[y]).sum() diff --git a/nested/src/grid/offset.rs b/nested/src/grid/offset.rs index 170a9db..bb69c7d 100644 --- a/nested/src/grid/offset.rs +++ b/nested/src/grid/offset.rs @@ -1,15 +1,12 @@ use { - std::sync::Arc, - cgmath::{Point2, Vector2}, - std::sync::RwLock, + cgmath::Vector2, crate::{ - core::{ - OuterViewPort - }, - grid::{GridView} + core::OuterViewPort, + grid::GridView } }; +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> impl OuterViewPort> where Item: 'static { diff --git a/nested/src/integer/add.rs b/nested/src/integer/add.rs index 49a87bf..7955dcb 100644 --- a/nested/src/integer/add.rs +++ b/nested/src/integer/add.rs @@ -2,7 +2,8 @@ use { std::sync::{Arc, RwLock}, crate::{ core::{InnerViewPort, OuterViewPort}, - sequence::{SequenceView, VecBuffer}, + sequence::SequenceView, + vec::VecBuffer, projection::ProjectionHelper } }; diff --git a/nested/src/integer/radix.rs b/nested/src/integer/radix.rs index 3d026cb..ab99484 100644 --- a/nested/src/integer/radix.rs +++ b/nested/src/integer/radix.rs @@ -6,7 +6,8 @@ use { InnerViewPort, OuterViewPort }, - sequence::{SequenceView, VecBuffer} + sequence::SequenceView, + vec::VecBuffer } }; diff --git a/nested/src/leveled_term_view.rs b/nested/src/leveled_term_view.rs index 1f6b387..4a7d445 100644 --- a/nested/src/leveled_term_view.rs +++ b/nested/src/leveled_term_view.rs @@ -73,9 +73,11 @@ impl ImplIndexView for LeveledTermView { fn get(&self, pos: &Point2) -> Option { self.src.get(pos).map( |a| a.add_style_front( - if self.level > 0 { + if self.level > 1 { TerminalStyle::bold(true) .add(TerminalStyle::bg_color((0, 0, 0))) + } else if self.level > 0 { + TerminalStyle::bg_color((40, 40, 40)) } else { TerminalStyle::bold(false) }) diff --git a/nested/src/lib.rs b/nested/src/lib.rs index 58f6e5e..64f83b1 100644 --- a/nested/src/lib.rs +++ b/nested/src/lib.rs @@ -7,6 +7,7 @@ pub mod singleton; pub mod index; pub mod grid; pub mod sequence; +pub mod vec; pub mod terminal; pub mod integer; diff --git a/nested/src/projection.rs b/nested/src/projection.rs index bc0ee05..b0443c3 100644 --- a/nested/src/projection.rs +++ b/nested/src/projection.rs @@ -68,7 +68,7 @@ impl ProjectionHelper

{ port.get_view_arc() } - pub fn new_index_arg( + pub fn new_index_arg( &mut self, port: OuterViewPort>, notify: impl Fn(&mut P, &Key) + Send + Sync + 'static @@ -87,7 +87,7 @@ impl ProjectionHelper

{ (tx, rx): (ChannelSender, ChannelReceiver) ) -> Arc>> - where V::Msg: Send + Sync, + where V::Msg: Send + Sync + std::fmt::Debug, D::IntoIter: Send + Sync + 'static { let arg = Arc::new(RwLock::new( @@ -124,18 +124,22 @@ impl UpdateTask for ProjectionArg where P: Send + Sync + 'static, V: View + ?Sized, D: ChannelData, - D::IntoIter: Send + Sync + D::IntoIter: Send + Sync, +V::Msg: std::fmt::Debug { fn update(&self) { if let Some(p) = self.proj.read().unwrap().upgrade() { if let Some(data) = self.rx.try_recv() { for msg in data { + //eprintln!("proj update {:?}", msg); (self.notify)( &mut *p.write().unwrap(), &msg ); } } + } else { + eprintln!("proj update: upgrade fail"); } } } @@ -144,7 +148,8 @@ impl UpdateTask for RwLock> where P: Send + Sync + 'static, V: View + ?Sized, D: ChannelData, - D::IntoIter: Send + Sync + D::IntoIter: Send + Sync, +V::Msg: std::fmt::Debug { fn update(&self) { self.read().unwrap().update(); diff --git a/nested/src/sequence/flatten.rs b/nested/src/sequence/flatten.rs index e2383fe..e317b8f 100644 --- a/nested/src/sequence/flatten.rs +++ b/nested/src/sequence/flatten.rs @@ -1,15 +1,13 @@ use { - async_std::stream::StreamExt, std::{ - sync::{Arc}, - collections::{BTreeMap, HashSet} + sync::Arc, + collections::BTreeMap }, std::sync::RwLock, crate::{ core::{ View, Observer, ObserverBroadcast, ObserverExt, ViewPort, InnerViewPort, OuterViewPort, - channel::{ChannelSender, ChannelReceiver}, port::UpdateTask }, sequence::SequenceView, @@ -144,7 +142,7 @@ where Item: 'static let mut dirty_idx = Vec::new(); let mut cur_offset = 0; - for (chunk_idx, chunk) in self.chunks.iter_mut() { + for (_chunk_idx, chunk) in self.chunks.iter_mut() { let old_offset = chunk.offset; chunk.offset = cur_offset; chunk.len = chunk.view.len().unwrap_or(0); diff --git a/nested/src/sequence/mod.rs b/nested/src/sequence/mod.rs index eb1d9a0..42f7f9e 100644 --- a/nested/src/sequence/mod.rs +++ b/nested/src/sequence/mod.rs @@ -1,14 +1,10 @@ pub mod seq2idx; -pub mod vec_buffer; pub mod map; pub mod filter; pub mod flatten; -pub use { - seq2idx::{Sequence2Index}, - vec_buffer::{VecBuffer, VecSequence} -}; +pub use seq2idx::{Sequence2Index}; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/nested/src/sequence/vec_buffer.rs b/nested/src/sequence/vec_buffer.rs deleted file mode 100644 index 2d3c9e8..0000000 --- a/nested/src/sequence/vec_buffer.rs +++ /dev/null @@ -1,362 +0,0 @@ -use { - std::{ - sync::Arc, - ops::{Deref, DerefMut}, - io::Write - }, - std::sync::RwLock, - async_std::{ - io::{Read, ReadExt}, - stream::{StreamExt} - }, - serde::{Serialize, Deserialize, de::DeserializeOwned}, - crate::{ - core::{View, Observer, ObserverExt, ObserverBroadcast, ViewPort, InnerViewPort, OuterViewPort}, - sequence::SequenceView, - } -}; - -#[derive(Clone, Serialize, Deserialize)] -pub enum VecDiff { - Clear, - Push(T), - Remove(usize), - Insert{ idx: usize, val: T }, - Update{ idx: usize, val: T } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl View for Vec -where T: Clone + Send + Sync + 'static { - type Msg = VecDiff; -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -/// Adapter View implementing `Sequence` for `Vec` -pub struct VecSequence -where T: Clone + Send + Sync + 'static { - cur_len: usize, - data: Option>>>, - cast: Arc>>> -} - -/// Serialization Observer for `Vec` -pub struct VecBinWriter -where T: Clone + Send + Sync + 'static, - W: Write + Send + Sync { - data: Option>>>, - out: RwLock -} - -pub struct VecJsonWriter -where T: Clone + Send + Sync + 'static, - W: Write + Send + Sync { - data: Option>>>, - out: RwLock -} - -impl OuterViewPort>> -where T: Clone + Send + Sync + 'static { - pub fn to_sequence(&self) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let vec_seq = VecSequence::new(port.inner()); - self.add_observer(vec_seq.clone()); - port.into_outer() - } -} - -impl OuterViewPort>> -where T: Clone + Serialize + Send + Sync + 'static { - pub fn serialize_bin(&self, out: W) -> Arc>> { - let writer = Arc::new(RwLock::new( - VecBinWriter { - data: None, - out: RwLock::new(out), - } - )); - self.add_observer(writer.clone()); - writer - } - - pub fn serialize_json(&self, out: W) -> Arc>> { - let writer = Arc::new(RwLock::new( - VecJsonWriter { - data: None, - out: RwLock::new(out), - } - )); - self.add_observer(writer.clone()); - writer - } -} - - -impl Observer>> for VecBinWriter -where T: Clone + Serialize + Send + Sync + 'static, - W: Write + Send + Sync -{ - fn reset(&mut self, view: Option>>>) { - self.data = view; - let mut out = self.out.write().unwrap(); - - out.write(&bincode::serialized_size(&VecDiff::::Clear).unwrap().to_le_bytes()).expect(""); - out.write(&bincode::serialize(&VecDiff::::Clear).unwrap()).expect(""); - - if let Some(data) = self.data.as_ref() { - for x in data.read().unwrap().iter() { - out.write(&bincode::serialized_size(&VecDiff::Push(x)).unwrap().to_le_bytes()).expect(""); - out.write(&bincode::serialize(&VecDiff::Push(x)).unwrap()).expect(""); - } - } - - out.flush().expect(""); - } - - fn notify(&mut self, diff: &VecDiff) { - let mut out = self.out.write().unwrap(); - out.write(&bincode::serialized_size(diff).unwrap().to_le_bytes()).expect(""); - out.write(&bincode::serialize(diff).unwrap()).expect(""); - out.flush().expect(""); - } -} - -impl Observer>> for VecJsonWriter -where T: Clone + Serialize + Send + Sync + 'static, - W: Write + Send + Sync -{ - fn reset(&mut self, view: Option>>>) { - self.data = view; - - self.out.write().unwrap().write(&serde_json::to_string(&VecDiff::::Clear).unwrap().as_bytes()).expect(""); - self.out.write().unwrap().write(b"\n").expect(""); - - if let Some(data) = self.data.as_ref() { - for x in data.read().unwrap().iter() { - self.out.write().unwrap().write(&serde_json::to_string(&VecDiff::Push(x)).unwrap().as_bytes()).expect(""); - self.out.write().unwrap().write(b"\n").expect(""); - } - } - - self.out.write().unwrap().flush().expect(""); - } - - fn notify(&mut self, diff: &VecDiff) { - self.out.write().unwrap().write(serde_json::to_string(diff).unwrap().as_bytes()).expect(""); - self.out.write().unwrap().write(b"\n").expect(""); - self.out.write().unwrap().flush().expect(""); - } -} - -impl VecSequence -where T: Clone + Send + Sync + 'static { - pub fn new( - port: InnerViewPort> - ) -> Arc> { - let seq = Arc::new(RwLock::new( - VecSequence { - cur_len: 0, - data: None, - cast: port.get_broadcast() - } - )); - port.set_view(Some(seq.clone())); - seq - } -} - -impl Observer>> for VecSequence -where T: Clone + Send + Sync + 'static { - fn reset(&mut self, view: Option>>>) { - let old_len = self.cur_len; - self.data = view; - self.cur_len = - if let Some(data) = self.data.as_ref() { - data.read().unwrap().len() - } else { - 0 - }; - - self.cast.notify_each(0 .. std::cmp::max(old_len, self.cur_len)); - } - - fn notify(&mut self, diff: &VecDiff) { - match diff { - VecDiff::Clear => { - self.cast.notify_each(0 .. self.cur_len); - self.cur_len = 0 - }, - VecDiff::Push(_) => { - self.cast.notify(&self.cur_len); - self.cur_len += 1; - }, - VecDiff::Remove(idx) => { - self.cast.notify_each(*idx .. self.cur_len); - self.cur_len -= 1; - }, - VecDiff::Insert{ idx, val: _ } => { - self.cur_len += 1; - self.cast.notify_each(*idx .. self.cur_len); - }, - VecDiff::Update{ idx, val: _ } => { - self.cast.notify(&idx); - } - } - } -} - -impl View for VecSequence -where T: Clone + Send + Sync + 'static { - type Msg = usize; -} - -impl SequenceView for VecSequence -where T: Clone + Send + Sync + 'static { - type Item = T; - - fn get(&self, idx: &usize) -> Option { - self.data.as_ref()? - .read().unwrap() - .get(*idx).cloned() - } - - fn len(&self) -> Option { - Some(self.cur_len) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone)] -pub struct VecBuffer -where T: Clone + Send + Sync + 'static -{ - data: Arc>>, - cast: Arc>>>> -} - -impl VecBuffer -where T: DeserializeOwned + Clone + Send + Sync + 'static -{ - pub async fn from_json(&mut self, read: R) { - let mut bytes = read.bytes(); - let mut s = String::new(); - while let Some(Ok(b)) = bytes.next().await { - match b { - b'\n' => { - if s.len() > 0 { - let diff = serde_json::from_str::>(&s).expect("error parsing json"); - self.apply_diff(diff); - s.clear(); - } - }, - c => { - s.push(c as char); - } - } - } - } -} - -impl VecBuffer -where T: Clone + Send + Sync + 'static -{ - pub fn with_data( - data: Vec, - port: InnerViewPort>> - ) -> Self { - let data = Arc::new(RwLock::new(data)); - port.set_view(Some(data.clone())); - VecBuffer { data, cast: port.get_broadcast() } - } - - pub fn new(port: InnerViewPort>>) -> Self { - VecBuffer::with_data(Vec::new(), port) - } - - pub fn apply_diff(&mut self, diff: VecDiff) { - let mut data = self.data.write().unwrap(); - match &diff { - VecDiff::Clear => { data.clear(); }, - VecDiff::Push(val) => { data.push(val.clone()); }, - VecDiff::Remove(idx) => { data.remove(*idx); }, - VecDiff::Insert{ idx, val } => { data.insert(*idx, val.clone()); }, - VecDiff::Update{ idx, val } => { data[*idx] = val.clone(); } - } - drop(data); - - self.cast.notify(&diff); - } - - pub fn len(&self) -> usize { - self.data.read().unwrap().len() - } - - pub fn get(&self, idx: usize) -> T { - self.data.read().unwrap()[idx].clone() - } - - pub fn clear(&mut self) { - self.apply_diff(VecDiff::Clear); - } - - pub fn push(&mut self, val: T) { - self.apply_diff(VecDiff::Push(val)); - } - - pub fn remove(&mut self, idx: usize) { - self.apply_diff(VecDiff::Remove(idx)); - } - - pub fn insert(&mut self, idx: usize, val: T) { - self.apply_diff(VecDiff::Insert{ idx, val }); - } - - pub fn update(&mut self, idx: usize, val: T) { - self.apply_diff(VecDiff::Update{ idx, val }); - } - - pub fn get_mut(&mut self, idx: usize) -> MutableVecAccess { - MutableVecAccess { - buf: self.clone(), - idx, - val: self.get(idx) - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct MutableVecAccess -where T: Clone + Send + Sync + 'static { - buf: VecBuffer, - idx: usize, - val: T, -} - -impl Deref for MutableVecAccess -where T: Clone + Send + Sync + 'static { - type Target = T; - - fn deref(&self) -> &T { - &self.val - } -} - -impl DerefMut for MutableVecAccess -where T: Clone + Send + Sync + 'static { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.val - } -} - -impl Drop for MutableVecAccess -where T: Clone + Send + Sync + 'static { - fn drop(&mut self) { - self.buf.update(self.idx, self.val.clone()); - } -} - diff --git a/nested/src/string_editor.rs b/nested/src/string_editor.rs index 064671e..8f9d070 100644 --- a/nested/src/string_editor.rs +++ b/nested/src/string_editor.rs @@ -3,7 +3,7 @@ use { crate::{ core::{ViewPort, OuterViewPort}, singleton::{SingletonView, SingletonBuffer}, - sequence::VecBuffer, + vec::VecBuffer, terminal::{TerminalView} } }; diff --git a/nested/src/terminal/mod.rs b/nested/src/terminal/mod.rs index 587a9f2..2687a92 100644 --- a/nested/src/terminal/mod.rs +++ b/nested/src/terminal/mod.rs @@ -24,7 +24,7 @@ pub trait TerminalView = GridView; use { crate::{ - sequence::VecBuffer, + vec::VecBuffer, core::{ViewPort, OuterViewPort} }, cgmath::Point2 @@ -32,7 +32,7 @@ use { pub fn make_label(s: &str) -> OuterViewPort { let label_port = ViewPort::new(); - let label = VecBuffer::with_data(s.chars().collect(), label_port.inner()); + let _label = VecBuffer::with_data(s.chars().collect(), label_port.inner()); label_port.outer() .to_sequence() .map(|c| TerminalAtom::from(c)) diff --git a/nested/src/vec/buffer.rs b/nested/src/vec/buffer.rs new file mode 100644 index 0000000..5116550 --- /dev/null +++ b/nested/src/vec/buffer.rs @@ -0,0 +1,129 @@ +use { + std::{ + sync::Arc, + ops::{Deref, DerefMut}, + }, + std::sync::RwLock, + crate::{ + core::{View, Observer, ObserverBroadcast, InnerViewPort}, + vec::VecDiff + } +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl View for Vec +where T: Clone + Send + Sync + 'static { + type Msg = VecDiff; +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +#[derive(Clone)] +pub struct VecBuffer +where T: Clone + Send + Sync + 'static +{ + data: Arc>>, + cast: Arc>>>> +} + +impl VecBuffer +where T: Clone + Send + Sync + 'static +{ + pub fn with_data( + data: Vec, + port: InnerViewPort>> + ) -> Self { + let data = Arc::new(RwLock::new(data)); + port.set_view(Some(data.clone())); + VecBuffer { data, cast: port.get_broadcast() } + } + + pub fn new(port: InnerViewPort>>) -> Self { + VecBuffer::with_data(Vec::new(), port) + } + + pub fn apply_diff(&mut self, diff: VecDiff) { + let mut data = self.data.write().unwrap(); + match &diff { + VecDiff::Clear => { data.clear(); }, + VecDiff::Push(val) => { data.push(val.clone()); }, + VecDiff::Remove(idx) => { data.remove(*idx); }, + VecDiff::Insert{ idx, val } => { data.insert(*idx, val.clone()); }, + VecDiff::Update{ idx, val } => { data[*idx] = val.clone(); } + } + drop(data); + + self.cast.notify(&diff); + } + + pub fn len(&self) -> usize { + self.data.read().unwrap().len() + } + + pub fn get(&self, idx: usize) -> T { + self.data.read().unwrap()[idx].clone() + } + + pub fn clear(&mut self) { + self.apply_diff(VecDiff::Clear); + } + + pub fn push(&mut self, val: T) { + self.apply_diff(VecDiff::Push(val)); + } + + pub fn remove(&mut self, idx: usize) { + self.apply_diff(VecDiff::Remove(idx)); + } + + pub fn insert(&mut self, idx: usize, val: T) { + self.apply_diff(VecDiff::Insert{ idx, val }); + } + + pub fn update(&mut self, idx: usize, val: T) { + self.apply_diff(VecDiff::Update{ idx, val }); + } + + pub fn get_mut(&mut self, idx: usize) -> MutableVecAccess { + MutableVecAccess { + buf: self.clone(), + idx, + val: self.get(idx) + } + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct MutableVecAccess +where T: Clone + Send + Sync + 'static { + buf: VecBuffer, + idx: usize, + val: T, +} + +impl Deref for MutableVecAccess +where T: Clone + Send + Sync + 'static { + type Target = T; + + fn deref(&self) -> &T { + &self.val + } +} + +impl DerefMut for MutableVecAccess +where T: Clone + Send + Sync + 'static { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.val + } +} + +impl Drop for MutableVecAccess +where T: Clone + Send + Sync + 'static { + fn drop(&mut self) { + self.buf.update(self.idx, self.val.clone()); + } +} + + diff --git a/nested/src/vec/mod.rs b/nested/src/vec/mod.rs new file mode 100644 index 0000000..0311a3b --- /dev/null +++ b/nested/src/vec/mod.rs @@ -0,0 +1,25 @@ + +pub mod buffer; +pub mod vec2seq; +pub mod vec2json; +pub mod vec2bin; + +pub use { + buffer::VecBuffer +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +use { + serde::{Serialize, Deserialize} +}; + +#[derive(Clone, Serialize, Deserialize)] +pub enum VecDiff { + Clear, + Push(T), + Remove(usize), + Insert{ idx: usize, val: T }, + Update{ idx: usize, val: T } +} + diff --git a/nested/src/vec/vec2bin.rs b/nested/src/vec/vec2bin.rs new file mode 100644 index 0000000..c274324 --- /dev/null +++ b/nested/src/vec/vec2bin.rs @@ -0,0 +1,67 @@ +use { + std::{ + sync::Arc, + io::Write + }, + std::sync::RwLock, + serde::Serialize, + crate::{ + core::{Observer, OuterViewPort}, + vec::VecDiff + } +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +/// Serialization Observer for `Vec` +pub struct VecBinWriter +where T: Clone + Send + Sync + 'static, + W: Write + Send + Sync { + data: Option>>>, + out: RwLock +} + + +impl OuterViewPort>> +where T: Clone + Serialize + Send + Sync + 'static { + pub fn serialize_bin(&self, out: W) -> Arc>> { + let writer = Arc::new(RwLock::new( + VecBinWriter { + data: None, + out: RwLock::new(out), + } + )); + self.add_observer(writer.clone()); + writer + } +} + +impl Observer>> for VecBinWriter +where T: Clone + Serialize + Send + Sync + 'static, + W: Write + Send + Sync +{ + fn reset(&mut self, view: Option>>>) { + self.data = view; + let mut out = self.out.write().unwrap(); + + out.write(&bincode::serialized_size(&VecDiff::::Clear).unwrap().to_le_bytes()).expect(""); + out.write(&bincode::serialize(&VecDiff::::Clear).unwrap()).expect(""); + + if let Some(data) = self.data.as_ref() { + for x in data.read().unwrap().iter() { + out.write(&bincode::serialized_size(&VecDiff::Push(x)).unwrap().to_le_bytes()).expect(""); + out.write(&bincode::serialize(&VecDiff::Push(x)).unwrap()).expect(""); + } + } + + out.flush().expect(""); + } + + fn notify(&mut self, diff: &VecDiff) { + let mut out = self.out.write().unwrap(); + out.write(&bincode::serialized_size(diff).unwrap().to_le_bytes()).expect(""); + out.write(&bincode::serialize(diff).unwrap()).expect(""); + out.flush().expect(""); + } +} + diff --git a/nested/src/vec/vec2json.rs b/nested/src/vec/vec2json.rs new file mode 100644 index 0000000..b5c8a0f --- /dev/null +++ b/nested/src/vec/vec2json.rs @@ -0,0 +1,91 @@ +use { + std::{ + sync::Arc, + io::Write + }, + std::sync::RwLock, + async_std::{ + io::{Read, ReadExt}, + stream::{StreamExt} + }, + serde::{Serialize, de::DeserializeOwned}, + crate::{ + core::{Observer, OuterViewPort}, + vec::{VecDiff, VecBuffer} + } +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct VecJsonWriter +where T: Clone + Send + Sync + 'static, + W: Write + Send + Sync { + data: Option>>>, + out: RwLock +} + +impl OuterViewPort>> +where T: Clone + Serialize + Send + Sync + 'static { + pub fn serialize_json(&self, out: W) -> Arc>> { + let writer = Arc::new(RwLock::new( + VecJsonWriter { + data: None, + out: RwLock::new(out), + } + )); + self.add_observer(writer.clone()); + writer + } +} + +impl Observer>> for VecJsonWriter +where T: Clone + Serialize + Send + Sync + 'static, + W: Write + Send + Sync +{ + fn reset(&mut self, view: Option>>>) { + self.data = view; + + self.out.write().unwrap().write(&serde_json::to_string(&VecDiff::::Clear).unwrap().as_bytes()).expect(""); + self.out.write().unwrap().write(b"\n").expect(""); + + if let Some(data) = self.data.as_ref() { + for x in data.read().unwrap().iter() { + self.out.write().unwrap().write(&serde_json::to_string(&VecDiff::Push(x)).unwrap().as_bytes()).expect(""); + self.out.write().unwrap().write(b"\n").expect(""); + } + } + + self.out.write().unwrap().flush().expect(""); + } + + fn notify(&mut self, diff: &VecDiff) { + self.out.write().unwrap().write(serde_json::to_string(diff).unwrap().as_bytes()).expect(""); + self.out.write().unwrap().write(b"\n").expect(""); + self.out.write().unwrap().flush().expect(""); + } +} + +impl VecBuffer +where T: DeserializeOwned + Clone + Send + Sync + 'static +{ + pub async fn from_json(&mut self, read: R) { + let mut bytes = read.bytes(); + let mut s = String::new(); + while let Some(Ok(b)) = bytes.next().await { + match b { + b'\n' => { + if s.len() > 0 { + let diff = serde_json::from_str::>(&s).expect("error parsing json"); + self.apply_diff(diff); + s.clear(); + } + }, + c => { + s.push(c as char); + } + } + } + } +} + + diff --git a/nested/src/vec/vec2seq.rs b/nested/src/vec/vec2seq.rs new file mode 100644 index 0000000..0c8871e --- /dev/null +++ b/nested/src/vec/vec2seq.rs @@ -0,0 +1,115 @@ +use { + std::{ + sync::Arc, + }, + std::sync::RwLock, + crate::{ + core::{View, Observer, ObserverExt, ObserverBroadcast, ViewPort, InnerViewPort, OuterViewPort}, + sequence::SequenceView, + vec::VecDiff + } +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +/// Adapter View implementing `Sequence` for `Vec` +pub struct VecSequence +where T: Clone + Send + Sync + 'static { + cur_len: usize, + data: Option>>>, + cast: Arc>>> +} + + +impl VecSequence +where T: Clone + Send + Sync + 'static { + pub fn new( + port: InnerViewPort> + ) -> Arc> { + let seq = Arc::new(RwLock::new( + VecSequence { + cur_len: 0, + data: None, + cast: port.get_broadcast() + } + )); + port.set_view(Some(seq.clone())); + seq + } +} + +impl Observer>> for VecSequence +where T: Clone + Send + Sync + 'static { + fn reset(&mut self, view: Option>>>) { + let old_len = self.cur_len; + self.data = view; + self.cur_len = + if let Some(data) = self.data.as_ref() { + data.read().unwrap().len() + } else { + 0 + }; + + self.cast.notify_each(0 .. std::cmp::max(old_len, self.cur_len)); + } + + fn notify(&mut self, diff: &VecDiff) { + match diff { + VecDiff::Clear => { + self.cast.notify_each(0 .. self.cur_len); + self.cur_len = 0 + }, + VecDiff::Push(_) => { + self.cast.notify(&self.cur_len); + self.cur_len += 1; + }, + VecDiff::Remove(idx) => { + self.cast.notify_each(*idx .. self.cur_len); + self.cur_len -= 1; + }, + VecDiff::Insert{ idx, val: _ } => { + self.cur_len += 1; + self.cast.notify_each(*idx .. self.cur_len); + }, + VecDiff::Update{ idx, val: _ } => { + self.cast.notify(&idx); + } + } + } +} + +impl View for VecSequence +where T: Clone + Send + Sync + 'static { + type Msg = usize; +} + +impl SequenceView for VecSequence +where T: Clone + Send + Sync + 'static { + type Item = T; + + fn get(&self, idx: &usize) -> Option { + self.data.as_ref()? + .read().unwrap() + .get(*idx).cloned() + } + + fn len(&self) -> Option { + Some(self.cur_len) + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl OuterViewPort>> +where T: Clone + Send + Sync + 'static { + pub fn to_sequence(&self) -> OuterViewPort> { + let port = ViewPort::new(); + port.add_update_hook(Arc::new(self.0.clone())); + + let vec_seq = VecSequence::new(port.inner()); + self.add_observer(vec_seq.clone()); + port.into_outer() + } +} + +