From ff0d44d0153ea09b9af083251adebfad82523d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=A4rtens?= Date: Tue, 29 Oct 2019 09:30:34 +0100 Subject: [PATCH] implement a DeltaStorage System similar to DataStore, however i stil need to make duplicate non modifyable and mutable implementations, even though i only need mut, and this should somehow be simplified. also the borrow checker is still quite chaotic --- worldsim/src/lodstore/delta.rs | 109 +++++++++++++++++++---- worldsim/src/lodstore/deltalizeable.rs | 16 ++++ worldsim/src/lodstore/drill.rs | 6 +- worldsim/src/lodstore/entrylayer.rs | 22 ++--- worldsim/src/lodstore/layer.rs | 18 ++-- worldsim/src/lodstore/materializeable.rs | 19 ++-- worldsim/src/lodstore/mod.rs | 1 + worldsim/src/lodstore/traversable.rs | 25 ++++-- 8 files changed, 167 insertions(+), 49 deletions(-) create mode 100644 worldsim/src/lodstore/deltalizeable.rs diff --git a/worldsim/src/lodstore/delta.rs b/worldsim/src/lodstore/delta.rs index f3063c0d49..d8adfe9449 100644 --- a/worldsim/src/lodstore/delta.rs +++ b/worldsim/src/lodstore/delta.rs @@ -19,27 +19,34 @@ use std::marker::PhantomData; However i belive that most algorithms only change every Value once. */ -pub trait Delta: Layer {} +pub trait DeltaStore: Layer { + type DETAIL; + fn store(&mut self, pos: LodPos, value: Option); +} #[derive(Default, Clone)] pub struct VecDelta { pub detail: Vec<(LodPos, Option)>, } #[derive(Default, Clone)] -pub struct VecNestDelta { +pub struct VecNestDelta { pub detail: Vec<(LodPos, Option)>, pub child: D, } -pub struct DeltaWriter<'a, C: EntryLayer<'a> + DetailStore, D: EntryLayer<'a> + Delta> { +pub struct DeltaWriter<'a, C: EntryLayer<'a> + DetailStore, D: EntryLayer<'a> + DeltaStore> { pub delta: &'a mut D, pub data: &'a mut C, } -pub struct VecDataIter<'a, D: Delta> { +pub struct VecDeltaIter<'a, D: DeltaStore> { pub( super ) layer: &'a D, } +pub struct VecDeltaIterMut<'a, D: DeltaStore> { + pub( super ) layer: &'a mut D, +} + pub struct DataWriterIter<'a, DT: 'a, CT: 'a> { pub( super ) delta_iter: DT, pub( super ) data_iter: CT, @@ -48,14 +55,24 @@ pub struct DataWriterIter<'a, DT: 'a, CT: 'a> { //####################################################### -impl<'a, C: DetailStore + EntryLayer<'a>, D: Delta + EntryLayer<'a>> DeltaWriter<'a, C, D> { +impl<'a, C: DetailStore + EntryLayer<'a>, D: DeltaStore + EntryLayer<'a>> DeltaWriter<'a, C, D> { pub fn new(delta: &'a mut D, data: &'a mut C) -> Self { DeltaWriter { delta, data } } } -impl Delta for VecDelta {} -impl Delta for VecNestDelta {} +impl DeltaStore for VecDelta { + type DETAIL = T; + fn store(&mut self, pos: LodPos, value: Option) { + self.detail.push((pos, value)); + } +} +impl DeltaStore for VecNestDelta { + type DETAIL = T; + fn store(&mut self, pos: LodPos, value: Option) { + self.detail.push((pos, value)); + } +} //####################################################### @@ -83,10 +100,10 @@ mod tests { let mut x = ExampleData::default(); let mut d = ExampleDelta::default(); { - let w = DeltaWriter::new(&mut d, &mut x); + let mut w = DeltaWriter::new(&mut d, &mut x); let i = LodPos::xyz(0, 1, 2); if false { - let y = w.trav(i); + let y = w.trav_mut(i); let ttc = y.get().get().get(); let _tt = ttc.mat(); } @@ -98,9 +115,71 @@ mod tests { let mut x = gen_simple_example(); let mut d = ExampleDelta::default(); { - let w = DeltaWriter::new(&mut d, &mut x); + let mut w = DeltaWriter::new(&mut d, &mut x); let i = LodPos::xyz(0, 0, 0); - assert_eq!(*w.trav(i).get().get().get().mat(), 7_i8); + assert_eq!(*w.trav_mut(i).get().get().get().mat(), 7_i8); + } + } + + #[test] + fn mut_first_element() { + let mut x = gen_simple_example(); + let mut d = ExampleDelta::default(); + //assert_eq!(x.detail_index.len(),1); + assert_eq!(d.detail.len(),0); + assert_eq!(d.child.detail.len(),0); + assert_eq!(d.child.child.detail.len(),0); + assert_eq!(d.child.child.child.detail.len(),0); + let i = LodPos::xyz(0, 0, 0); + { + let mut w = DeltaWriter::new(&mut d, &mut x); + assert_eq!(*w.trav_mut(i).get().get().get().mat(), 7_i8); + } + { + let mut w = DeltaWriter::new(&mut d, &mut x); + w.trav_mut(i).get().get().get().store(123); + } + { //TODO: this shouldnt be necessary but somehow it is... + let mut w = DeltaWriter::new(&mut d, &mut x); + assert_eq!(*w.trav_mut(i).get().get().get().mat(), 123_i8); + assert_eq!(d.detail.len(),0); + assert_eq!(d.child.detail.len(),0); + assert_eq!(d.child.child.detail.len(),0); + assert_eq!(d.child.child.child.detail.len(),1); + //assert_eq!(x.detail_index.len(),1); + } + } + + #[test] + fn mut_multiple_elements() { + let mut x = gen_simple_example(); + let mut d = ExampleDelta::default(); + let i = LodPos::xyz(0, 0, 0); + { + let mut w = DeltaWriter::new(&mut d, &mut x); + assert_eq!(*w.trav_mut(i).get().get().get().mat(), 7_i8); + } + { + let mut w = DeltaWriter::new(&mut d, &mut x); + w.trav_mut(i).get().get().get().store(123); + } + { + let mut w = DeltaWriter::new(&mut d, &mut x); + w.trav_mut(LodPos::xyz(0, 0, 1)).get().get().get().store(111); + } + { + let mut w = DeltaWriter::new(&mut d, &mut x); + w.trav_mut(LodPos::xyz(0, 0, 2)).get().get().get().store(112); + } + { + let mut w = DeltaWriter::new(&mut d, &mut x); + w.trav_mut(LodPos::xyz(0, 0, 3)).get().get().get().store(111); + } + { //TODO: this shouldnt be necessary but somehow it is... + let mut w = DeltaWriter::new(&mut d, &mut x); + let i = LodPos::xyz(0, 0, 0); + assert_eq!(*w.trav_mut(i).get().get().get().mat(), 123_i8); + assert_eq!(x.detail_index.len(),1); } } @@ -109,9 +188,9 @@ mod tests { let mut x = gen_simple_example(); let mut d = ExampleDelta::default(); { - let w = DeltaWriter::new(&mut d, &mut x); + let mut w = DeltaWriter::new(&mut d, &mut x); let access = LodPos::xyz(0, 0, 0); - b.iter(|| w.trav(access)); + b.iter(|| w.trav_mut(access)); } } @@ -120,9 +199,9 @@ mod tests { let mut x = gen_simple_example(); let mut d = ExampleDelta::default(); { - let w = DeltaWriter::new(&mut d, &mut x); + let mut w = DeltaWriter::new(&mut d, &mut x); let access = LodPos::xyz(0, 0, 0); - b.iter(|| w.trav(access).get().get().get().mat()); + b.iter(|| w.trav_mut(access).get().get().get().mat()); } } } diff --git a/worldsim/src/lodstore/deltalizeable.rs b/worldsim/src/lodstore/deltalizeable.rs new file mode 100644 index 0000000000..7457b0dea8 --- /dev/null +++ b/worldsim/src/lodstore/deltalizeable.rs @@ -0,0 +1,16 @@ +use super::lodpos::{LodPos}; +use super::delta::{DeltaStore, VecDeltaIterMut}; + +pub trait Deltalizeable { + type DELTA: DeltaStore; + fn store(self, pos: LodPos, value: Option<::DETAIL>); +} + +///////////////// delta types + +impl<'a, D: DeltaStore> Deltalizeable for VecDeltaIterMut<'a, D> { + type DELTA = D; + fn store(self, pos: LodPos, value: Option) { + self.layer.store(pos, value); + } +} \ No newline at end of file diff --git a/worldsim/src/lodstore/drill.rs b/worldsim/src/lodstore/drill.rs index 4493a5a4f7..ea231b4108 100644 --- a/worldsim/src/lodstore/drill.rs +++ b/worldsim/src/lodstore/drill.rs @@ -1,4 +1,4 @@ -use super::delta::Delta; +use super::delta::DeltaStore; /* traits: @@ -7,12 +7,12 @@ use super::delta::Delta; */ pub trait DrillDownable { - type DELTA: Delta; + type DELTA: DeltaStore; fn drill_down(detail: Self) -> Self::DELTA; } pub trait DrillUpable { - type DELTA: Delta; + type DELTA: DeltaStore; fn drill_up(detail: Self) -> Self::DELTA; } diff --git a/worldsim/src/lodstore/entrylayer.rs b/worldsim/src/lodstore/entrylayer.rs index fec353327b..9f3ac41e07 100644 --- a/worldsim/src/lodstore/entrylayer.rs +++ b/worldsim/src/lodstore/entrylayer.rs @@ -1,7 +1,7 @@ use super::index::ToOptionUsize; use super::lodpos::LodPos; use super::data::{HashNestLayer, DetailStore, HashIter, HashIterMut}; -use super::delta::{VecNestDelta, Delta, VecDataIter, DataWriterIter, DeltaWriter}; +use super::delta::{VecNestDelta, DeltaStore, VecDeltaIter, VecDeltaIterMut, DataWriterIter, DeltaWriter}; use super::traversable::Traversable; use std::marker::PhantomData; @@ -40,26 +40,26 @@ for HashNestLayer ///////////////// delta types -impl<'a, D: 'a + Delta, T: 'a, const L: u8> EntryLayer<'a> for VecNestDelta { - type TRAV = VecDataIter<'a, VecNestDelta>; - type TRAV_MUT = VecDataIter<'a, VecNestDelta>; +impl<'a, D: 'a + DeltaStore, T: 'a, const L: u8> EntryLayer<'a> for VecNestDelta { + type TRAV = VecDeltaIter<'a, VecNestDelta>; + type TRAV_MUT = VecDeltaIterMut<'a, VecNestDelta>; fn trav(&'a self, _pos: LodPos) -> Self::TRAV { - VecDataIter { layer: self } + VecDeltaIter { layer: self } } fn trav_mut(&'a mut self, _pos: LodPos) -> Self::TRAV_MUT { - VecDataIter { layer: self } + VecDeltaIterMut { layer: self } } } -impl<'a, C: DetailStore + EntryLayer<'a>, D: Delta + EntryLayer<'a>> EntryLayer<'a> +impl<'a, C: DetailStore + EntryLayer<'a>, D: DeltaStore + EntryLayer<'a>> EntryLayer<'a> for DeltaWriter<'a, C, D> where <>::TRAV as Traversable>::TRAV_CHILD: Traversable, <>::TRAV as Traversable>::TRAV_CHILD: Traversable, { type TRAV = DataWriterIter<'a, D::TRAV, C::TRAV>; - type TRAV_MUT = DataWriterIter<'a, D::TRAV, C::TRAV>; + type TRAV_MUT = DataWriterIter<'a, D::TRAV_MUT, C::TRAV_MUT>; fn trav(&'a self, pos: LodPos) -> DataWriterIter { DataWriterIter { @@ -69,10 +69,10 @@ for DeltaWriter<'a, C, D> } } - fn trav_mut(&'a mut self, pos: LodPos) -> DataWriterIter { + fn trav_mut(&'a mut self, pos: LodPos) -> DataWriterIter { DataWriterIter { - delta_iter: self.delta.trav(pos), - data_iter: self.data.trav(pos), + delta_iter: self.delta.trav_mut(pos), + data_iter: self.data.trav_mut(pos), _a: PhantomData::<&'a ()>::default(), } } diff --git a/worldsim/src/lodstore/layer.rs b/worldsim/src/lodstore/layer.rs index 48d0de4f57..e8737acc62 100644 --- a/worldsim/src/lodstore/layer.rs +++ b/worldsim/src/lodstore/layer.rs @@ -1,7 +1,7 @@ use super::index::ToOptionUsize; use super::lodpos::{two_pow_u, LodPos}; use super::data::{VecLayer, HashLayer, VecNestLayer, HashNestLayer, DetailStore}; -use super::delta::{VecDelta, VecNestDelta, Delta}; +use super::delta::{VecDelta, VecNestDelta, DeltaStore}; use vek::Vec3; pub trait Layer { @@ -25,19 +25,19 @@ pub trait ParentLayer: Layer { ///////////////// data types impl Layer for VecLayer { - type KEY = (usize); + type KEY = usize; const LEVEL: u8 = { L }; } impl Layer for HashLayer { - type KEY = (LodPos); + type KEY = LodPos; const LEVEL: u8 = { L }; } impl Layer for VecNestLayer { - type KEY = (usize); + type KEY = usize; const LEVEL: u8 = { L }; } impl Layer for HashNestLayer { - type KEY = (LodPos); + type KEY = LodPos; const LEVEL: u8 = { L }; } @@ -67,15 +67,15 @@ impl ParentLayer ///////////////// delta types impl Layer for VecDelta { - type KEY = (usize); + type KEY = usize; const LEVEL: u8 = { L }; } -impl Layer for VecNestDelta { - type KEY = (usize); +impl Layer for VecNestDelta { + type KEY = usize; const LEVEL: u8 = { L }; } -impl ParentLayer for VecNestDelta { +impl ParentLayer for VecNestDelta { type CHILD = D; fn child(&self) -> &Self::CHILD { &self.child diff --git a/worldsim/src/lodstore/materializeable.rs b/worldsim/src/lodstore/materializeable.rs index c3faf6b786..66180b7af7 100644 --- a/worldsim/src/lodstore/materializeable.rs +++ b/worldsim/src/lodstore/materializeable.rs @@ -1,6 +1,7 @@ use super::lodpos::{LodPos}; use super::data::{DetailStore, HashIter, VecIter, HashIterMut, VecIterMut}; -use super::delta::DataWriterIter; +use super::delta::{DataWriterIter}; +use super::deltalizeable::{Deltalizeable}; /* @@ -32,7 +33,8 @@ type MAT_CHILD = L::DETAIL; fn mat(self) -> &'a L::DETAIL { DetailStore::load(self.layer, self.layer_lod) } -fn store(self, mat: L::DETAIL) { +fn store(self, _mat: L::DETAIL) { + unimplemented!("only call on mut Iter"); //DetailStore::save(self.layer, self.layer_key, mat) } } @@ -44,7 +46,7 @@ impl<'a, L: DetailStore> Materializeable<'a> for HashIterMut<'a, L DetailStore::load(self.layer, self.layer_lod) } fn store(self, mat: L::DETAIL) { -//DetailStore::save(self.layer, self.layer_key, mat) + DetailStore::save(self.layer, self.layer_lod, mat) } } @@ -52,7 +54,8 @@ impl<'a, L: DetailStore> Materializeable<'a> for VecIter<'a, L> { type MAT_CHILD = L::DETAIL; fn mat(self) -> &'a L::DETAIL { DetailStore::load(self.layer, self.layer_key) } -fn store(self, mat: L::DETAIL) { +fn store(self, _mat: L::DETAIL) { + unimplemented!("only call on mut Iter"); //DetailStore::save(self.layer, self.layer_key, mat) } } @@ -68,13 +71,19 @@ impl<'a, L: DetailStore> Materializeable<'a> for VecIterMut<'a, L> ///////////////// delta types -impl<'a, DT, CT: Materializeable<'a>> Materializeable<'a> for DataWriterIter<'a, DT, CT> { +impl<'a, DT: Deltalizeable, CT: Materializeable<'a>> Materializeable<'a> for DataWriterIter<'a, DT, CT> { type MAT_CHILD = CT::MAT_CHILD; fn mat(self) -> &'a CT::MAT_CHILD { self.data_iter.mat() } fn store(self, mat: CT::MAT_CHILD) { + //self.delta_iter.register(LodPos::xyz(2,2,2,), mat); + + //
::DELTA::store(self.delta_iter,LodPos::xyz(2,2,2), None); + self.delta_iter.store(LodPos::xyz(2,2,2), None); + println!("saaave"); + self.data_iter.store(mat); //self.data_iter.store(mat) } } diff --git a/worldsim/src/lodstore/mod.rs b/worldsim/src/lodstore/mod.rs index 6745c8cb20..a71945e326 100644 --- a/worldsim/src/lodstore/mod.rs +++ b/worldsim/src/lodstore/mod.rs @@ -3,6 +3,7 @@ pub mod lodarea; pub mod layer; pub mod traversable; pub mod materializeable; +pub mod deltalizeable; pub mod entrylayer; pub mod data; pub mod delta; diff --git a/worldsim/src/lodstore/traversable.rs b/worldsim/src/lodstore/traversable.rs index a9dcf6c982..c8686e4c09 100644 --- a/worldsim/src/lodstore/traversable.rs +++ b/worldsim/src/lodstore/traversable.rs @@ -1,7 +1,7 @@ use super::index::ToOptionUsize; use super::lodpos::{multily_with_2_pow_n, relative_to_1d, LodPos}; use super::data::{DetailStore, IndexStore, HashIter, VecIter, HashIterMut, VecIterMut}; -use super::delta::{Delta, VecDataIter, DataWriterIter}; +use super::delta::{DeltaStore, VecDeltaIter, VecDeltaIterMut, DataWriterIter}; #[allow(unused_imports)] //not unsued, cargo is just to stupud to detect that use super::layer::{Layer, ParentLayer}; use std::marker::PhantomData; @@ -123,19 +123,32 @@ impl<'a, L: DetailStore + IndexStore> Traversable for VecIterMut<'a ///////////////// delta types -impl<'a, D: Delta + ParentLayer> Traversable for VecDataIter<'a, D> +impl<'a, D: DeltaStore + ParentLayer> Traversable for VecDeltaIter<'a, D> where - D::CHILD: Delta, + D::CHILD: DeltaStore, { - type TRAV_CHILD = VecDataIter<'a, D::CHILD>; + type TRAV_CHILD = VecDeltaIter<'a, D::CHILD>; - fn get(self) -> VecDataIter<'a, D::CHILD> { - VecDataIter { + fn get(self) -> VecDeltaIter<'a, D::CHILD> { + VecDeltaIter { layer: self.layer.child(), } } } +impl<'a, D: DeltaStore + ParentLayer> Traversable for VecDeltaIterMut<'a, D> + where + D::CHILD: DeltaStore, +{ + type TRAV_CHILD = VecDeltaIterMut<'a, D::CHILD>; + + fn get(self) -> VecDeltaIterMut<'a, D::CHILD> { + VecDeltaIterMut { + layer: self.layer.child_mut(), + } + } +} + impl<'a, DT: Traversable, CT: Traversable> Traversable for DataWriterIter<'a, DT, CT> { type TRAV_CHILD = DataWriterIter<'a, DT::TRAV_CHILD, CT::TRAV_CHILD>;