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::delta::LodDelta;
use serde::export::PhantomData;
/*
traits and structs explained:
- IndexStore: Every detail must implement this for either <usize, I> or <LodIndex, I>. 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.
- 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.
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.
That reduced duplicate coding because it is used in layers as well as the leaf layers.
- actual structs regarding of position in the chain. They represent the Layers and contain the details.
Naming Scheme is <Own Detail Type><Parent Detail Type>[Nest]Layer
1) VecVecLayer/VecHashLayer: Vec Leaf Layers that have a vec/hash index.
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
Terminology:
- Layer: the layer of the LoDTree, a tree can have n layers, every layer contains their child layer, except for the last one.
Each layer contains a level, a number from 15-0. the level of each child must be lower than the parents layer!
- Detail: Each Layer contains information about that layer, here called Detail. This is the usable information we want to store in the LoDTree
Each detail has a position. Multiple Details can exist at the same position on different 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)
or this refers to the actually storage for the index for the next layer (often a u16,u32)
//TODO: define the LodIndex as LoDPosition
- Key: always refers to the storage of a LAYER. Any keyword with KEY is either of type usize or LodIndex.
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
//I: Index stored, often u16 or u32
pub trait IndexStore<K, I: Copy> {
fn load(&mut self, key: K) -> I;
fn store(&mut self, key: K, index: I);
pub trait IndexStore {
type KEY;
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> {
fn load(&mut self, key: K2) -> &T;
fn load_mut(&mut self, key: K2) -> &mut T;
fn store(&mut self, key: K2, index: T);
pub trait DetailStore {
type KEY;
type DETAIL;
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 VecVecStore<T, I: Copy> {
fn detail(&self) -> &Vec<T>;
fn detail_mut(&mut self) -> &mut Vec<T>;
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 Nestable {
type NESTED: IndexStore + DetailStore;
fn nested(&self) -> &Self::NESTED;
}
pub trait Traversable<C> {
fn get() -> C;
fn get(&self) -> C;
}
pub trait Materializeable<T> {
fn mat() -> T;
fn mat(&self) -> T;
}
/*
struct LayerResult<C> {
child: &C,
index: LodIndex,
C::Type,
}
impl LayerResult {
fn get() -> LayerReslt<C::C>;
fn mat() -> T;
}*/
pub trait Lod<T> {
fn materialize(&self, i:LodIndex) -> &T;
//struct LayerResult<'a, N: IndexStore<PK, I> + DetailStore<K, CT>, PK, I: Copy, K, CT> {
pub struct LayerResult<'a, N: IndexStore + DetailStore, PK> {
child: &'a N,
wanted: LodIndex,
index: PK,
}
//#######################################################
// 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 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 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 index: Vec<I>,
pub index: Vec<PI>,
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 index: HashMap<LodIndex, I>,
pub index: HashMap<LodIndex, PI>,
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 nested: N,
pk_: PhantomData<K>,
pi_: PhantomData<I>,
}
impl<T, I: Copy, const L: u8> VecVecStore<T, I> for VecVecLayer<T, I, {L}> {
fn detail(&self) -> &Vec<T> {&self.detail}
fn detail_mut(&mut self) -> &mut Vec<T> {&mut self.detail}
fn index(&self) -> &Vec<I> {&self.index}
fn index_mut(&mut self) -> &mut Vec<I> {&mut self.index}
#[rustfmt::skip]
//impl<T, I: Copy, const L: u8> IndexStore<usize, I> for VecVecLayer<T, I, {L}> {
impl<T, PI: Copy, const L: u8> IndexStore for VecVecLayer<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<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}> {
fn detail(&self) -> &Vec<T> {&self.detail}
fn detail_mut(&mut self) -> &mut Vec<T> {&mut self.detail}
fn index(&self) -> &Vec<I> {&self.index}
fn index_mut(&mut self) -> &mut Vec<I> {&mut self.index}
#[rustfmt::skip]
//impl<T, I: Copy, const L: u8> DetailStore<usize, T> for VecVecLayer<T, I, {L}> {
impl<T, PI: Copy, const L: u8> DetailStore for VecVecLayer<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 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}> {
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}
#[rustfmt::skip]
//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}> {
impl<N: IndexStore<KEY=usize> + DetailStore, T, PI: Copy, const L: u8> Nestable for VecVecNestLayer<N, T, PI, {L}> {
type NESTED=N;
fn nested(&self) -> &N { &self.nested }
}
impl<N: IndexStore<K, I>, T, K, I: Copy, const L: u8> HashNoneStore<T, I> for HashNoneNestLayer<N, T, K, I, {L}> {
fn detail(&self) -> &HashMap<LodIndex, T> {&self.detail}
fn detail_mut(&mut self) -> &mut HashMap<LodIndex, T> {&mut self.detail}
#[rustfmt::skip]
//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}> {
impl<N: IndexStore<KEY=usize> + DetailStore, T, PI: Copy, const L: u8> Nestable for VecHashNestLayer<N, T, PI, {L}> {
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> {
fn load(&mut self, key: usize) -> I {
*self.index().get(key).unwrap()
}
fn store(&mut self, key: usize, index: I) {
self.index_mut().insert(key, index);
//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}> {
impl<N: IndexStore<KEY=LodIndex> + DetailStore, T, const L: u8> HashNoneNestLayer<N, T, {L}> {
// 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> {
LayerResult{
child: &self.nested,
wanted: index,
index: 0,
}
}
}
impl<T, I: Copy> IndexStore<LodIndex, I> for VecHashStore<T, I> {
fn load(&mut self, key: LodIndex) -> I {
*self.index().get(&key).unwrap()
}
fn store(&mut self, key: LodIndex, index: I) {
self.index_mut().insert(key, index);
impl<'a, N: IndexStore + DetailStore + Nestable, PK> Traversable<LayerResult<'a, N::NESTED, <N as IndexStore>::KEY>> for LayerResult<'a, N, PK> {
fn get(&self) -> LayerResult<'a, N::NESTED, <N as IndexStore>::KEY> {
unimplemented!();
}
}
impl<T, I: Copy> IndexStore<usize, I> for HashNoneStore<T, I> {
fn load(&mut self, key: usize) -> I {
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]
impl<'a, N: IndexStore + DetailStore, PK> Materializeable<N::DETAIL> for LayerResult<'a, N, PK> {
fn mat(&self) -> N::DETAIL {
unimplemented!();
}
}
//pub struct HashNoneNestLayer<N: IndexStore<LodIndex, I> + DetailStore<K, CT>, K, T, CT, I: Copy, const L: u8> {
pub type ExampleDelta =
HashNoneNestLayer<
VecHashNestLayer<
VecVecNestLayer<
VecVecLayer<
() ,u16 , 0
> ,() ,usize ,u32 ,4
> ,() ,usize ,u16 ,9
> ,() ,usize ,u16 ,13
(), u16, 0
> ,(), u32, 4
> ,Option<()> , u16, 9
> ,() , 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.