mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-05 01:24:53 +01:00
world: add section iterator
An (empty for now) trait is introduced to abstract over the two section types.
This commit is contained in:
parent
2d782f25b1
commit
c130f3cdae
2 changed files with 124 additions and 2 deletions
|
@ -1,10 +1,13 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::{
|
||||
collections::{btree_map, BTreeMap},
|
||||
iter::{self, FusedIterator},
|
||||
};
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use super::{
|
||||
de,
|
||||
section::{OldSection, PaletteSection, PaletteSectionBiomes},
|
||||
section::{OldSection, PaletteSection, PaletteSectionBiomes, Section},
|
||||
};
|
||||
use crate::types::*;
|
||||
|
||||
|
@ -23,6 +26,25 @@ pub enum Chunk<'a> {
|
|||
Empty,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum SectionIterInner<'a> {
|
||||
V1_18 {
|
||||
iter: btree_map::Iter<'a, SectionY, (PaletteSection<'a>, PaletteSectionBiomes<'a>)>,
|
||||
},
|
||||
V1_13 {
|
||||
iter: btree_map::Iter<'a, SectionY, PaletteSection<'a>>,
|
||||
},
|
||||
Old {
|
||||
iter: btree_map::Iter<'a, SectionY, OldSection<'a>>,
|
||||
},
|
||||
Empty,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SectionIter<'a> {
|
||||
inner: SectionIterInner<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Chunk<'a> {
|
||||
pub fn new(data: &'a de::Chunk) -> Result<Self> {
|
||||
let data_version = data.data_version.unwrap_or_default();
|
||||
|
@ -108,4 +130,98 @@ impl<'a> Chunk<'a> {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn sections(&self) -> SectionIter {
|
||||
use SectionIterInner::*;
|
||||
SectionIter {
|
||||
inner: match self {
|
||||
Chunk::V1_18 { section_map } => V1_18 {
|
||||
iter: section_map.iter(),
|
||||
},
|
||||
Chunk::V1_13 { section_map, .. } => V1_13 {
|
||||
iter: section_map.iter(),
|
||||
},
|
||||
Chunk::Old { section_map, .. } => Old {
|
||||
iter: section_map.iter(),
|
||||
},
|
||||
Chunk::Empty => Empty,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait SectionIterTrait<'a>:
|
||||
Iterator<Item = (SectionY, &'a dyn Section)>
|
||||
+ DoubleEndedIterator
|
||||
+ ExactSizeIterator
|
||||
+ FusedIterator
|
||||
{
|
||||
}
|
||||
|
||||
impl<'a, T> SectionIterTrait<'a> for T where
|
||||
T: Iterator<Item = (SectionY, &'a dyn Section)>
|
||||
+ DoubleEndedIterator
|
||||
+ ExactSizeIterator
|
||||
+ FusedIterator
|
||||
{
|
||||
}
|
||||
|
||||
impl<'a> SectionIter<'a> {
|
||||
fn with_iter<F, T>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut dyn SectionIterTrait<'a>) -> T,
|
||||
{
|
||||
match &mut self.inner {
|
||||
SectionIterInner::V1_18 { iter } => f(
|
||||
&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, §ion.0) })
|
||||
),
|
||||
SectionIterInner::V1_13 { iter } => {
|
||||
f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) }))
|
||||
}
|
||||
SectionIterInner::Old { iter } => {
|
||||
f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) }))
|
||||
}
|
||||
SectionIterInner::Empty => f(&mut iter::empty()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for SectionIter<'a> {
|
||||
type Item = (SectionY, &'a dyn Section);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.with_iter(|iter| iter.next())
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
match &self.inner {
|
||||
SectionIterInner::V1_18 { iter } => iter.size_hint(),
|
||||
SectionIterInner::V1_13 { iter } => iter.size_hint(),
|
||||
SectionIterInner::Old { iter } => iter.size_hint(),
|
||||
SectionIterInner::Empty => (0, Some(0)),
|
||||
}
|
||||
}
|
||||
|
||||
fn last(mut self) -> Option<Self::Item> {
|
||||
self.with_iter(|iter| iter.last())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DoubleEndedIterator for SectionIter<'a> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
self.with_iter(|iter| iter.next_back())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExactSizeIterator for SectionIter<'a> {
|
||||
fn len(&self) -> usize {
|
||||
match &self.inner {
|
||||
SectionIterInner::V1_18 { iter } => iter.len(),
|
||||
SectionIterInner::V1_13 { iter } => iter.len(),
|
||||
SectionIterInner::Old { iter } => iter.len(),
|
||||
SectionIterInner::Empty => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FusedIterator for SectionIter<'a> {}
|
||||
|
|
|
@ -15,6 +15,8 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option<u8> {
|
|||
Some(bits)
|
||||
}
|
||||
|
||||
pub trait Section {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PaletteSectionBiomes<'a> {
|
||||
biomes: Option<&'a fastnbt::LongArray>,
|
||||
|
@ -81,6 +83,8 @@ impl<'a> PaletteSection<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Section for PaletteSection<'a> {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OldSection<'a> {
|
||||
blocks: &'a fastnbt::ByteArray,
|
||||
|
@ -93,3 +97,5 @@ impl<'a> OldSection<'a> {
|
|||
Ok(Self { blocks, data })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Section for OldSection<'a> {}
|
||||
|
|
Loading…
Add table
Reference in a new issue