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

95 lines
2.3 KiB
Rust
Raw Normal View History

2021-04-29 01:32:59 +02:00
use {
std::sync::{Arc, RwLock},
crate::{
core::{
Observer,
InnerViewPort,
OuterViewPort
},
sequence::{SequenceView, VecBuffer}
}
};
pub struct RadixProjection {
src_radix: usize,
dst_radix: usize,
src_digits: Option<Arc<dyn SequenceView<Item = usize>>>,
dst_digits: RwLock<VecBuffer<usize>>
}
impl RadixProjection {
pub fn new(
src_radix: usize,
dst_radix: usize,
src_digits: OuterViewPort<dyn SequenceView<Item = usize>>,
dst_digits: InnerViewPort<RwLock<Vec<usize>>>
) -> Arc<RwLock<Self>> {
let proj = Arc::new(RwLock::new(
RadixProjection {
src_radix,
dst_radix,
src_digits: None,
dst_digits: RwLock::new(VecBuffer::new(dst_digits))
}
));
src_digits.add_observer(proj.clone());
proj
}
fn machine_int(&self) -> usize {
let mut val = 0;
let mut r = 1;
for i in 0 .. self.src_digits.len().unwrap_or(0) {
val += r * self.src_digits.get(&i).unwrap();
r *= self.src_radix;
}
val
}
// recalculate everything
fn update(&self) {
let mut dst = self.dst_digits.write().unwrap();
dst.clear();
let mut val = self.machine_int();
while val > 0 {
dst.push(val % self.dst_radix);
val /= self.dst_radix;
}
}
2021-05-13 16:22:30 +02:00
fn _update_dst_digit(&mut self, _idx: usize) {
2021-04-29 01:32:59 +02:00
/*
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
}
*/
}
}
impl Observer<dyn SequenceView<Item = usize>> for RadixProjection {
fn reset(&mut self, view: Option<Arc<dyn SequenceView<Item = usize>>>) {
self.src_digits = view;
}
2021-05-13 16:22:30 +02:00
fn notify(&self, _idx: &usize) {
2021-04-29 01:32:59 +02:00
// todo:
// src digit i changed.
// which dst-digits does it affect?
// update dst-digit j:
// ...but for now the easy way
self.update();
}
}