world/chunk: change Chunk into a struct

The version-specific part is extracted as an enum ChunkInner.
This commit is contained in:
Matthias Schiffer 2023-11-25 19:07:49 +01:00
parent 61d456846a
commit 638d5046c9
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C

View file

@ -16,10 +16,9 @@ use crate::{
types::*, types::*,
}; };
/// Chunk data structure wrapping a [de::Chunk] for convenient access to /// Version-specific part of [Chunk]
/// block and biome data
#[derive(Debug)] #[derive(Debug)]
pub enum Chunk<'a> { pub enum ChunkInner<'a> {
/// Minecraft v1.18+ chunk with biome data moved into sections /// Minecraft v1.18+ chunk with biome data moved into sections
V1_18 { V1_18 {
/// Section data /// Section data
@ -50,6 +49,14 @@ pub enum Chunk<'a> {
Empty, Empty,
} }
/// Chunk data structure wrapping a [de::Chunk] for convenient access to
/// block and biome data
#[derive(Debug)]
pub struct Chunk<'a> {
/// Version-specific data
inner: ChunkInner<'a>,
}
impl<'a> Chunk<'a> { impl<'a> Chunk<'a> {
/// Creates a new [Chunk] from a deserialized [de::Chunk] /// Creates a new [Chunk] from a deserialized [de::Chunk]
pub fn new( pub fn new(
@ -59,15 +66,17 @@ impl<'a> Chunk<'a> {
) -> Result<(Self, bool)> { ) -> Result<(Self, bool)> {
let data_version = data.data_version.unwrap_or_default(); let data_version = data.data_version.unwrap_or_default();
match &data.chunk { let (inner, has_unknown) = match &data.chunk {
de::ChunkVariant::V1_18 { de::ChunkVariant::V1_18 {
sections, sections,
block_entities: _, block_entities: _,
} => Self::new_v1_18(data_version, sections, block_types, biome_types), } => Self::new_v1_18(data_version, sections, block_types, biome_types)?,
de::ChunkVariant::V0 { level } => { de::ChunkVariant::V0 { level } => {
Self::new_v0(data_version, level, block_types, biome_types) Self::new_v0(data_version, level, block_types, biome_types)?
} }
} };
Ok((Chunk { inner }, has_unknown))
} }
/// [Chunk::new] implementation for Minecraft v1.18+ chunks /// [Chunk::new] implementation for Minecraft v1.18+ chunks
@ -76,7 +85,7 @@ impl<'a> Chunk<'a> {
sections: &'a Vec<de::SectionV1_18>, sections: &'a Vec<de::SectionV1_18>,
block_types: &'a BlockTypes, block_types: &'a BlockTypes,
biome_types: &'a BiomeTypes, biome_types: &'a BiomeTypes,
) -> Result<(Self, bool)> { ) -> Result<(ChunkInner<'a>, bool)> {
let mut section_map = BTreeMap::new(); let mut section_map = BTreeMap::new();
let mut has_unknown = false; let mut has_unknown = false;
@ -118,7 +127,7 @@ impl<'a> Chunk<'a> {
}; };
} }
let chunk = Chunk::V1_18 { section_map }; let chunk = ChunkInner::V1_18 { section_map };
Ok((chunk, has_unknown)) Ok((chunk, has_unknown))
} }
@ -128,7 +137,7 @@ impl<'a> Chunk<'a> {
level: &'a de::LevelV0, level: &'a de::LevelV0,
block_types: &'a BlockTypes, block_types: &'a BlockTypes,
biome_types: &'a BiomeTypes, biome_types: &'a BiomeTypes,
) -> Result<(Self, bool)> { ) -> Result<(ChunkInner<'a>, bool)> {
let mut section_map_v1_13 = BTreeMap::new(); let mut section_map_v1_13 = BTreeMap::new();
let mut section_map_v0 = BTreeMap::new(); let mut section_map_v0 = BTreeMap::new();
let mut has_unknown = false; let mut has_unknown = false;
@ -168,12 +177,12 @@ impl<'a> Chunk<'a> {
let biomes = BiomesV0::new(level.biomes.as_ref(), biome_types); let biomes = BiomesV0::new(level.biomes.as_ref(), biome_types);
let chunk = match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) { let chunk = match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) {
(true, true) => Chunk::Empty, (true, true) => ChunkInner::Empty,
(false, true) => Chunk::V1_13 { (false, true) => ChunkInner::V1_13 {
section_map: section_map_v1_13, section_map: section_map_v1_13,
biomes: biomes?, biomes: biomes?,
}, },
(true, false) => Chunk::V0 { (true, false) => ChunkInner::V0 {
section_map: section_map_v0, section_map: section_map_v0,
biomes: biomes?, biomes: biomes?,
}, },
@ -187,11 +196,11 @@ impl<'a> Chunk<'a> {
/// Returns true if the chunk does not contain any sections /// Returns true if the chunk does not contain any sections
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
match self { match &self.inner {
Chunk::V1_18 { section_map } => section_map.is_empty(), ChunkInner::V1_18 { section_map } => section_map.is_empty(),
Chunk::V1_13 { section_map, .. } => section_map.is_empty(), ChunkInner::V1_13 { section_map, .. } => section_map.is_empty(),
Chunk::V0 { section_map, .. } => section_map.is_empty(), ChunkInner::V0 { section_map, .. } => section_map.is_empty(),
Chunk::Empty => true, ChunkInner::Empty => true,
} }
} }
@ -199,25 +208,25 @@ impl<'a> Chunk<'a> {
pub fn sections(&self) -> SectionIter { pub fn sections(&self) -> SectionIter {
use SectionIterInner::*; use SectionIterInner::*;
SectionIter { SectionIter {
inner: match self { inner: match &self.inner {
Chunk::V1_18 { section_map } => V1_18 { ChunkInner::V1_18 { section_map } => V1_18 {
iter: section_map.iter(), iter: section_map.iter(),
}, },
Chunk::V1_13 { ChunkInner::V1_13 {
section_map, section_map,
biomes, biomes,
} => V1_13 { } => V1_13 {
iter: section_map.iter(), iter: section_map.iter(),
biomes, biomes,
}, },
Chunk::V0 { ChunkInner::V0 {
section_map, section_map,
biomes, biomes,
} => V0 { } => V0 {
iter: section_map.iter(), iter: section_map.iter(),
biomes, biomes,
}, },
Chunk::Empty => Empty, ChunkInner::Empty => Empty,
}, },
} }
} }
@ -253,26 +262,26 @@ impl<'a, T> SectionIterTrait<'a> for T where
/// Inner data structure of [SectionIter] /// Inner data structure of [SectionIter]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum SectionIterInner<'a> { enum SectionIterInner<'a> {
/// Iterator over sections of [Chunk::V1_18] /// Iterator over sections of [ChunkInner::V1_18]
V1_18 { V1_18 {
/// Inner iterator into section map /// Inner iterator into section map
iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV1_18<'a>, BlockLight<'a>)>, iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV1_18<'a>, BlockLight<'a>)>,
}, },
/// Iterator over sections of [Chunk::V1_13] /// Iterator over sections of [ChunkInner::V1_13]
V1_13 { V1_13 {
/// Inner iterator into section map /// Inner iterator into section map
iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BlockLight<'a>)>, iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BlockLight<'a>)>,
/// Chunk biome data /// Chunk biome data
biomes: &'a BiomesV0<'a>, biomes: &'a BiomesV0<'a>,
}, },
/// Iterator over sections of [Chunk::V0] /// Iterator over sections of [ChunkInner::V0]
V0 { V0 {
/// Inner iterator into section map /// Inner iterator into section map
iter: btree_map::Iter<'a, SectionY, (SectionV0<'a>, BlockLight<'a>)>, iter: btree_map::Iter<'a, SectionY, (SectionV0<'a>, BlockLight<'a>)>,
/// Chunk biome data /// Chunk biome data
biomes: &'a BiomesV0<'a>, biomes: &'a BiomesV0<'a>,
}, },
/// Empty iterator over an unpopulated chunk ([Chunk::Empty]) /// Empty iterator over an unpopulated chunk ([ChunkInner::Empty])
Empty, Empty,
} }