move VecBuffer and views into separate vec module

This commit is contained in:
Michael Sippel 2021-06-16 01:56:09 +02:00
parent 30a3df180b
commit 835a0bf08e
Signed by: senvas
GPG key ID: F96CF119C34B64A6
19 changed files with 461 additions and 397 deletions

View file

@ -5,7 +5,7 @@ use {
ViewPort, ViewPort,
TypeDict TypeDict
}, },
sequence::{VecBuffer}, vec::{VecBuffer},
integer::{RadixProjection} integer::{RadixProjection}
} }
}; };

View file

@ -100,7 +100,7 @@ where V::Msg: Clone {
impl<V: View + ?Sized> UpdateTask for ViewPort<V> where V::Msg: Clone + Send + Sync{ impl<V: View + ?Sized> UpdateTask for ViewPort<V> where V::Msg: Clone + Send + Sync{
fn update(&self) { fn update(&self) {
let mut v = { let v = {
let t = self.update_hooks.read().unwrap(); let t = self.update_hooks.read().unwrap();
t.iter().cloned().collect::<Vec<_>>() t.iter().cloned().collect::<Vec<_>>()
}; };

View file

@ -1,8 +1,7 @@
use { use {
async_std::stream::StreamExt,
std::{ std::{
sync::{Arc}, sync::Arc,
collections::{HashMap, HashSet} collections::HashMap
}, },
std::sync::RwLock, std::sync::RwLock,
cgmath::{Point2, Vector2}, cgmath::{Point2, Vector2},
@ -10,7 +9,6 @@ use {
core::{ core::{
View, Observer, ObserverBroadcast, ObserverExt, View, Observer, ObserverBroadcast, ObserverExt,
ViewPort, InnerViewPort, OuterViewPort, ViewPort, InnerViewPort, OuterViewPort,
channel::{ChannelSender, ChannelReceiver},
port::UpdateTask port::UpdateTask
}, },
grid::{GridView, GridWindowIterator}, grid::{GridView, GridWindowIterator},
@ -21,7 +19,7 @@ use {
impl<Item> OuterViewPort<dyn GridView<Item = OuterViewPort<dyn GridView<Item = Item>>>> impl<Item> OuterViewPort<dyn GridView<Item = OuterViewPort<dyn GridView<Item = Item>>>>
where Item: 'static{ where Item: 'static{
pub fn flatten(&self) -> OuterViewPort<dyn GridView<Item = Item>> { pub fn flatten(&self) -> OuterViewPort<dyn GridView<Item = Item> + 'static> {
let port = ViewPort::new(); let port = ViewPort::new();
port.add_update_hook(Arc::new(self.0.clone())); port.add_update_hook(Arc::new(self.0.clone()));
Flatten::new(self.clone(), port.inner()); 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( self.limit = Point2::new(
(0 .. top_range.end.x as usize).map(|x| col_widths[x]).sum(), (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() (0 .. top_range.end.y as usize).map(|y| row_heights[y]).sum()

View file

@ -1,15 +1,12 @@
use { use {
std::sync::Arc, cgmath::Vector2,
cgmath::{Point2, Vector2},
std::sync::RwLock,
crate::{ crate::{
core::{ core::OuterViewPort,
OuterViewPort grid::GridView
},
grid::{GridView}
} }
}; };
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl<Item> OuterViewPort<dyn GridView<Item = Item>> impl<Item> OuterViewPort<dyn GridView<Item = Item>>
where Item: 'static { where Item: 'static {

View file

@ -2,7 +2,8 @@ use {
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
crate::{ crate::{
core::{InnerViewPort, OuterViewPort}, core::{InnerViewPort, OuterViewPort},
sequence::{SequenceView, VecBuffer}, sequence::SequenceView,
vec::VecBuffer,
projection::ProjectionHelper projection::ProjectionHelper
} }
}; };

View file

@ -6,7 +6,8 @@ use {
InnerViewPort, InnerViewPort,
OuterViewPort OuterViewPort
}, },
sequence::{SequenceView, VecBuffer} sequence::SequenceView,
vec::VecBuffer
} }
}; };

View file

@ -73,9 +73,11 @@ impl ImplIndexView for LeveledTermView {
fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> { fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> {
self.src.get(pos).map( self.src.get(pos).map(
|a| a.add_style_front( |a| a.add_style_front(
if self.level > 0 { if self.level > 1 {
TerminalStyle::bold(true) TerminalStyle::bold(true)
.add(TerminalStyle::bg_color((0, 0, 0))) .add(TerminalStyle::bg_color((0, 0, 0)))
} else if self.level > 0 {
TerminalStyle::bg_color((40, 40, 40))
} else { } else {
TerminalStyle::bold(false) TerminalStyle::bold(false)
}) })

View file

@ -7,6 +7,7 @@ pub mod singleton;
pub mod index; pub mod index;
pub mod grid; pub mod grid;
pub mod sequence; pub mod sequence;
pub mod vec;
pub mod terminal; pub mod terminal;
pub mod integer; pub mod integer;

View file

@ -68,7 +68,7 @@ impl<P: Send + Sync + 'static> ProjectionHelper<P> {
port.get_view_arc() port.get_view_arc()
} }
pub fn new_index_arg<Key: Hash + Eq + Clone + Send + Sync + 'static, Item: 'static>( pub fn new_index_arg<Key: Hash + Eq + Clone + Send + Sync + std::fmt::Debug + 'static, Item: 'static>(
&mut self, &mut self,
port: OuterViewPort<dyn IndexView<Key, Item = Item>>, port: OuterViewPort<dyn IndexView<Key, Item = Item>>,
notify: impl Fn(&mut P, &Key) + Send + Sync + 'static notify: impl Fn(&mut P, &Key) + Send + Sync + 'static
@ -87,7 +87,7 @@ impl<P: Send + Sync + 'static> ProjectionHelper<P> {
(tx, rx): (ChannelSender<D>, ChannelReceiver<D>) (tx, rx): (ChannelSender<D>, ChannelReceiver<D>)
) )
-> Arc<RwLock<ProjectionArg<P, V, D>>> -> Arc<RwLock<ProjectionArg<P, V, D>>>
where V::Msg: Send + Sync, where V::Msg: Send + Sync + std::fmt::Debug,
D::IntoIter: Send + Sync + 'static D::IntoIter: Send + Sync + 'static
{ {
let arg = Arc::new(RwLock::new( let arg = Arc::new(RwLock::new(
@ -124,18 +124,22 @@ impl<P, V, D> UpdateTask for ProjectionArg<P, V, D>
where P: Send + Sync + 'static, where P: Send + Sync + 'static,
V: View + ?Sized, V: View + ?Sized,
D: ChannelData<Item = V::Msg>, D: ChannelData<Item = V::Msg>,
D::IntoIter: Send + Sync D::IntoIter: Send + Sync,
V::Msg: std::fmt::Debug
{ {
fn update(&self) { fn update(&self) {
if let Some(p) = self.proj.read().unwrap().upgrade() { if let Some(p) = self.proj.read().unwrap().upgrade() {
if let Some(data) = self.rx.try_recv() { if let Some(data) = self.rx.try_recv() {
for msg in data { for msg in data {
//eprintln!("proj update {:?}", msg);
(self.notify)( (self.notify)(
&mut *p.write().unwrap(), &mut *p.write().unwrap(),
&msg &msg
); );
} }
} }
} else {
eprintln!("proj update: upgrade fail");
} }
} }
} }
@ -144,7 +148,8 @@ impl<P, V, D> UpdateTask for RwLock<ProjectionArg<P, V, D>>
where P: Send + Sync + 'static, where P: Send + Sync + 'static,
V: View + ?Sized, V: View + ?Sized,
D: ChannelData<Item = V::Msg>, D: ChannelData<Item = V::Msg>,
D::IntoIter: Send + Sync D::IntoIter: Send + Sync,
V::Msg: std::fmt::Debug
{ {
fn update(&self) { fn update(&self) {
self.read().unwrap().update(); self.read().unwrap().update();

View file

@ -1,15 +1,13 @@
use { use {
async_std::stream::StreamExt,
std::{ std::{
sync::{Arc}, sync::Arc,
collections::{BTreeMap, HashSet} collections::BTreeMap
}, },
std::sync::RwLock, std::sync::RwLock,
crate::{ crate::{
core::{ core::{
View, Observer, ObserverBroadcast, ObserverExt, View, Observer, ObserverBroadcast, ObserverExt,
ViewPort, InnerViewPort, OuterViewPort, ViewPort, InnerViewPort, OuterViewPort,
channel::{ChannelSender, ChannelReceiver},
port::UpdateTask port::UpdateTask
}, },
sequence::SequenceView, sequence::SequenceView,
@ -144,7 +142,7 @@ where Item: 'static
let mut dirty_idx = Vec::new(); let mut dirty_idx = Vec::new();
let mut cur_offset = 0; 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; let old_offset = chunk.offset;
chunk.offset = cur_offset; chunk.offset = cur_offset;
chunk.len = chunk.view.len().unwrap_or(0); chunk.len = chunk.view.len().unwrap_or(0);

View file

@ -1,14 +1,10 @@
pub mod seq2idx; pub mod seq2idx;
pub mod vec_buffer;
pub mod map; pub mod map;
pub mod filter; pub mod filter;
pub mod flatten; pub mod flatten;
pub use { pub use seq2idx::{Sequence2Index};
seq2idx::{Sequence2Index},
vec_buffer::{VecBuffer, VecSequence}
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -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<T> {
Clear,
Push(T),
Remove(usize),
Insert{ idx: usize, val: T },
Update{ idx: usize, val: T }
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl<T> View for Vec<T>
where T: Clone + Send + Sync + 'static {
type Msg = VecDiff<T>;
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
/// Adapter View implementing `Sequence` for `Vec`
pub struct VecSequence<T>
where T: Clone + Send + Sync + 'static {
cur_len: usize,
data: Option<Arc<RwLock<Vec<T>>>>,
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = T>>>>
}
/// Serialization Observer for `Vec`
pub struct VecBinWriter<T, W>
where T: Clone + Send + Sync + 'static,
W: Write + Send + Sync {
data: Option<Arc<RwLock<Vec<T>>>>,
out: RwLock<W>
}
pub struct VecJsonWriter<T, W>
where T: Clone + Send + Sync + 'static,
W: Write + Send + Sync {
data: Option<Arc<RwLock<Vec<T>>>>,
out: RwLock<W>
}
impl<T> OuterViewPort<RwLock<Vec<T>>>
where T: Clone + Send + Sync + 'static {
pub fn to_sequence(&self) -> OuterViewPort<dyn SequenceView<Item = T>> {
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<T> OuterViewPort<RwLock<Vec<T>>>
where T: Clone + Serialize + Send + Sync + 'static {
pub fn serialize_bin<W: Write + Send + Sync + 'static>(&self, out: W) -> Arc<RwLock<VecBinWriter<T, W>>> {
let writer = Arc::new(RwLock::new(
VecBinWriter {
data: None,
out: RwLock::new(out),
}
));
self.add_observer(writer.clone());
writer
}
pub fn serialize_json<W: Write + Send + Sync + 'static>(&self, out: W) -> Arc<RwLock<VecJsonWriter<T, W>>> {
let writer = Arc::new(RwLock::new(
VecJsonWriter {
data: None,
out: RwLock::new(out),
}
));
self.add_observer(writer.clone());
writer
}
}
impl<T, W> Observer<RwLock<Vec<T>>> for VecBinWriter<T, W>
where T: Clone + Serialize + Send + Sync + 'static,
W: Write + Send + Sync
{
fn reset(&mut self, view: Option<Arc<RwLock<Vec<T>>>>) {
self.data = view;
let mut out = self.out.write().unwrap();
out.write(&bincode::serialized_size(&VecDiff::<T>::Clear).unwrap().to_le_bytes()).expect("");
out.write(&bincode::serialize(&VecDiff::<T>::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<T>) {
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<T, W> Observer<RwLock<Vec<T>>> for VecJsonWriter<T, W>
where T: Clone + Serialize + Send + Sync + 'static,
W: Write + Send + Sync
{
fn reset(&mut self, view: Option<Arc<RwLock<Vec<T>>>>) {
self.data = view;
self.out.write().unwrap().write(&serde_json::to_string(&VecDiff::<T>::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<T>) {
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<T> VecSequence<T>
where T: Clone + Send + Sync + 'static {
pub fn new(
port: InnerViewPort<dyn SequenceView<Item = T>>
) -> Arc<RwLock<Self>> {
let seq = Arc::new(RwLock::new(
VecSequence {
cur_len: 0,
data: None,
cast: port.get_broadcast()
}
));
port.set_view(Some(seq.clone()));
seq
}
}
impl<T> Observer<RwLock<Vec<T>>> for VecSequence<T>
where T: Clone + Send + Sync + 'static {
fn reset(&mut self, view: Option<Arc<RwLock<Vec<T>>>>) {
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<T>) {
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<T> View for VecSequence<T>
where T: Clone + Send + Sync + 'static {
type Msg = usize;
}
impl<T> SequenceView for VecSequence<T>
where T: Clone + Send + Sync + 'static {
type Item = T;
fn get(&self, idx: &usize) -> Option<T> {
self.data.as_ref()?
.read().unwrap()
.get(*idx).cloned()
}
fn len(&self) -> Option<usize> {
Some(self.cur_len)
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Clone)]
pub struct VecBuffer<T>
where T: Clone + Send + Sync + 'static
{
data: Arc<RwLock<Vec<T>>>,
cast: Arc<RwLock<ObserverBroadcast<RwLock<Vec<T>>>>>
}
impl<T> VecBuffer<T>
where T: DeserializeOwned + Clone + Send + Sync + 'static
{
pub async fn from_json<R: Read + async_std::io::Read + Unpin>(&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::<VecDiff<T>>(&s).expect("error parsing json");
self.apply_diff(diff);
s.clear();
}
},
c => {
s.push(c as char);
}
}
}
}
}
impl<T> VecBuffer<T>
where T: Clone + Send + Sync + 'static
{
pub fn with_data(
data: Vec<T>,
port: InnerViewPort<RwLock<Vec<T>>>
) -> 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<RwLock<Vec<T>>>) -> Self {
VecBuffer::with_data(Vec::new(), port)
}
pub fn apply_diff(&mut self, diff: VecDiff<T>) {
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<T> {
MutableVecAccess {
buf: self.clone(),
idx,
val: self.get(idx)
}
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct MutableVecAccess<T>
where T: Clone + Send + Sync + 'static {
buf: VecBuffer<T>,
idx: usize,
val: T,
}
impl<T> Deref for MutableVecAccess<T>
where T: Clone + Send + Sync + 'static {
type Target = T;
fn deref(&self) -> &T {
&self.val
}
}
impl<T> DerefMut for MutableVecAccess<T>
where T: Clone + Send + Sync + 'static {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.val
}
}
impl<T> Drop for MutableVecAccess<T>
where T: Clone + Send + Sync + 'static {
fn drop(&mut self) {
self.buf.update(self.idx, self.val.clone());
}
}

View file

@ -3,7 +3,7 @@ use {
crate::{ crate::{
core::{ViewPort, OuterViewPort}, core::{ViewPort, OuterViewPort},
singleton::{SingletonView, SingletonBuffer}, singleton::{SingletonView, SingletonBuffer},
sequence::VecBuffer, vec::VecBuffer,
terminal::{TerminalView} terminal::{TerminalView}
} }
}; };

View file

@ -24,7 +24,7 @@ pub trait TerminalView = GridView<Item = TerminalAtom>;
use { use {
crate::{ crate::{
sequence::VecBuffer, vec::VecBuffer,
core::{ViewPort, OuterViewPort} core::{ViewPort, OuterViewPort}
}, },
cgmath::Point2 cgmath::Point2
@ -32,7 +32,7 @@ use {
pub fn make_label(s: &str) -> OuterViewPort<dyn TerminalView> { pub fn make_label(s: &str) -> OuterViewPort<dyn TerminalView> {
let label_port = ViewPort::new(); 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() label_port.outer()
.to_sequence() .to_sequence()
.map(|c| TerminalAtom::from(c)) .map(|c| TerminalAtom::from(c))

129
nested/src/vec/buffer.rs Normal file
View file

@ -0,0 +1,129 @@
use {
std::{
sync::Arc,
ops::{Deref, DerefMut},
},
std::sync::RwLock,
crate::{
core::{View, Observer, ObserverBroadcast, InnerViewPort},
vec::VecDiff
}
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl<T> View for Vec<T>
where T: Clone + Send + Sync + 'static {
type Msg = VecDiff<T>;
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Clone)]
pub struct VecBuffer<T>
where T: Clone + Send + Sync + 'static
{
data: Arc<RwLock<Vec<T>>>,
cast: Arc<RwLock<ObserverBroadcast<RwLock<Vec<T>>>>>
}
impl<T> VecBuffer<T>
where T: Clone + Send + Sync + 'static
{
pub fn with_data(
data: Vec<T>,
port: InnerViewPort<RwLock<Vec<T>>>
) -> 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<RwLock<Vec<T>>>) -> Self {
VecBuffer::with_data(Vec::new(), port)
}
pub fn apply_diff(&mut self, diff: VecDiff<T>) {
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<T> {
MutableVecAccess {
buf: self.clone(),
idx,
val: self.get(idx)
}
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct MutableVecAccess<T>
where T: Clone + Send + Sync + 'static {
buf: VecBuffer<T>,
idx: usize,
val: T,
}
impl<T> Deref for MutableVecAccess<T>
where T: Clone + Send + Sync + 'static {
type Target = T;
fn deref(&self) -> &T {
&self.val
}
}
impl<T> DerefMut for MutableVecAccess<T>
where T: Clone + Send + Sync + 'static {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.val
}
}
impl<T> Drop for MutableVecAccess<T>
where T: Clone + Send + Sync + 'static {
fn drop(&mut self) {
self.buf.update(self.idx, self.val.clone());
}
}

25
nested/src/vec/mod.rs Normal file
View file

@ -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<T> {
Clear,
Push(T),
Remove(usize),
Insert{ idx: usize, val: T },
Update{ idx: usize, val: T }
}

67
nested/src/vec/vec2bin.rs Normal file
View file

@ -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<T, W>
where T: Clone + Send + Sync + 'static,
W: Write + Send + Sync {
data: Option<Arc<RwLock<Vec<T>>>>,
out: RwLock<W>
}
impl<T> OuterViewPort<RwLock<Vec<T>>>
where T: Clone + Serialize + Send + Sync + 'static {
pub fn serialize_bin<W: Write + Send + Sync + 'static>(&self, out: W) -> Arc<RwLock<VecBinWriter<T, W>>> {
let writer = Arc::new(RwLock::new(
VecBinWriter {
data: None,
out: RwLock::new(out),
}
));
self.add_observer(writer.clone());
writer
}
}
impl<T, W> Observer<RwLock<Vec<T>>> for VecBinWriter<T, W>
where T: Clone + Serialize + Send + Sync + 'static,
W: Write + Send + Sync
{
fn reset(&mut self, view: Option<Arc<RwLock<Vec<T>>>>) {
self.data = view;
let mut out = self.out.write().unwrap();
out.write(&bincode::serialized_size(&VecDiff::<T>::Clear).unwrap().to_le_bytes()).expect("");
out.write(&bincode::serialize(&VecDiff::<T>::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<T>) {
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("");
}
}

View file

@ -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<T, W>
where T: Clone + Send + Sync + 'static,
W: Write + Send + Sync {
data: Option<Arc<RwLock<Vec<T>>>>,
out: RwLock<W>
}
impl<T> OuterViewPort<RwLock<Vec<T>>>
where T: Clone + Serialize + Send + Sync + 'static {
pub fn serialize_json<W: Write + Send + Sync + 'static>(&self, out: W) -> Arc<RwLock<VecJsonWriter<T, W>>> {
let writer = Arc::new(RwLock::new(
VecJsonWriter {
data: None,
out: RwLock::new(out),
}
));
self.add_observer(writer.clone());
writer
}
}
impl<T, W> Observer<RwLock<Vec<T>>> for VecJsonWriter<T, W>
where T: Clone + Serialize + Send + Sync + 'static,
W: Write + Send + Sync
{
fn reset(&mut self, view: Option<Arc<RwLock<Vec<T>>>>) {
self.data = view;
self.out.write().unwrap().write(&serde_json::to_string(&VecDiff::<T>::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<T>) {
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<T> VecBuffer<T>
where T: DeserializeOwned + Clone + Send + Sync + 'static
{
pub async fn from_json<R: Read + async_std::io::Read + Unpin>(&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::<VecDiff<T>>(&s).expect("error parsing json");
self.apply_diff(diff);
s.clear();
}
},
c => {
s.push(c as char);
}
}
}
}
}

115
nested/src/vec/vec2seq.rs Normal file
View file

@ -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<T>
where T: Clone + Send + Sync + 'static {
cur_len: usize,
data: Option<Arc<RwLock<Vec<T>>>>,
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = T>>>>
}
impl<T> VecSequence<T>
where T: Clone + Send + Sync + 'static {
pub fn new(
port: InnerViewPort<dyn SequenceView<Item = T>>
) -> Arc<RwLock<Self>> {
let seq = Arc::new(RwLock::new(
VecSequence {
cur_len: 0,
data: None,
cast: port.get_broadcast()
}
));
port.set_view(Some(seq.clone()));
seq
}
}
impl<T> Observer<RwLock<Vec<T>>> for VecSequence<T>
where T: Clone + Send + Sync + 'static {
fn reset(&mut self, view: Option<Arc<RwLock<Vec<T>>>>) {
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<T>) {
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<T> View for VecSequence<T>
where T: Clone + Send + Sync + 'static {
type Msg = usize;
}
impl<T> SequenceView for VecSequence<T>
where T: Clone + Send + Sync + 'static {
type Item = T;
fn get(&self, idx: &usize) -> Option<T> {
self.data.as_ref()?
.read().unwrap()
.get(*idx).cloned()
}
fn len(&self) -> Option<usize> {
Some(self.cur_len)
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl<T> OuterViewPort<RwLock<Vec<T>>>
where T: Clone + Send + Sync + 'static {
pub fn to_sequence(&self) -> OuterViewPort<dyn SequenceView<Item = T>> {
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()
}
}