Put the .trav() function into a new Trait: EntryLayer

this trait needs to be implemented for the TopMost Layer of a LodTree as well of the LodDelta.
This can be archived by a lot of trait magic.
However, due to a fight with the borrow checker, this commit here contains a lot of weird lifetimes, i really have no idea, and prob will cleanup this, BUT, it compiles, and tests run green
This commit is contained in:
Marcel Märtens 2019-10-22 16:56:27 +02:00
parent 91f5ad141c
commit 750048f26c
3 changed files with 54 additions and 18 deletions

View File

@ -1,5 +1,6 @@
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![feature(const_generics, test)] #![feature(const_generics, test)]
#![feature(associated_type_bounds)]
extern crate serde_derive; extern crate serde_derive;
#[macro_use] #[macro_use]

View File

@ -28,6 +28,7 @@ use vek::*;
- ToOptionUsize: to store INDEX in z16/u32 efficiently and move up to usize on calculation - 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. - 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. - Materializeable: trait is used to actually return a Detail for a concrete position.
- EntryLayer: the topmost layer which can generate a Traversable for a LodPos must implement this, e.g. needed by delta
Actual structs regarding of position in the chain. They represent the Layers and contain the Details, they implement (some of) the 2 Store traits Actual structs regarding of position in the chain. They represent the Layers and contain the Details, they implement (some of) the 2 Store traits
Naming Scheme is <Own Detail Type>[Nest]Layer Naming Scheme is <Own Detail Type>[Nest]Layer
@ -81,6 +82,10 @@ pub trait Materializeable {
type MAT_CHILD; type MAT_CHILD;
fn mat(self) -> Self::MAT_CHILD; fn mat(self) -> Self::MAT_CHILD;
} }
pub trait EntryLayer<'a> {
type TRAV: Traversable;
fn trav(&'a self, pos: LodPos) -> Self::TRAV;
}
//####################################################### //#######################################################
@ -150,9 +155,12 @@ impl<C: DetailStore, T, I: ToOptionUsize, const L: u8> ParentLayer
} }
} }
impl<C: DetailStore, T, I: ToOptionUsize, const L: u8> HashNestLayer<C, T, I, { L }> { impl<'a, C: 'a + DetailStore, T: 'a, I: 'a + ToOptionUsize, const L: u8> EntryLayer<'a>
#[allow(dead_code)] for HashNestLayer<C, T, I, { L }>
fn trav(&self, pos: LodPos) -> HashIter<Self> { {
type TRAV = HashIter<'a, HashNestLayer<C, T, I, { L }>>;
fn trav(&'a self, pos: LodPos) -> Self::TRAV {
HashIter { HashIter {
layer: &self, layer: &self,
wanted: pos, wanted: pos,

View File

@ -1,7 +1,6 @@
use super::data::{DetailStore, Layer, ParentLayer, Traversable}; use super::data::{DetailStore, EntryLayer, Layer, Materializeable, ParentLayer, Traversable};
use super::index::ToOptionUsize; use super::lodpos::LodPos;
use super::lodpos::{multily_with_2_pow_n, relative_to_1d, two_pow_u32, LodPos}; use std::marker::PhantomData;
use serde::export::PhantomData;
/* /*
A LodDelta applies a change to a Lod A LodDelta applies a change to a Lod
The rules for LodDeltas are strict in order to make them as simple as possible. The rules for LodDeltas are strict in order to make them as simple as possible.
@ -32,18 +31,19 @@ pub struct VecNestDelta<D: Delta, T, const L: u8> {
pub child: D, pub child: D,
} }
pub struct DeltaWriter<'a, C: DetailStore, D: Delta> { pub struct DeltaWriter<'a, C: EntryLayer<'a> + DetailStore, D: EntryLayer<'a> + Delta> {
pub delta: &'a mut D, pub delta: &'a mut D,
pub data: &'a mut C, pub data: &'a mut C,
} }
struct VecDataIter<'a, D: Delta> { pub struct VecDataIter<'a, D: Delta> {
layer: &'a D, layer: &'a D,
} }
struct DataWriterIter<DT: Traversable, CT: Traversable> { pub struct DataWriterIter<'a, DT: 'a, CT: 'a> {
delta_iter: DT, delta_iter: DT,
data_iter: CT, data_iter: CT,
_a: PhantomData<&'a ()>,
} }
//####################################################### //#######################################################
@ -64,16 +64,33 @@ impl<D: Delta, T, const L: u8> ParentLayer for VecNestDelta<D, T, { L }> {
} }
} }
impl<'a, C: DetailStore, D: Delta> DeltaWriter<'a, C, D> { impl<'a, C: DetailStore + EntryLayer<'a>, D: Delta + EntryLayer<'a>> DeltaWriter<'a, C, D> {
pub fn new(delta: &'a mut D, data: &'a mut C) -> Self { pub fn new(delta: &'a mut D, data: &'a mut C) -> Self {
DeltaWriter { delta, data } DeltaWriter { delta, data }
} }
} }
impl<'a, C: DetailStore, D: Delta> DeltaWriter<'a, C, D> { impl<'a, D: 'a + Delta, T: 'a, const L: u8> EntryLayer<'a> for VecNestDelta<D, T, { L }> {
#[allow(dead_code)] type TRAV = VecDataIter<'a, VecNestDelta<D, T, { L }>>;
fn trav(&'a self, pos: LodPos) -> VecDataIter<'a, D> {
VecDataIter { layer: &self.delta } fn trav(&'a self, pos: LodPos) -> Self::TRAV {
VecDataIter { layer: &self }
}
}
impl<'a, C: DetailStore + EntryLayer<'a>, D: Delta + EntryLayer<'a>> EntryLayer<'a>
for DeltaWriter<'a, C, D>
where
<<C as EntryLayer<'a>>::TRAV as Traversable>::TRAV_CHILD: Traversable,
<<D as EntryLayer<'a>>::TRAV as Traversable>::TRAV_CHILD: Traversable,
{
type TRAV = DataWriterIter<'a, D::TRAV, C::TRAV>;
fn trav(&'a self, pos: LodPos) -> DataWriterIter<D::TRAV, C::TRAV> {
DataWriterIter {
delta_iter: self.delta.trav(pos),
data_iter: self.data.trav(pos),
_a: PhantomData::<&'a ()>::default(),
}
} }
} }
@ -90,20 +107,30 @@ where
} }
} }
impl<'a, DT: Traversable, CT: Traversable> Traversable for DataWriterIter<DT, CT> impl<'a, DT: Traversable, CT: Traversable> Traversable for DataWriterIter<'a, DT, CT>
where where
DT::TRAV_CHILD: Traversable, DT::TRAV_CHILD: Traversable,
CT::TRAV_CHILD: Traversable, CT::TRAV_CHILD: Traversable,
{ {
type TRAV_CHILD = DataWriterIter<DT::TRAV_CHILD, CT::TRAV_CHILD>; type TRAV_CHILD = DataWriterIter<'a, DT::TRAV_CHILD, CT::TRAV_CHILD>;
fn get(self) -> DataWriterIter<DT::TRAV_CHILD, CT::TRAV_CHILD> { fn get(self) -> DataWriterIter<'a, DT::TRAV_CHILD, CT::TRAV_CHILD> {
DataWriterIter { DataWriterIter {
delta_iter: self.delta_iter.get(), delta_iter: self.delta_iter.get(),
data_iter: self.data_iter.get(), data_iter: self.data_iter.get(),
_a: PhantomData::<&'a ()>::default(),
} }
} }
} }
/*
impl<'a, DT: Materializeable, CT: Materializeable> Materializeable
for DataWriterIter<DT, CT> {
type MAT_CHILD = &'a CT::MAT_CHILD;
fn mat(self) -> &'a CT::MAT_CHILD {
self.data_iter.mat()
}
}*/
impl<T, const L: u8> Delta for VecDelta<T, { L }> {} impl<T, const L: u8> Delta for VecDelta<T, { L }> {}
impl<C: Delta, T, const L: u8> Delta for VecNestDelta<C, T, { L }> {} impl<C: Delta, T, const L: u8> Delta for VecNestDelta<C, T, { L }> {}