diff --git a/worldsim/src/lib.rs b/worldsim/src/lib.rs index ad63ec2059..d9d65622fe 100644 --- a/worldsim/src/lib.rs +++ b/worldsim/src/lib.rs @@ -1,3 +1,4 @@ +#![allow(incomplete_features)] #![feature(const_generics, test)] extern crate serde_derive; diff --git a/worldsim/src/lodstore/data.rs b/worldsim/src/lodstore/data.rs index ab89339773..a534b5cae8 100644 --- a/worldsim/src/lodstore/data.rs +++ b/worldsim/src/lodstore/data.rs @@ -23,6 +23,7 @@ use vek::*; Every Indexstore is a ParentLayer. - DetailStore: Every layer must implement this for their KEY. This is used to store the actual DETAIL of every layer. + - DetailStoreMut: allows mut borrow for Vec types (Hash not supported) !!Calculations will be implemented on these 2 Stores, rather than the actual structs to reduce duplciate coding!! - ToOptionUsize: to store INDEX in z16/u32 efficiently and move up to usize on calculation - Traversable: trait is used to get child layer and child Index for a concrete position. @@ -66,13 +67,19 @@ pub trait IndexStore: ParentLayer { pub trait DetailStore: Layer { type DETAIL; fn load(&self, key: Self::KEY) -> &Self::DETAIL; + fn save(&mut self, key: Self::KEY, detail: Self::DETAIL); +} +pub trait DetailStoreMut: DetailStore { + fn load_mut(&mut self, key: Self::KEY) -> &mut Self::DETAIL; } -pub trait Traversable { - fn get(self) -> C; +pub trait Traversable { + type TRAV_CHILD; + fn get(self) -> Self::TRAV_CHILD; } -pub trait Materializeable { - fn mat(self) -> T; +pub trait Materializeable { + type MAT_CHILD; + fn mat(self) -> Self::MAT_CHILD; } //####################################################### @@ -176,6 +183,16 @@ impl DetailStore fn load(&self, key: Self::KEY) -> &Self::DETAIL { &self.detail[key] } + fn save(&mut self, key: Self::KEY, detail: Self::DETAIL) { + self.detail.insert(key, detail); + } +} +impl DetailStoreMut + for VecNestLayer +{ + fn load_mut(&mut self, key: Self::KEY) -> &mut Self::DETAIL { + &mut self.detail[key] + } } impl DetailStore for HashNestLayer @@ -185,12 +202,24 @@ impl DetailStore debug_assert_eq!(key, key.align_to_level({ L })); &self.detail_index[&key].0 } + fn save(&mut self, key: LodPos, detail: Self::DETAIL) { + debug_assert_eq!(key, key.align_to_level({ L })); + self.detail_index.insert(key, (detail, I::none())); + } } impl DetailStore for VecLayer { type DETAIL = T; fn load(&self, key: usize) -> &Self::DETAIL { &self.detail[key] } + fn save(&mut self, key: usize, detail: Self::DETAIL) { + self.detail[key] = detail; + } +} +impl DetailStoreMut for VecLayer { + fn load_mut(&mut self, key: usize) -> &mut Self::DETAIL { + &mut self.detail[key] + } } impl DetailStore for HashLayer { type DETAIL = T; @@ -198,13 +227,18 @@ impl DetailStore for HashLayer { debug_assert_eq!(key, key.align_to_level({ L })); &self.detail[&key] } + fn save(&mut self, key: LodPos, detail: Self::DETAIL) { + debug_assert_eq!(key, key.align_to_level({ L })); + self.detail.insert(key, detail); + } } -impl<'a, L: DetailStore + IndexStore> Traversable> - for HashIter<'a, L> +impl<'a, L: DetailStore + IndexStore> Traversable for HashIter<'a, L> where L::CHILD: DetailStore, { + type TRAV_CHILD = VecIter<'a, L::CHILD>; + fn get(self) -> VecIter<'a, L::CHILD> { let child_lod = self.wanted.align_to_level(L::CHILD::LEVEL); let pos_offset = relative_to_1d( @@ -226,11 +260,12 @@ where } } -impl<'a, L: DetailStore + IndexStore> Traversable> - for VecIter<'a, L> +impl<'a, L: DetailStore + IndexStore> Traversable for VecIter<'a, L> where L::CHILD: DetailStore, { + type TRAV_CHILD = VecIter<'a, L::CHILD>; + fn get(self) -> VecIter<'a, L::CHILD> { let child_lod = self.wanted.align_to_level(L::CHILD::LEVEL); let pos_offset = relative_to_1d( @@ -252,35 +287,39 @@ where } } -impl<'a, L: DetailStore> Materializeable<&'a L::DETAIL> for HashIter<'a, L> { +impl<'a, L: DetailStore> Materializeable for HashIter<'a, L> { + type MAT_CHILD = &'a L::DETAIL; + fn mat(self) -> &'a L::DETAIL { DetailStore::load(self.layer, self.layer_lod) } } -impl<'a, L: DetailStore> Materializeable<&'a L::DETAIL> for VecIter<'a, L> { +impl<'a, L: DetailStore> Materializeable for VecIter<'a, L> { + type MAT_CHILD = &'a L::DETAIL; + fn mat(self) -> &'a L::DETAIL { DetailStore::load(self.layer, self.layer_key) } } -#[rustfmt::skip] -pub type ExampleData = -HashNestLayer< - VecNestLayer< - VecNestLayer< - VecLayer< - i8, 0 - > ,Option<()>, u16, 2 - > ,() , u32, 3 - > ,() ,u16, 4 ->; - #[cfg(test)] mod tests { use crate::lodstore::data::*; use test::Bencher; + #[rustfmt::skip] + pub type ExampleData = + HashNestLayer< + VecNestLayer< + VecNestLayer< + VecLayer< + i8, 0 + > ,Option<()>, u16, 2 + > ,() , u32, 3 + > ,() ,u16, 4 + >; + fn gen_simple_example() -> ExampleData { let mut detail_index = FxHashMap::default(); detail_index.insert(LodPos::xyz(0, 0, 0), ((), 0)); diff --git a/worldsim/src/lodstore/delta.rs b/worldsim/src/lodstore/delta.rs index 0ca22a1197..a894d25874 100644 --- a/worldsim/src/lodstore/delta.rs +++ b/worldsim/src/lodstore/delta.rs @@ -1,15 +1,7 @@ -/* -use super::{ - data::{ - LodData, - LodConfig, - }, - lodpos::LodPos, - area::LodArea, -}; - -pub type LodIndex = LodPos; - +use super::data::{DetailStore, Layer, ParentLayer, Traversable}; +use super::index::ToOptionUsize; +use super::lodpos::{multily_with_2_pow_n, relative_to_1d, two_pow_u32, LodPos}; +use serde::export::PhantomData; /* A LodDelta applies a change to a Lod The rules for LodDeltas are strict in order to make them as simple as possible. @@ -21,151 +13,148 @@ pub type LodIndex = LodPos; However i belive that most algorithms only change every Value once. */ -#[derive(Debug, Clone)] -pub struct LodDelta { - pub layer0: Vec<(LodIndex, Option)>, // 1/16 - pub layer1: Vec<(LodIndex, Option)>, // 1/8 - pub layer2: Vec<(LodIndex, Option)>, // 1/4 - pub layer3: Vec<(LodIndex, Option)>, // 1/2 - pub layer4: Vec<(LodIndex, Option)>, // 1 - pub layer5: Vec<(LodIndex, Option)>, // 2 - pub layer6: Vec<(LodIndex, Option)>, // 4 - pub layer7: Vec<(LodIndex, Option)>, // 8 - pub layer8: Vec<(LodIndex, Option)>, // 16 - pub layer9: Vec<(LodIndex, Option)>, // 32 - pub layer10: Vec<(LodIndex, Option)>, // 64 - pub layer11: Vec<(LodIndex, Option)>, // 128 - pub layer12: Vec<(LodIndex, Option)>, // 256 - pub layer13: Vec<(LodIndex, Option)>, // 512 - pub layer14: Vec<(LodIndex, Option)>, // 1024 - pub layer15: Vec<(LodIndex, Option)>, // 2048 -} - -impl LodDelta { - pub fn new() -> Self { - Self { - layer0: Vec::new(), - layer1: Vec::new(), - layer2: Vec::new(), - layer3: Vec::new(), - layer4: Vec::new(), - layer5: Vec::new(), - layer6: Vec::new(), - layer7: Vec::new(), - layer8: Vec::new(), - layer9: Vec::new(), - layer10: Vec::new(), - layer11: Vec::new(), - layer12: Vec::new(), - layer13: Vec::new(), - layer14: Vec::new(), - layer15: Vec::new(), - } - } - - //TODO: apply that moves out - pub fn apply(&self, data: &mut LodData) { - for (index, item) in &self.layer15 { - if let Some(item) = item { - data.set15(*index, item.clone(), None); - } - } - for (index, item) in &self.layer14 { - if let Some(item) = item { - data.set14(*index, item.clone(), None); - } - } - for (index, item) in &self.layer13 { - if let Some(item) = item { - data.set13(*index, item.clone(), None); - } - } - for (index, item) in &self.layer12 { - if let Some(item) = item { - data.set12(*index, item.clone(), None); - } - } - for (index, item) in &self.layer11 { - if let Some(item) = item { - data.set11(*index, item.clone(), None); - } - } - for (index, item) in &self.layer10 { - if let Some(item) = item { - data.set10(*index, item.clone(), None); - } - } - for (index, item) in &self.layer9 { - if let Some(item) = item { - data.set9(*index, item.clone(), None); - } - } - for (index, item) in &self.layer8 { - if let Some(item) = item { - data.set8(*index, item.clone(), None); - } - } - for (index, item) in &self.layer7 { - if let Some(item) = item { - data.set7(*index, item.clone(), None); - } - } - for (index, item) in &self.layer6 { - if let Some(item) = item { - data.set6(*index, item.clone(), None); - } - } - for (index, item) in &self.layer5 { - if let Some(item) = item { - data.set5(*index, item.clone(), None); - } - } - for (index, item) in &self.layer4 { - if let Some(item) = item { - data.set4(*index, item.clone(), None); - } - } - for (index, item) in &self.layer3 { - if let Some(item) = item { - data.set3(*index, item.clone(), None); - } - } - for (index, item) in &self.layer2 { - if let Some(item) = item { - data.set2(*index, item.clone(), None); - } - } - for (index, item) in &self.layer1 { - if let Some(item) = item { - data.set1(*index, item.clone(), None); - } - } - for (index, item) in &self.layer0 { - if let Some(item) = item { - data.set0(*index, item.clone(), None); - } - } - } - - pub fn filter(&self, area: LodArea) -> Self { - Self { - layer0: self.layer0.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer1: self.layer1.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer2: self.layer2.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer3: self.layer3.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer4: self.layer4.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer5: self.layer5.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer6: self.layer6.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer7: self.layer7.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer8: self.layer8.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer9: self.layer9.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer10: self.layer10.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer11: self.layer11.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer12: self.layer12.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer13: self.layer13.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer14: self.layer14.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - layer15: self.layer15.iter().filter(|(index, _)| area.is_inside(index.clone())).cloned().collect(), - } - } -} +/* +The Idea is to create a DeltaWriter that has a mutable Detla and Data and implements the Data interaces. +While it borrows a mutable reference to both it locks both with rusts system +When the writing is done, we destroy the Writer but keep the Delta and Data. +The DeltaWriter will output its own iterator, +We only need a traversable trait */ +pub trait Delta: Layer {} + +#[derive(Default, Clone)] +pub struct VecDelta { + pub detail: Vec<(LodPos, Option)>, +} +#[derive(Default, Clone)] +pub struct VecNestDelta { + pub detail: Vec<(LodPos, Option)>, + pub child: D, +} + +pub struct DeltaWriter<'a, C: DetailStore, D: Delta> { + pub delta: &'a mut D, + pub data: &'a mut C, +} + +struct VecDataIter<'a, D: Delta> { + layer: &'a D, +} + +struct DataWriterIter { + delta_iter: DT, + data_iter: CT, +} + +//####################################################### + +impl Layer for VecDelta { + type KEY = (usize); + const LEVEL: u8 = { L }; +} +impl Layer for VecNestDelta { + type KEY = (usize); + const LEVEL: u8 = { L }; +} + +impl ParentLayer for VecNestDelta { + type CHILD = D; + fn child(&self) -> &Self::CHILD { + &self.child + } +} + +impl<'a, C: DetailStore, D: Delta> DeltaWriter<'a, C, D> { + pub fn new(delta: &'a mut D, data: &'a mut C) -> Self { + DeltaWriter { delta, data } + } +} + +impl<'a, C: DetailStore, D: Delta> DeltaWriter<'a, C, D> { + #[allow(dead_code)] + fn trav(&'a self, pos: LodPos) -> VecDataIter<'a, D> { + VecDataIter { layer: &self.delta } + } +} + +impl<'a, D: Delta + ParentLayer> Traversable for VecDataIter<'a, D> +where + D::CHILD: Delta, +{ + type TRAV_CHILD = VecDataIter<'a, D::CHILD>; + + fn get(self) -> VecDataIter<'a, D::CHILD> { + VecDataIter { + layer: self.layer.child(), + } + } +} + +impl<'a, DT: Traversable, CT: Traversable> Traversable for DataWriterIter +where + DT::TRAV_CHILD: Traversable, + CT::TRAV_CHILD: Traversable, +{ + type TRAV_CHILD = DataWriterIter; + + fn get(self) -> DataWriterIter { + DataWriterIter { + delta_iter: self.delta_iter.get(), + data_iter: self.data_iter.get(), + } + } +} + +impl Delta for VecDelta {} +impl Delta for VecNestDelta {} + +//####################################################### + +#[cfg(test)] +mod tests { + use crate::lodstore::data::*; + use crate::lodstore::delta::*; + use test::Bencher; + + #[rustfmt::skip] + pub type ExampleData = + HashNestLayer< + VecNestLayer< + VecNestLayer< + VecLayer< + i8, 0 + > ,Option<()>, u16, 2 + > ,() , u32, 3 + > ,() ,u16, 4 + >; + + #[rustfmt::skip] + pub type ExampleDelta = + VecNestDelta< + VecNestDelta< + VecNestDelta< + VecDelta< + i8, 0 + >, Option<()>, 2 + >, (), 3 + >, (), 4 + >; + + #[test] + fn compilation() { + let mut x = ExampleData::default(); + let mut d = ExampleDelta::default(); + { + let w = DeltaWriter::new(&mut d, &mut x); + let i = LodPos::xyz(0, 1, 2); + + if false {} + } + } + + #[test] + fn access_first_element() { + let x = ExampleDelta::default(); + let i = LodPos::xyz(0, 0, 0); + } +} diff --git a/worldsim/src/lodstore/drill.rs b/worldsim/src/lodstore/drill.rs new file mode 100644 index 0000000000..0bc00cd17f --- /dev/null +++ b/worldsim/src/lodstore/drill.rs @@ -0,0 +1,23 @@ +use super::delta::Delta; +use super::index::ToOptionUsize; +use fxhash::FxHashMap; +use std::{u16, u32}; +use vek::*; + +/* + traits: + - DrillDown + - DrillUp +*/ + +pub trait DrillDownable { + type DELTA: Delta; + fn drill_down(detail: Self) -> Self::DELTA; +} + +pub trait DrillUpable { + type DELTA: Delta; + fn drill_up(detail: Self) -> Self::DELTA; +} + +//####################################################### diff --git a/worldsim/src/lodstore/index.rs b/worldsim/src/lodstore/index.rs index e3717f3b6f..c838a4a268 100644 --- a/worldsim/src/lodstore/index.rs +++ b/worldsim/src/lodstore/index.rs @@ -1,11 +1,15 @@ use std::{u16, u32}; pub trait ToOptionUsize: Copy { + fn none() -> Self; fn is_some(self) -> bool; fn into_usize(self) -> usize; } impl ToOptionUsize for u32 { + fn none() -> Self { + u32::MAX + } fn is_some(self) -> bool { self != u32::MAX } @@ -15,6 +19,9 @@ impl ToOptionUsize for u32 { } impl ToOptionUsize for u16 { + fn none() -> Self { + u16::MAX + } fn is_some(self) -> bool { self != u16::MAX } diff --git a/worldsim/src/lodstore/mod.rs b/worldsim/src/lodstore/mod.rs index f6ddeedb7e..5499a3ce48 100644 --- a/worldsim/src/lodstore/mod.rs +++ b/worldsim/src/lodstore/mod.rs @@ -1,6 +1,7 @@ pub mod area; pub mod data; pub mod delta; +pub mod drill; pub mod index; pub mod lodpos; pub use data::{HashLayer, HashNestLayer, VecLayer, VecNestLayer};