mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-06 01:54:51 +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 anyhow::{bail, Context, Result};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
de,
|
de,
|
||||||
section::{OldSection, PaletteSection, PaletteSectionBiomes},
|
section::{OldSection, PaletteSection, PaletteSectionBiomes, Section},
|
||||||
};
|
};
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
|
@ -23,6 +26,25 @@ pub enum Chunk<'a> {
|
||||||
Empty,
|
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> {
|
impl<'a> Chunk<'a> {
|
||||||
pub fn new(data: &'a de::Chunk) -> Result<Self> {
|
pub fn new(data: &'a de::Chunk) -> Result<Self> {
|
||||||
let data_version = data.data_version.unwrap_or_default();
|
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)
|
Some(bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Section {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PaletteSectionBiomes<'a> {
|
pub struct PaletteSectionBiomes<'a> {
|
||||||
biomes: Option<&'a fastnbt::LongArray>,
|
biomes: Option<&'a fastnbt::LongArray>,
|
||||||
|
@ -81,6 +83,8 @@ impl<'a> PaletteSection<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Section for PaletteSection<'a> {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OldSection<'a> {
|
pub struct OldSection<'a> {
|
||||||
blocks: &'a fastnbt::ByteArray,
|
blocks: &'a fastnbt::ByteArray,
|
||||||
|
@ -93,3 +97,5 @@ impl<'a> OldSection<'a> {
|
||||||
Ok(Self { blocks, data })
|
Ok(Self { blocks, data })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Section for OldSection<'a> {}
|
||||||
|
|
Loading…
Add table
Reference in a new issue