move to associated types in most traits to clean up mess

implement a api to travers to the Detail already
create a DetailStore for actual work on the Detail
create Nestable for child layer trait
update description
This commit is contained in:
Marcel Märtens 2019-10-09 16:34:37 +02:00
parent 85ca33024c
commit 70831aea62

View File

@ -10,202 +10,268 @@ use super::index::{
}; };
use super::area::LodArea; use super::area::LodArea;
use super::delta::LodDelta; use super::delta::LodDelta;
use serde::export::PhantomData;
/* /*
traits and structs explained: Terminology:
- IndexStore: Every detail must implement this for either <usize, I> or <LodIndex, I>. depending on the store of the parent detail. - Layer: the layer of the LoDTree, a tree can have n layers, every layer contains their child layer, except for the last one.
It is accessed by parent layer to store the index when a detail is added or removed. Each layer contains a level, a number from 15-0. the level of each child must be lower than the parents layer!
- VecVecStore/VecHashStore/HashVecStore[HashHashStore]: Handles the different combination of layer and parent layer. Currently only 3 exist because for now there is no Hash in between the chain. - Detail: Each Layer contains information about that layer, here called Detail. This is the usable information we want to store in the LoDTree
We use this to half the number of structs we need. Also we can implement all algorithms which only requiere layer and parent layer on top of this trait. Each detail has a position. Multiple Details can exist at the same position on different layers!
That reduced duplicate coding because it is used in layers as well as the leaf layers. - Index: this is a bit ambiguous yet, it either means a value from type LodIndex, a LodIndex always marks a specific position in the LoDTree(but not layer)
- actual structs regarding of position in the chain. They represent the Layers and contain the details. or this refers to the actually storage for the index for the next layer (often a u16,u32)
Naming Scheme is <Own Detail Type><Parent Detail Type>[Nest]Layer //TODO: define the LodIndex as LoDPosition
1) VecVecLayer/VecHashLayer: Vec Leaf Layers that have a vec/hash index. - Key: always refers to the storage of a LAYER. Any keyword with KEY is either of type usize or LodIndex.
2) VecVecNestLayer/VecHashNestLayer: Vec Layers that have a vec/hash index and are middle layers
3) HashNoneNestLayer: Hash Layer that has no index and must be parent layer
traits:
- IndexStore: Every layer must implement this for either KEY=usize or KEY=LodIndex and INDEX is often u16/u32. depending on the store of the parent detail.
It is accessed by parent layer to store the index when a detail is added or removed.
- DetailStore: Every layer must implement this for either KEY=usize or KEY=LodIndex, independent from the parent.
This is used to store the actual detail of every layer.
- Nestable: All layers, except the lowest one implement this trait. It links the below layer to interact with the child layer.
!!Calculations will be implemented on these 3 Stores, rather than the actual structs to reduce duplciate coding!!
- Traversable: trait is used to get child layer and child Index for a concrete position.
- Materializeable: trait is used to actually return a Detail for a concrete position.
Actual structs regarding of position in the chain. They represent the Layers and contain the Details, they implement (some of) the 3 Store traits
Naming Scheme is <Own Detail Type><Parent Detail Type>[Nest]Layer
- VecVecLayer/VecHashLayer: Vec Leaf Layers that have a vec/hash index and dont have a child layer.
- VecVecNestLayer/VecHashNestLayer: Vec Layers that have a vec/hash index and are middle layers
- HashNoneNestLayer: Hash Layer that has no index and must be parent layer
Result Structs:
- LayerResult: Is used to access a layer meta information or Detail via LoDTree.traverse().get().get().get().mat().
When LoDTree.traverse() returns a LayerResult.
*/ */
//K: Key is either usize or LodIndex //K: Key is either usize or LodIndex
//I: Index stored, often u16 or u32 //I: Index stored, often u16 or u32
pub trait IndexStore<K, I: Copy> { pub trait IndexStore {
fn load(&mut self, key: K) -> I; type KEY;
fn store(&mut self, key: K, index: I); type INDEX: Copy;
fn load(&mut self, key: Self::KEY) -> Self::INDEX;
fn store(&mut self, key: Self::KEY, index: Self::INDEX);
} }
pub trait DatailStore<K2, T> { pub trait DetailStore {
fn load(&mut self, key: K2) -> &T; type KEY;
fn load_mut(&mut self, key: K2) -> &mut T; type DETAIL;
fn store(&mut self, key: K2, index: T);
fn load(&mut self, key: Self::KEY) -> &Self::DETAIL;
fn load_mut(&mut self, key: Self::KEY) -> &mut Self::DETAIL;
fn store(&mut self, key: Self::KEY, detail: Self::DETAIL);
} }
// Algorithms for a Layer are impemented based on these traits pub trait Nestable {
pub trait VecVecStore<T, I: Copy> { type NESTED: IndexStore + DetailStore;
fn detail(&self) -> &Vec<T>;
fn detail_mut(&mut self) -> &mut Vec<T>; fn nested(&self) -> &Self::NESTED;
fn index(&self) -> &Vec<I>;
fn index_mut(&mut self) -> &mut Vec<I>;
}
pub trait VecHashStore<T, I: Copy> {
fn detail(&self) -> &Vec<T>;
fn detail_mut(&mut self) -> &mut Vec<T>;
fn index(&self) -> &HashMap<LodIndex, I>;
fn index_mut(&mut self) -> &mut HashMap<LodIndex, I>;
}
pub trait HashNoneStore<T, I: Copy> {
fn detail(&self) -> &HashMap<LodIndex, T>;
fn detail_mut(&mut self) -> &mut HashMap<LodIndex, T>;
// fn get(&self, index: LodIndex) -> (&Child, index: LodIndex, usize/*shouldnt this be based on child ?*/)
} }
pub trait Traversable<C> { pub trait Traversable<C> {
fn get() -> C; fn get(&self) -> C;
} }
pub trait Materializeable<T> { pub trait Materializeable<T> {
fn mat() -> T; fn mat(&self) -> T;
} }
/* //struct LayerResult<'a, N: IndexStore<PK, I> + DetailStore<K, CT>, PK, I: Copy, K, CT> {
struct LayerResult<C> { pub struct LayerResult<'a, N: IndexStore + DetailStore, PK> {
child: &C, child: &'a N,
index: LodIndex, wanted: LodIndex,
C::Type, index: PK,
}
impl LayerResult {
fn get() -> LayerReslt<C::C>;
fn mat() -> T;
}*/
pub trait Lod<T> {
fn materialize(&self, i:LodIndex) -> &T;
} }
//####################################################### //#######################################################
// Name <Own detail><Parent Index> // Name <Own detail><Parent Index>
pub struct VecVecLayer<T, I: Copy, const L: u8> { pub struct VecVecLayer<T, PI: Copy, const L: u8> {
pub detail: Vec<T>, pub detail: Vec<T>,
pub index: Vec<I>, pub index: Vec<PI>,
} }
pub struct VecHashLayer<T, I: Copy, const L: u8> { pub struct VecHashLayer<T, PI: Copy, const L: u8> {
pub detail: Vec<T>, pub detail: Vec<T>,
pub index: HashMap<LodIndex, I>, pub index: HashMap<LodIndex, PI>,
} }
pub struct VecVecNestLayer<N: IndexStore<K, I>, T, K, I: Copy, const L: u8> { //K: Child detail storage type usize or LodIndex
//T: own detail type
//PI: parents index type u16, u32
//CT: Child detail type
//I: own index type u16, u32
//pub struct VecVecNestLayer<N: IndexStore<usize, I> + DetailStore<K, CT>, K, T, PI: Copy, CT, I: Copy, const L: u8> {
pub struct VecVecNestLayer<N: IndexStore + DetailStore, T, PI: Copy, const L: u8> {
pub detail: Vec<T>, pub detail: Vec<T>,
pub index: Vec<I>, pub index: Vec<PI>,
pub nested: N, pub nested: N,
pk_: PhantomData<K>,
} }
pub struct VecHashNestLayer<N: IndexStore<K, I>, T, K, I: Copy, const L: u8> { //pub struct VecHashNestLayer<N: IndexStore<usize, I> + DetailStore<K, CT>, K, T, PI: Copy, CT, I: Copy, const L: u8> {
pub struct VecHashNestLayer<N: IndexStore + DetailStore, T, PI: Copy, const L: u8> {
pub detail: Vec<T>, pub detail: Vec<T>,
pub index: HashMap<LodIndex, I>, pub index: HashMap<LodIndex, PI>,
pub nested: N, pub nested: N,
pk_: PhantomData<K>,
} }
pub struct HashNoneNestLayer<N: IndexStore<K, I>, T, K, I: Copy, const L: u8> { //pub struct HashNoneNestLayer<N: IndexStore<LodIndex, I> + DetailStore<K, CT>, K, T, CT, I: Copy, const L: u8> {
pub struct HashNoneNestLayer<N: IndexStore + DetailStore, T, const L: u8> {
pub detail: HashMap<LodIndex, T>, pub detail: HashMap<LodIndex, T>,
pub nested: N, pub nested: N,
pk_: PhantomData<K>,
pi_: PhantomData<I>,
} }
impl<T, I: Copy, const L: u8> VecVecStore<T, I> for VecVecLayer<T, I, {L}> { #[rustfmt::skip]
fn detail(&self) -> &Vec<T> {&self.detail} //impl<T, I: Copy, const L: u8> IndexStore<usize, I> for VecVecLayer<T, I, {L}> {
fn detail_mut(&mut self) -> &mut Vec<T> {&mut self.detail} impl<T, PI: Copy, const L: u8> IndexStore for VecVecLayer<T, PI, {L}> {
fn index(&self) -> &Vec<I> {&self.index} type KEY=usize; type INDEX=PI;
fn index_mut(&mut self) -> &mut Vec<I> {&mut self.index} fn load(&mut self, key: usize) -> PI { *self.index.get(key).unwrap() }
fn store(&mut self, key: usize, index: PI) { self.index.insert(key, index); }
}
#[rustfmt::skip]
//impl<N: IndexStore<usize, I> + DetailStore<K, CT>, K, T, PI: Copy, CT, I: Copy, const L: u8> IndexStore<usize, PI> for VecVecNestLayer<N, K, T, PI, CT, I, {L}> {
impl<N: IndexStore<KEY=usize> + DetailStore, T, PI: Copy, const L: u8> IndexStore for VecVecNestLayer<N, T, PI, {L}> {
type KEY=usize; type INDEX=PI;
fn load(&mut self, key: usize) -> PI { *self.index.get(key).unwrap() }
fn store(&mut self, key: usize, index: PI) { self.index.insert(key, index); }
}
#[rustfmt::skip]
//impl<T, I: Copy, const L: u8> IndexStore<LodIndex, I> for VecHashLayer<T, I, {L}> {
impl<T, PI: Copy, const L: u8> IndexStore for VecHashLayer<T, PI, {L}> {
type KEY=LodIndex; type INDEX=PI;
fn load(&mut self, key: LodIndex) -> PI { *self.index.get(&key).unwrap() }
fn store(&mut self, key: LodIndex, index: PI) { self.index.insert(key, index); }
}
#[rustfmt::skip]
//impl<N: IndexStore<usize, I> + DetailStore<K, CT>, K, T, PI: Copy, CT, I: Copy, const L: u8> IndexStore<LodIndex, PI> for VecHashNestLayer<N, K, T, PI, CT, I, {L}> {
impl<N: IndexStore<KEY=usize> + DetailStore, T, PI: Copy, const L: u8> IndexStore for VecHashNestLayer<N, T, PI, {L}> {
type KEY=LodIndex; type INDEX=PI;
fn load(&mut self, key: LodIndex) -> PI { *self.index.get(&key).unwrap() }
fn store(&mut self, key: LodIndex, index: PI) { self.index.insert(key, index); }
} }
impl<N: IndexStore<K, I>, T, K, I: Copy, const L: u8> VecVecStore<T, I> for VecVecNestLayer<N, T, K, I, {L}> { #[rustfmt::skip]
fn detail(&self) -> &Vec<T> {&self.detail} //impl<T, I: Copy, const L: u8> DetailStore<usize, T> for VecVecLayer<T, I, {L}> {
fn detail_mut(&mut self) -> &mut Vec<T> {&mut self.detail} impl<T, PI: Copy, const L: u8> DetailStore for VecVecLayer<T, PI, {L}> {
fn index(&self) -> &Vec<I> {&self.index} type KEY=usize; type DETAIL=T;
fn index_mut(&mut self) -> &mut Vec<I> {&mut self.index} fn load(&mut self, key: usize) -> &T { self.detail.get(key).unwrap() }
fn load_mut(&mut self, key: usize) -> &mut T { self.detail.get_mut(key).unwrap() }
fn store(&mut self, key: usize, detail: T) { self.detail.insert(key, detail); }
}
#[rustfmt::skip]
//impl<N: IndexStore<usize, I> + DetailStore<K, CT>, K, T, PI: Copy, CT, I: Copy, const L: u8> DetailStore<usize, T> for VecVecNestLayer<N, K, T, PI, CT, I, {L}> {
impl<N: IndexStore<KEY=usize> + DetailStore, T, PI: Copy, const L: u8> DetailStore for VecVecNestLayer<N, T, PI, {L}> {
type KEY=usize; type DETAIL=T;
fn load(&mut self, key: usize) -> &T { self.detail.get(key).unwrap() }
fn load_mut(&mut self, key: usize) -> &mut T { self.detail.get_mut(key).unwrap() }
fn store(&mut self, key: usize, detail: T) { self.detail.insert(key, detail); }
}
#[rustfmt::skip]
//impl<T, I: Copy, const L: u8> DetailStore<usize, T> for VecHashLayer<T, I, {L}> {
impl<T, PI: Copy, const L: u8> DetailStore for VecHashLayer<T, PI, {L}> {
type KEY=usize; type DETAIL=T;
fn load(&mut self, key: usize) -> &T { self.detail.get(key).unwrap() }
fn load_mut(&mut self, key: usize) -> &mut T { self.detail.get_mut(key).unwrap() }
fn store(&mut self, key: usize, detail: T) { self.detail.insert(key, detail); }
}
#[rustfmt::skip]
//impl<N: IndexStore<usize, I> + DetailStore<K, CT>, K, T, PI: Copy, CT, I: Copy, const L: u8> DetailStore<usize, T> for VecHashNestLayer<N, K, T, PI, CT, I, {L}> {
impl<N: IndexStore<KEY=usize> + DetailStore, T, PI: Copy, const L: u8> DetailStore for VecHashNestLayer<N, T, PI, {L}> {
type KEY=usize; type DETAIL=T;
fn load(&mut self, key: usize) -> &T { self.detail.get(key).unwrap() }
fn load_mut(&mut self, key: usize) -> &mut T { self.detail.get_mut(key).unwrap() }
fn store(&mut self, key: usize, detail: T) { self.detail.insert(key, detail); }
}
#[rustfmt::skip]
//impl<N: IndexStore<LodIndex, I> + DetailStore<K, CT>, K, T, CT, I: Copy, const L: u8> DetailStore<LodIndex, T> for HashNoneNestLayer<N, K, T, CT, I, {L}> {
impl<N: IndexStore<KEY=LodIndex> + DetailStore, T, const L: u8> DetailStore for HashNoneNestLayer<N, T, {L}> {
type KEY=LodIndex; type DETAIL=T;
fn load(&mut self, key: LodIndex) -> &T { self.detail.get(&key).unwrap() }
fn load_mut(&mut self, key: LodIndex) -> &mut T { self.detail.get_mut(&key).unwrap() }
fn store(&mut self, key: LodIndex, detail: T) { self.detail.insert(key, detail); }
} }
impl<T, I: Copy, const L: u8> VecHashStore<T, I> for VecHashLayer<T, I, {L}> {
fn detail(&self) -> &Vec<T> {&self.detail}
fn detail_mut(&mut self) -> &mut Vec<T> {&mut self.detail}
fn index(&self) -> &HashMap<LodIndex, I> {&self.index}
fn index_mut(&mut self) -> &mut HashMap<LodIndex, I> {&mut self.index}
}
impl<N: IndexStore<K, I>, T, K, I: Copy, const L: u8> VecHashStore<T, I> for VecHashNestLayer<N, T, K, I, {L}> { #[rustfmt::skip]
fn detail(&self) -> &Vec<T> {&self.detail} //impl<N: IndexStore<usize, I> + DetailStore<K, CT>, K, T, PI: Copy, CT, I: Copy, const L: u8> Nestable<N, usize, I, K, CT> for VecVecNestLayer<N, K, T, PI, CT, I, {L}> {
fn detail_mut(&mut self) -> &mut Vec<T> {&mut self.detail} impl<N: IndexStore<KEY=usize> + DetailStore, T, PI: Copy, const L: u8> Nestable for VecVecNestLayer<N, T, PI, {L}> {
fn index(&self) -> &HashMap<LodIndex, I> {&self.index} type NESTED=N;
fn index_mut(&mut self) -> &mut HashMap<LodIndex, I> {&mut self.index} fn nested(&self) -> &N { &self.nested }
} }
#[rustfmt::skip]
impl<N: IndexStore<K, I>, T, K, I: Copy, const L: u8> HashNoneStore<T, I> for HashNoneNestLayer<N, T, K, I, {L}> { //impl<N: IndexStore<usize, I> + DetailStore<K, CT>, K, T, PI: Copy, CT, I: Copy, const L: u8> Nestable<N, usize, I, K, CT> for VecHashNestLayer<N, K, T, PI, CT, I, {L}> {
fn detail(&self) -> &HashMap<LodIndex, T> {&self.detail} impl<N: IndexStore<KEY=usize> + DetailStore, T, PI: Copy, const L: u8> Nestable for VecHashNestLayer<N, T, PI, {L}> {
fn detail_mut(&mut self) -> &mut HashMap<LodIndex, T> {&mut self.detail} type NESTED=N;
fn nested(&self) -> &N { &self.nested }
}
#[rustfmt::skip]
//impl<N: IndexStore<LodIndex, I> + DetailStore<K, CT>, K, T, CT, I: Copy, const L: u8> Nestable<N, LodIndex, I, K, CT> for HashNoneNestLayer<N, K, T, CT, I, {L}> {
impl<N: IndexStore<KEY=LodIndex> + DetailStore, T, const L: u8> Nestable for HashNoneNestLayer<N, T, {L}> {
type NESTED=N;
fn nested(&self) -> &N { &self.nested }
} }
//####################################################### //#######################################################
impl<T, I: Copy> IndexStore<usize, I> for VecVecStore<T, I> { //impl<N: IndexStore<usize, I> + DetailStore<K, CT>, K, T, PI: Copy, CT, I: Copy, const L: u8> VecVecNestLayer<N, K, T, PI, CT, I, {L}> {
fn load(&mut self, key: usize) -> I { impl<N: IndexStore<KEY=LodIndex> + DetailStore, T, const L: u8> HashNoneNestLayer<N, T, {L}> {
*self.index().get(key).unwrap() // fn get<'a>(&'a self, index: LodIndex) -> LayerResult<'a, N, usize, I, K, CT> {
} pub fn trav<'a>(&'a self, index: LodIndex) -> LayerResult<'a, N, usize> {
fn store(&mut self, key: usize, index: I) { LayerResult{
self.index_mut().insert(key, index); child: &self.nested,
wanted: index,
index: 0,
}
} }
} }
impl<T, I: Copy> IndexStore<LodIndex, I> for VecHashStore<T, I> { impl<'a, N: IndexStore + DetailStore + Nestable, PK> Traversable<LayerResult<'a, N::NESTED, <N as IndexStore>::KEY>> for LayerResult<'a, N, PK> {
fn load(&mut self, key: LodIndex) -> I { fn get(&self) -> LayerResult<'a, N::NESTED, <N as IndexStore>::KEY> {
*self.index().get(&key).unwrap() unimplemented!();
}
fn store(&mut self, key: LodIndex, index: I) {
self.index_mut().insert(key, index);
} }
} }
impl<T, I: Copy> IndexStore<usize, I> for HashNoneStore<T, I> { impl<'a, N: IndexStore + DetailStore, PK> Materializeable<N::DETAIL> for LayerResult<'a, N, PK> {
fn load(&mut self, key: usize) -> I { fn mat(&self) -> N::DETAIL {
unimplemented!() unimplemented!();
}
fn store(&mut self, key: usize, index: I) {
unimplemented!()
}
}
//#######################################################
impl<T, I: Copy> Lod<T> for VecVecStore<T, I> {
fn materialize(&self, i: LodIndex) -> &T {
&self.detail()[0]
}
}
impl<T, I: Copy> Lod<T> for VecHashStore<T, I> {
fn materialize(&self, i: LodIndex) -> &T {
&self.detail()[0]
}
}
impl<T, I: Copy> Lod<T> for HashNoneStore<T, I> {
fn materialize(&self, i: LodIndex) -> &T {
&self.detail()[&i]
} }
} }
//pub struct HashNoneNestLayer<N: IndexStore<LodIndex, I> + DetailStore<K, CT>, K, T, CT, I: Copy, const L: u8> {
pub type ExampleDelta = pub type ExampleDelta =
HashNoneNestLayer< HashNoneNestLayer<
VecHashNestLayer< VecHashNestLayer<
VecVecNestLayer< VecVecNestLayer<
VecVecLayer< VecVecLayer<
() ,u16 , 0 (), u16, 0
> ,() ,usize ,u32 ,4 > ,(), u32, 4
> ,() ,usize ,u16 ,9 > ,Option<()> , u16, 9
> ,() ,usize ,u16 ,13 > ,() , 13
>; >;
#[cfg(test)]
mod tests {
use crate::lodstore::newdata::*;
#[test]
fn newdata() {
let x = ExampleDelta {
detail: HashMap::new(),
nested: VecHashNestLayer {
detail: Vec::new(),
index: HashMap::new(),
nested: VecVecNestLayer {
detail: Vec::new(),
index: Vec::new(),
nested: VecVecLayer {
detail: Vec::new(),
index: Vec::new(),
}
}
}
};
let i = LodIndex::new(Vec3::new(0,1,2));
let y = x.trav(i);
let ttc = y.get().get();
let tt = ttc.mat();
}
}
// TODO: instead of storing the absolute index in index, we store (index / number of entities), which means a u16 in Block can not only hold 2 full Subblocks (32^3 subblocks per block). but the full 2^16-1 ones. // TODO: instead of storing the absolute index in index, we store (index / number of entities), which means a u16 in Block can not only hold 2 full Subblocks (32^3 subblocks per block). but the full 2^16-1 ones.