From 750048f26c49a8534e4289ed869d02b3b901135d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=A4rtens?= Date: Tue, 22 Oct 2019 16:56:27 +0200 Subject: [PATCH] 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 --- worldsim/src/lib.rs | 1 + worldsim/src/lodstore/data.rs | 14 +++++++-- worldsim/src/lodstore/delta.rs | 57 +++++++++++++++++++++++++--------- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/worldsim/src/lib.rs b/worldsim/src/lib.rs index d9d65622fe..722f442c71 100644 --- a/worldsim/src/lib.rs +++ b/worldsim/src/lib.rs @@ -1,5 +1,6 @@ #![allow(incomplete_features)] #![feature(const_generics, test)] +#![feature(associated_type_bounds)] extern crate serde_derive; #[macro_use] diff --git a/worldsim/src/lodstore/data.rs b/worldsim/src/lodstore/data.rs index a534b5cae8..843198987c 100644 --- a/worldsim/src/lodstore/data.rs +++ b/worldsim/src/lodstore/data.rs @@ -28,6 +28,7 @@ use vek::*; - 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. - 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 Naming Scheme is [Nest]Layer @@ -81,6 +82,10 @@ pub trait Materializeable { type 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 ParentLayer } } -impl HashNestLayer { - #[allow(dead_code)] - fn trav(&self, pos: LodPos) -> HashIter { +impl<'a, C: 'a + DetailStore, T: 'a, I: 'a + ToOptionUsize, const L: u8> EntryLayer<'a> + for HashNestLayer +{ + type TRAV = HashIter<'a, HashNestLayer>; + + fn trav(&'a self, pos: LodPos) -> Self::TRAV { HashIter { layer: &self, wanted: pos, diff --git a/worldsim/src/lodstore/delta.rs b/worldsim/src/lodstore/delta.rs index a894d25874..749ca64cef 100644 --- a/worldsim/src/lodstore/delta.rs +++ b/worldsim/src/lodstore/delta.rs @@ -1,7 +1,6 @@ -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; +use super::data::{DetailStore, EntryLayer, Layer, Materializeable, ParentLayer, Traversable}; +use super::lodpos::LodPos; +use std::marker::PhantomData; /* A LodDelta applies a change to a Lod The rules for LodDeltas are strict in order to make them as simple as possible. @@ -32,18 +31,19 @@ pub struct VecNestDelta { 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 data: &'a mut C, } -struct VecDataIter<'a, D: Delta> { +pub struct VecDataIter<'a, D: Delta> { layer: &'a D, } -struct DataWriterIter { +pub struct DataWriterIter<'a, DT: 'a, CT: 'a> { delta_iter: DT, data_iter: CT, + _a: PhantomData<&'a ()>, } //####################################################### @@ -64,16 +64,33 @@ impl ParentLayer for VecNestDelta { } } -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 { 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: 'a + Delta, T: 'a, const L: u8> EntryLayer<'a> for VecNestDelta { + type TRAV = VecDataIter<'a, VecNestDelta>; + + 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 + <>::TRAV as Traversable>::TRAV_CHILD: Traversable, + <>::TRAV as Traversable>::TRAV_CHILD: Traversable, +{ + type TRAV = DataWriterIter<'a, D::TRAV, C::TRAV>; + fn trav(&'a self, pos: LodPos) -> DataWriterIter { + 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 +impl<'a, DT: Traversable, CT: Traversable> Traversable for DataWriterIter<'a, DT, CT> where DT::TRAV_CHILD: Traversable, CT::TRAV_CHILD: Traversable, { - type TRAV_CHILD = DataWriterIter; + type TRAV_CHILD = DataWriterIter<'a, DT::TRAV_CHILD, CT::TRAV_CHILD>; - fn get(self) -> DataWriterIter { + fn get(self) -> DataWriterIter<'a, DT::TRAV_CHILD, CT::TRAV_CHILD> { DataWriterIter { delta_iter: self.delta_iter.get(), data_iter: self.data_iter.get(), + _a: PhantomData::<&'a ()>::default(), } } } +/* +impl<'a, DT: Materializeable, CT: Materializeable> Materializeable + for DataWriterIter { + type MAT_CHILD = &'a CT::MAT_CHILD; + + fn mat(self) -> &'a CT::MAT_CHILD { + self.data_iter.mat() + } +}*/ impl Delta for VecDelta {} impl Delta for VecNestDelta {}