lib-nested/lib-nested-core/src/editors/integer/radix.rs

144 lines
3.8 KiB
Rust

use {
r3vi::{
view::{
View, ViewPort,
InnerViewPort, Observer, OuterViewPort,
ObserverBroadcast,
sequence::*,
list::*
},
buffer::{vec::*}
},
crate::{
editors::integer::{
PositionalUInt
},
repr_tree::{ReprTree, ReprLeaf}
},
std::sync::{Arc, RwLock},
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub trait PosIntProjections {
fn transform_radix(&self, dst_radix: u64) -> OuterViewPort<dyn SequenceView<Item = u64>>;
// fn to_digits(&self) -> OuterViewPort<dyn SequenceView<Item = usize>>;
}
impl PosIntProjections for OuterViewPort<dyn PositionalUInt> {
fn transform_radix(&self, dst_radix: u64) -> OuterViewPort<dyn SequenceView<Item = u64>> {
let port = ViewPort::<dyn SequenceView<Item = u64>>::new();
port.add_update_hook(Arc::new(self.0.clone()));
// let mut vec_port = ViewPort::new();
let proj = Arc::new(RwLock::new(RadixProjection {
src: None,
dst_radix,
dst_digits: VecBuffer::new(),
cast: port.inner().get_broadcast()
}));
self.add_observer(proj.clone());
port.set_view(Some(proj as Arc<dyn SequenceView<Item = u64>>));
port.into_outer()
}
/*
fn to_digits(&self) -> OuterViewPort<dyn SequenceView<Item = usize>> {
let port = ViewPort::new();
port.add_update_hook(Arc::new(self.0.clone()));
let proj = Arc::new(RwLock::new(PosUIntToDigits {
src: None,
cast: port.inner().get_broadcast()
}));
self.add_observer(proj.clone());
port.inner().set_view(Some(proj));
port.into_outer()
}
*/
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct RadixProjection {
src: Option<Arc<dyn PositionalUInt>>,
dst_radix: u64,
dst_digits: VecBuffer<u64>,
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = u64>>>>
}
impl View for RadixProjection {
type Msg = usize;
}
impl SequenceView for RadixProjection {
type Item = u64;
fn get(&self, idx: &usize) -> Option<u64> {
if *idx < self.dst_digits.len() {
Some(self.dst_digits.get(*idx))
} else {
None
}
}
fn len(&self) -> Option<usize> {
Some(self.dst_digits.len())
}
}
impl PositionalUInt for RadixProjection {
fn get_radix(&self) -> u64 {
self.dst_radix
}
}
impl Observer< dyn PositionalUInt > for RadixProjection {
fn reset(&mut self, view: Option<Arc<dyn PositionalUInt>>) {
self.src = view;
self.update();
}
fn notify(&mut self, idx: &usize) {
self.update();
// self.update_digit(idx)
}
}
impl RadixProjection {
/// recalculate everything
fn update(&mut self) {
// let mut dst = self.dst_digits;
let old_len = self.dst_digits.len();
self.dst_digits.clear();
if let Some(src) = self.src.as_ref() {
let mut val = src.get_value();
while val > 0 {
self.dst_digits.push(val % self.dst_radix);
val /= self.dst_radix;
}
}
let new_len = self.dst_digits.len();
for i in 0 .. usize::max(old_len, new_len) {
self.cast.write().unwrap().notify(&i);
}
}
fn _update_dst_digit(&mut self, _idx: usize) {
/*
let v = 0; // calculate new digit value
// which src-digits are responsible?
if idx < self.dst_digits.len() {
self.dst_digits.get_mut(idx) = v;
} else if idx == self.dst_digits.len() {
self.dst_digits.push(v);
} else {
// error
}
*/
}
}